Skip to content
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 FROM_DAYS #15058

Merged
merged 8 commits into from
Jan 29, 2024
8 changes: 8 additions & 0 deletions go/mysql/datetime/mydate.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,11 @@

panic("unreachable: yday is too large?")
}

// DateFromDayNumber converts an absolute day number into a Date.
// Returns zero date if day number exceeds 3652499 or is less than 366.
func DateFromDayNumber(daynr int) Date {
var d Date
d.year, d.month, d.day = mysqlDateFromDayNumber(daynr)
return d

Check warning on line 90 in go/mysql/datetime/mydate.go

View check run for this annotation

Codecov / codecov/patch

go/mysql/datetime/mydate.go#L87-L90

Added lines #L87 - L90 were not covered by tests
}
12 changes: 12 additions & 0 deletions go/vt/vtgate/evalengine/cached_size.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions go/vt/vtgate/evalengine/compiler_asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3795,6 +3795,20 @@ func (asm *assembler) Fn_LAST_DAY() {
}, "FN LAST_DAY DATETIME(SP-1)")
}

func (asm *assembler) Fn_FROM_DAYS() {
asm.emit(func(env *ExpressionEnv) int {
arg := env.vm.stack[env.vm.sp-1].(*evalInt64)
d := datetime.DateFromDayNumber(int(arg.i))
if d.Year() > 9999 {
env.vm.stack[env.vm.sp-1] = nil
return 1
}

env.vm.stack[env.vm.sp-1] = env.vm.arena.newEvalDate(d)
return 1
}, "FN FROM_DAYS INT64(SP-1)")
}

func (asm *assembler) Fn_QUARTER() {
asm.emit(func(env *ExpressionEnv) int {
if env.vm.stack[env.vm.sp-1] == nil {
Expand Down
41 changes: 41 additions & 0 deletions go/vt/vtgate/evalengine/fn_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@
CallExpr
}

builtinFromDays struct {
CallExpr
}

builtinQuarter struct {
CallExpr
}
Expand Down Expand Up @@ -173,6 +177,7 @@
var _ IR = (*builtinMonth)(nil)
var _ IR = (*builtinMonthName)(nil)
var _ IR = (*builtinLastDay)(nil)
var _ IR = (*builtinFromDays)(nil)
var _ IR = (*builtinQuarter)(nil)
var _ IR = (*builtinSecond)(nil)
var _ IR = (*builtinTime)(nil)
Expand Down Expand Up @@ -1249,6 +1254,42 @@
return ctype{Type: sqltypes.Date, Flag: arg.Flag | flagNullable}, nil
}

func (b *builtinFromDays) eval(env *ExpressionEnv) (eval, error) {
arg, err := b.arg1(env)
if arg == nil {
return nil, nil
}
if err != nil {
return nil, err
}

d := datetime.DateFromDayNumber(int(evalToInt64(arg).i))

// mysql returns NULL if year is greater than 9999
if d.Year() > 9999 {
return nil, nil
}
return newEvalDate(d, true), nil
}

func (call *builtinFromDays) compile(c *compiler) (ctype, error) {
arg, err := call.Arguments[0].compile(c)
if err != nil {
return ctype{}, err
}

Check warning on line 1279 in go/vt/vtgate/evalengine/fn_time.go

View check run for this annotation

Codecov / codecov/patch

go/vt/vtgate/evalengine/fn_time.go#L1278-L1279

Added lines #L1278 - L1279 were not covered by tests

skip := c.compileNullCheck1(arg)
switch arg.Type {
case sqltypes.Int64:
default:
c.asm.Convert_xi(1)
}

c.asm.Fn_FROM_DAYS()
c.asm.jumpDestination(skip)
return ctype{Type: sqltypes.Date, Flag: arg.Flag | flagNullable}, nil
}

func (b *builtinQuarter) eval(env *ExpressionEnv) (eval, error) {
date, err := b.arg1(env)
if err != nil {
Expand Down
23 changes: 23 additions & 0 deletions go/vt/vtgate/evalengine/testcases/cases.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ var Cases = []TestCase{
{Run: FnMonth},
{Run: FnMonthName},
{Run: FnLastDay},
{Run: FnFromDays},
{Run: FnQuarter},
{Run: FnSecond},
{Run: FnTime},
Expand Down Expand Up @@ -1766,6 +1767,28 @@ func FnLastDay(yield Query) {
}
}

func FnFromDays(yield Query) {
for _, d := range inputConversions {
yield(fmt.Sprintf("FROM_DAYS(%s)", d), nil)
}

days := []string{
"0",
"1",
"366",
"365242",
"3652424",
"3652425",
beingnoble03 marked this conversation as resolved.
Show resolved Hide resolved
"3652500",
"3652499",
"730669",
}

for _, d := range days {
yield(fmt.Sprintf("FROM_DAYS(%s)", d), nil)
}
}

func FnQuarter(yield Query) {
for _, d := range inputConversions {
yield(fmt.Sprintf("QUARTER(%s)", d), nil)
Expand Down
5 changes: 5 additions & 0 deletions go/vt/vtgate/evalengine/translate_builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,11 @@
return nil, argError(method)
}
return &builtinLastDay{CallExpr: call}, nil
case "from_days":
if len(args) != 1 {
return nil, argError(method)
}

Check warning on line 425 in go/vt/vtgate/evalengine/translate_builtin.go

View check run for this annotation

Codecov / codecov/patch

go/vt/vtgate/evalengine/translate_builtin.go#L424-L425

Added lines #L424 - L425 were not covered by tests
return &builtinFromDays{CallExpr: call}, nil
case "quarter":
if len(args) != 1 {
return nil, argError(method)
Expand Down
Loading