Skip to content

Commit

Permalink
evalengine: Return evalTemporal types for current date / time (#15079)
Browse files Browse the repository at this point in the history
Signed-off-by: Dirkjan Bussink <[email protected]>
  • Loading branch information
dbussink authored Jan 30, 2024
1 parent c156ca2 commit 77dc0c9
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 37 deletions.
4 changes: 2 additions & 2 deletions go/mysql/datetime/datetime.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,9 +546,9 @@ func (dt DateTime) Compare(dt2 DateTime) int {
return dt.Time.Compare(dt2.Time)
}

func (dt DateTime) AddInterval(itv *Interval, stradd bool) (DateTime, uint8, bool) {
func (dt DateTime) AddInterval(itv *Interval, prec uint8, stradd bool) (DateTime, uint8, bool) {
ok := dt.addInterval(itv)
return dt, itv.precision(stradd), ok
return dt, max(prec, itv.precision(stradd)), ok
}

func (dt DateTime) Round(p int) (r DateTime) {
Expand Down
37 changes: 15 additions & 22 deletions go/vt/vtgate/evalengine/compiler_asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3286,31 +3286,32 @@ func cmpnum[N interface{ int64 | uint64 | float64 }](a, b N) int {
}
}

func (asm *assembler) Fn_Now(t querypb.Type, format *datetime.Strftime, prec uint8, utc bool) {
func (asm *assembler) Fn_Now(prec uint8, utc bool) {
asm.adjustStack(1)
asm.emit(func(env *ExpressionEnv) int {
val := env.vm.arena.newEvalBytesEmpty()
val.tt = int16(t)
val.bytes = format.Format(env.time(utc), prec)
val.col = collationBinary
env.vm.stack[env.vm.sp] = val
env.vm.stack[env.vm.sp] = env.vm.arena.newEvalDateTime(env.time(utc), int(prec))
env.vm.sp++
return 1
}, "FN NOW")
}, "FN NOW(DATETIME)")
}

func (asm *assembler) Fn_NowTime(prec uint8, utc bool) {
asm.adjustStack(1)
asm.emit(func(env *ExpressionEnv) int {
env.vm.stack[env.vm.sp] = env.vm.arena.newEvalTime(env.time(utc).Time, int(prec))
env.vm.sp++
return 1
}, "FN NOW(TIME)")
}

func (asm *assembler) Fn_Sysdate(prec uint8) {
asm.adjustStack(1)
asm.emit(func(env *ExpressionEnv) int {
val := env.vm.arena.newEvalBytesEmpty()
val.tt = int16(sqltypes.Datetime)
now := SystemTime()
if tz := env.currentTimezone(); tz != nil {
now = now.In(tz)
}
val.bytes = datetime.NewDateTimeFromStd(now).Format(prec)
val.col = collationBinary
env.vm.stack[env.vm.sp] = val
env.vm.stack[env.vm.sp] = env.vm.arena.newEvalDateTime(datetime.NewDateTimeFromStd(now), int(prec))
env.vm.sp++
return 1
}, "FN SYSDATE")
Expand All @@ -3319,11 +3320,7 @@ func (asm *assembler) Fn_Sysdate(prec uint8) {
func (asm *assembler) Fn_Curdate() {
asm.adjustStack(1)
asm.emit(func(env *ExpressionEnv) int {
val := env.vm.arena.newEvalBytesEmpty()
val.tt = int16(sqltypes.Date)
val.bytes = datetime.Date_YYYY_MM_DD.Format(env.time(false), 0)
val.col = collationBinary
env.vm.stack[env.vm.sp] = val
env.vm.stack[env.vm.sp] = env.vm.arena.newEvalDate(env.time(false).Date)
env.vm.sp++
return 1
}, "FN CURDATE")
Expand All @@ -3332,11 +3329,7 @@ func (asm *assembler) Fn_Curdate() {
func (asm *assembler) Fn_UtcDate() {
asm.adjustStack(1)
asm.emit(func(env *ExpressionEnv) int {
val := env.vm.arena.newEvalBytesEmpty()
val.tt = int16(sqltypes.Date)
val.bytes = datetime.Date_YYYY_MM_DD.Format(env.time(true), 0)
val.col = collationBinary
env.vm.stack[env.vm.sp] = val
env.vm.stack[env.vm.sp] = env.vm.arena.newEvalDate(env.time(true).Date)
env.vm.sp++
return 1
}, "FN UTC_DATE")
Expand Down
10 changes: 9 additions & 1 deletion go/vt/vtgate/evalengine/compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,14 @@ func TestCompilerSingle(t *testing.T) {
expression: `CAST(time '32:34:58.5' AS TIME)`,
result: `TIME("32:34:59")`,
},
{
expression: `now(6) + interval 1 day`,
result: `DATETIME("2023-10-25 12:00:00.123456")`,
},
{
expression: `now() + interval 654321 microsecond`,
result: `DATETIME("2023-10-24 12:00:00.654321")`,
},
}

tz, _ := time.LoadLocation("Europe/Madrid")
Expand All @@ -629,7 +637,7 @@ func TestCompilerSingle(t *testing.T) {
}

env := evalengine.NewExpressionEnv(context.Background(), nil, evalengine.NewEmptyVCursor(venv, tz))
env.SetTime(time.Date(2023, 10, 24, 12, 0, 0, 0, tz))
env.SetTime(time.Date(2023, 10, 24, 12, 0, 0, 123456000, tz))
env.Row = tc.values

expected, err := env.EvaluateAST(converted)
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/evalengine/eval_temporal.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func (e *evalTemporal) addInterval(interval *datetime.Interval, coll collations.
tmp.dt.Time, tmp.prec, ok = e.dt.Time.AddInterval(interval, coll != collations.Unknown)
case tt == sqltypes.Datetime || tt == sqltypes.Timestamp || (tt == sqltypes.Date && interval.Unit().HasTimeParts()) || (tt == sqltypes.Time && interval.Unit().HasDateParts()):
tmp = e.toDateTime(int(e.prec), now)
tmp.dt, tmp.prec, ok = e.dt.AddInterval(interval, coll != collations.Unknown)
tmp.dt, tmp.prec, ok = e.dt.AddInterval(interval, tmp.prec, coll != collations.Unknown)
}
if !ok {
return nil
Expand Down
18 changes: 7 additions & 11 deletions go/vt/vtgate/evalengine/fn_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,26 +196,22 @@ var _ IR = (*builtinYearWeek)(nil)
func (call *builtinNow) eval(env *ExpressionEnv) (eval, error) {
now := env.time(call.utc)
if call.onlyTime {
buf := datetime.Time_hh_mm_ss.Format(now, call.prec)
return newEvalRaw(sqltypes.Time, buf, collationBinary), nil
return newEvalTime(now.Time, int(call.prec)), nil
} else {
buf := datetime.DateTime_YYYY_MM_DD_hh_mm_ss.Format(now, call.prec)
return newEvalRaw(sqltypes.Datetime, buf, collationBinary), nil
return newEvalDateTime(now, int(call.prec), false), nil
}
}

func (call *builtinNow) compile(c *compiler) (ctype, error) {
var format *datetime.Strftime
var t sqltypes.Type

if call.onlyTime {
format = datetime.Time_hh_mm_ss
t = sqltypes.Time
c.asm.Fn_NowTime(call.prec, call.utc)
} else {
format = datetime.DateTime_YYYY_MM_DD_hh_mm_ss
t = sqltypes.Datetime
c.asm.Fn_Now(call.prec, call.utc)
}
c.asm.Fn_Now(t, format, call.prec, call.utc)
return ctype{Type: t, Col: collationBinary}, nil
}

Expand All @@ -228,7 +224,7 @@ func (call *builtinSysdate) eval(env *ExpressionEnv) (eval, error) {
if tz := env.currentTimezone(); tz != nil {
now = now.In(tz)
}
return newEvalRaw(sqltypes.Datetime, datetime.NewDateTimeFromStd(now).Format(call.prec), collationBinary), nil
return newEvalDateTime(datetime.NewDateTimeFromStd(now), int(call.prec), false), nil
}

func (call *builtinSysdate) compile(c *compiler) (ctype, error) {
Expand All @@ -242,7 +238,7 @@ func (call *builtinSysdate) constant() bool {

func (call *builtinCurdate) eval(env *ExpressionEnv) (eval, error) {
now := env.time(false)
return newEvalRaw(sqltypes.Date, datetime.Date_YYYY_MM_DD.Format(now, 0), collationBinary), nil
return newEvalDate(now.Date, false), nil
}

func (*builtinCurdate) compile(c *compiler) (ctype, error) {
Expand All @@ -256,7 +252,7 @@ func (call *builtinCurdate) constant() bool {

func (call *builtinUtcDate) eval(env *ExpressionEnv) (eval, error) {
now := env.time(true)
return newEvalRaw(sqltypes.Date, datetime.Date_YYYY_MM_DD.Format(now, 0), collationBinary), nil
return newEvalDate(now.Date, false), nil
}

func (*builtinUtcDate) compile(c *compiler) (ctype, error) {
Expand Down

0 comments on commit 77dc0c9

Please sign in to comment.