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
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.

17 changes: 17 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,23 @@ 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)
if arg == nil {
beingnoble03 marked this conversation as resolved.
Show resolved Hide resolved
return 1
}

d := fromDays(env.currentTimezone(), arg.i)
if d == nil || d.IsZero() {
env.vm.stack[env.vm.sp-1] = nil
} else {
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
52 changes: 52 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 @@ type (
CallExpr
}

builtinFromDays struct {
CallExpr
}

builtinQuarter struct {
CallExpr
}
Expand Down Expand Up @@ -173,6 +177,7 @@ var _ IR = (*builtinMinute)(nil)
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,53 @@ func (call *builtinLastDay) compile(c *compiler) (ctype, error) {
return ctype{Type: sqltypes.Date, Flag: arg.Flag | flagNullable}, nil
}

func fromDays(loc *time.Location, d int64) *datetime.Date {
// 3652424 days corresponds to maximum date i.e. 9999-12-31
// mysql returns 0000-00-00 for days below 366
if d > 3652424 || d < 366 {
beingnoble03 marked this conversation as resolved.
Show resolved Hide resolved
return nil
beingnoble03 marked this conversation as resolved.
Show resolved Hide resolved
}

t := time.Date(1, time.January, 1, 0, 0, 0, 0, loc).AddDate(0, 0, int(d-366))
dt := datetime.NewDateFromStd(t)
return &dt
}

func (b *builtinFromDays) eval(env *ExpressionEnv) (eval, error) {
d, err := b.arg1(env)
if err != nil {
return nil, err
}
if d == nil {
return nil, nil
}
days := evalToInt64(d).i
dt := fromDays(env.currentTimezone(), days)

if dt == nil {
return nil, nil
}
return newEvalDate(*dt, env.sqlmode.AllowZeroDate()), nil
beingnoble03 marked this conversation as resolved.
Show resolved Hide resolved
}

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

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
20 changes: 20 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,25 @@ 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
}

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 @@ func (ast *astCompiler) translateFuncExpr(fn *sqlparser.FuncExpr) (IR, error) {
return nil, argError(method)
}
return &builtinLastDay{CallExpr: call}, nil
case "from_days":
if len(args) != 1 {
return nil, argError(method)
}
return &builtinFromDays{CallExpr: call}, nil
case "quarter":
if len(args) != 1 {
return nil, argError(method)
Expand Down
Loading