-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
evalengine: Implement LAST_DAY #15038
Changes from 1 commit
32a2831
d012b1c
2ea4596
c24efc8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -493,7 +493,7 @@ func (b *builtinDayOfWeek) eval(env *ExpressionEnv) (eval, error) { | |
if d == nil || d.isZero() { | ||
return nil, nil | ||
} | ||
return newEvalInt64(int64(d.dt.Date.ToStdTime(time.Local).Weekday() + 1)), nil | ||
return newEvalInt64(int64(d.dt.Date.ToStdTime(env.currentTimezone()).Weekday() + 1)), nil | ||
} | ||
|
||
func (call *builtinDayOfWeek) compile(c *compiler) (ctype, error) { | ||
|
@@ -526,7 +526,7 @@ func (b *builtinDayOfYear) eval(env *ExpressionEnv) (eval, error) { | |
if d == nil || d.isZero() { | ||
return nil, nil | ||
} | ||
return newEvalInt64(int64(d.dt.Date.ToStdTime(time.Local).YearDay())), nil | ||
return newEvalInt64(int64(d.dt.Date.ToStdTime(env.currentTimezone()).YearDay())), nil | ||
} | ||
|
||
func (call *builtinDayOfYear) compile(c *compiler) (ctype, error) { | ||
|
@@ -756,7 +756,7 @@ func (call *builtinHour) compile(c *compiler) (ctype, error) { | |
return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: arg.Flag | flagNullable}, nil | ||
} | ||
|
||
func yearDayToTime(y, yd int64) time.Time { | ||
func yearDayToTime(env *ExpressionEnv, y, yd int64) time.Time { | ||
if y >= 0 && y < 100 { | ||
if y < 70 { | ||
y += 2000 | ||
|
@@ -768,7 +768,7 @@ func yearDayToTime(y, yd int64) time.Time { | |
if y < 0 || y > 9999 || yd < 1 || yd > math.MaxInt32 { | ||
return time.Time{} | ||
} | ||
t := time.Date(int(y), time.January, 1, 0, 0, 0, 0, time.Local).AddDate(0, 0, int(yd-1)) | ||
t := time.Date(int(y), time.January, 1, 0, 0, 0, 0, env.currentTimezone()).AddDate(0, 0, int(yd-1)) | ||
if t.Year() > 9999 { | ||
return time.Time{} | ||
} | ||
|
@@ -796,7 +796,7 @@ func (b *builtinMakedate) eval(env *ExpressionEnv) (eval, error) { | |
y := evalToInt64(year).i | ||
yd := evalToInt64(yearDay).i | ||
|
||
t := yearDayToTime(y, yd) | ||
t := yearDayToTime(env, y, yd) | ||
if t.IsZero() { | ||
return nil, nil | ||
} | ||
|
@@ -1205,13 +1205,13 @@ func (call *builtinMonthName) compile(c *compiler) (ctype, error) { | |
return ctype{Type: sqltypes.VarChar, Col: col, Flag: arg.Flag | flagNullable}, nil | ||
} | ||
|
||
func lastDay(dt datetime.DateTime) (datetime.Date, bool) { | ||
ts := dt.Date.ToStdTime(time.Local) | ||
firstDayOfNextMonth := time.Date(ts.Year(), ts.Month()+1, 1, 0, 0, 0, 0, time.Local) | ||
lastDayOfMonth := firstDayOfNextMonth.AddDate(0, 0, -1) | ||
func lastDay(env *ExpressionEnv, dt datetime.DateTime) datetime.Date { | ||
ts := dt.Date.ToStdTime(env.currentTimezone()) | ||
firstDayOfMonth := time.Date(ts.Year(), ts.Month(), 1, 0, 0, 0, 0, env.currentTimezone()) | ||
lastDayOfMonth := firstDayOfMonth.AddDate(0, 1, -1) | ||
|
||
date := datetime.NewDateFromStd(lastDayOfMonth) | ||
return date, true | ||
return date | ||
} | ||
|
||
func (b *builtinLastDay) eval(env *ExpressionEnv) (eval, error) { | ||
|
@@ -1227,8 +1227,8 @@ func (b *builtinLastDay) eval(env *ExpressionEnv) (eval, error) { | |
return nil, nil | ||
} | ||
|
||
d, ok := lastDay(dt.dt) | ||
if !ok { | ||
d := lastDay(env, dt.dt) | ||
if d.IsZero() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this case happen? We already check above that it's not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm... true. This can not happen. Removed from here. |
||
return nil, nil | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1747,6 +1747,23 @@ func FnLastDay(yield Query) { | |
for _, d := range inputConversions { | ||
yield(fmt.Sprintf("LAST_DAY(%s)", d), nil) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Next to these inputs, we should also test it against a few more inputs explicitly to test edge case behaviors here. Like last of December, January & February years (with / without leap years etc). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. |
||
|
||
dates := []string{ | ||
`DATE'2024-02-18'`, | ||
`DATE'2023-02-01'`, | ||
`DATE'2100-02-01'`, | ||
`TIMESTAMP'2020-12-31 23:59:59'`, | ||
`TIMESTAMP'2025-01-01 00:00:00'`, | ||
`'2000-02-01'`, | ||
`'2020-12-31 23:59:59'`, | ||
`'2025-01-01 00:00:00'`, | ||
`20250101`, | ||
`'20250101'`, | ||
} | ||
|
||
for _, d := range dates { | ||
yield(fmt.Sprintf("LAST_DAY(%s)", d), nil) | ||
} | ||
} | ||
|
||
func FnQuarter(yield Query) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it’s best to pass in the most specific type. So we should pass in the time zone itself here I think.
Same applies to lastday as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.