Skip to content

Commit

Permalink
evalengine: Implement TO_SECONDS (#15590)
Browse files Browse the repository at this point in the history
Signed-off-by: Noble Mittal <noblemittal@outlook.com>
  • Loading branch information
beingnoble03 committed Apr 1, 2024
1 parent add3887 commit b2e5ce7
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 1 deletion.
5 changes: 5 additions & 0 deletions go/mysql/datetime/datetime.go
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,11 @@ func (dt DateTime) toDuration() time.Duration {
return dur
}

func (dt DateTime) ToSeconds() int64 {
numDays := MysqlDayNumber(dt.Date.Year(), dt.Date.Month(), dt.Date.Day())
return int64(numDays*24*3600) + dt.Time.ToSeconds()
}

func (dt *DateTime) addInterval(itv *Interval) bool {
switch {
case itv.unit.HasTimeParts():
Expand Down
13 changes: 12 additions & 1 deletion go/mysql/datetime/datetime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -552,10 +552,21 @@ func TestToSeconds(t *testing.T) {
assert.Equal(t, 45020, int(res))

// Neg Time Case
tt.hour = 1<<15 | tt.hour
tt.hour |= 1 << 15
res = tt.ToSeconds()

assert.Equal(t, -45020, int(res))

dt := NewDateTimeFromStd(testGoTime)

res = dt.ToSeconds()
assert.Equal(t, 63877465820, int(res))

// Neg Time Case
dt.Time.hour |= 1 << 15
res = dt.ToSeconds()

assert.Equal(t, 63877375780, int(res))
}

func TestToStdTime(t *testing.T) {
Expand Down
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.

11 changes: 11 additions & 0 deletions go/vt/vtgate/evalengine/compiler_asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3927,6 +3927,17 @@ func (asm *assembler) Fn_TIME_TO_SEC() {
}, "FN TIME_TO_SEC TIME(SP-1)")
}

func (asm *assembler) Fn_TO_SECONDS() {
asm.emit(func(env *ExpressionEnv) int {
if env.vm.stack[env.vm.sp-1] == nil {
return 1
}
arg := env.vm.stack[env.vm.sp-1].(*evalTemporal)
env.vm.stack[env.vm.sp-1] = env.vm.arena.newEvalInt64(arg.dt.ToSeconds())
return 1
}, "FN TO_SECONDS DATETIME(SP-1)")
}

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

builtinToSeconds struct {
CallExpr
}

builtinQuarter struct {
CallExpr
}
Expand Down Expand Up @@ -188,6 +192,7 @@ var _ IR = (*builtinLastDay)(nil)
var _ IR = (*builtinToDays)(nil)
var _ IR = (*builtinFromDays)(nil)
var _ IR = (*builtinTimeToSec)(nil)
var _ IR = (*builtinToSeconds)(nil)
var _ IR = (*builtinQuarter)(nil)
var _ IR = (*builtinSecond)(nil)
var _ IR = (*builtinTime)(nil)
Expand Down Expand Up @@ -1373,6 +1378,40 @@ func (call *builtinTimeToSec) compile(c *compiler) (ctype, error) {
return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: arg.Flag | flagNullable}, nil
}

func (b *builtinToSeconds) eval(env *ExpressionEnv) (eval, error) {
date, err := b.arg1(env)
if err != nil {
return nil, err
}
if date == nil {
return nil, nil
}
dt := evalToDateTime(date, -1, env.now, false)
if dt == nil {
return nil, nil
}

return newEvalInt64(dt.dt.ToSeconds()), nil
}

func (call *builtinToSeconds) 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.Date, sqltypes.Datetime:
default:
c.asm.Convert_xDT(1, -1, false)
}
c.asm.Fn_TO_SECONDS()
c.asm.jumpDestination(skip)
return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: arg.Flag | flagNullable}, nil
}

func (b *builtinQuarter) eval(env *ExpressionEnv) (eval, error) {
date, err := b.arg1(env)
if err != nil {
Expand Down
35 changes: 35 additions & 0 deletions go/vt/vtgate/evalengine/testcases/cases.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ var Cases = []TestCase{
{Run: FnToDays},
{Run: FnFromDays},
{Run: FnTimeToSec},
{Run: FnToSeconds},
{Run: FnQuarter},
{Run: FnSecond},
{Run: FnTime},
Expand Down Expand Up @@ -1997,6 +1998,40 @@ func FnTimeToSec(yield Query) {
}
}

func FnToSeconds(yield Query) {
for _, t := range inputConversions {
yield(fmt.Sprintf("TO_SECONDS(%s)", t), nil)
}

timeInputs := []string{
`DATE'0000-00-00'`,
`0`,
`'0000-00-00'`,
`'00:00:00'`,
`DATE'2023-09-03 00:00:00'`,
`DATE'0000-00-00 00:00:00'`,
`950501`,
`'2007-10-07'`,
`'0000-01-01'`,
`TIME'00:00:00'`,
`TIME'120:01:12'`,
}

for _, t := range timeInputs {
yield(fmt.Sprintf("TO_SECONDS(%s)", t), nil)
}

mysqlDocSamples := []string{
`TO_SECONDS(950501)`,
`TO_SECONDS('2009-11-29')`,
`TO_SECONDS('2009-11-29 13:43:32')`,
}

for _, q := range mysqlDocSamples {
yield(q, 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 @@ -457,6 +457,11 @@ func (ast *astCompiler) translateFuncExpr(fn *sqlparser.FuncExpr) (IR, error) {
return nil, argError(method)
}
return &builtinTimeToSec{CallExpr: call}, nil
case "to_seconds":
if len(args) != 1 {
return nil, argError(method)
}
return &builtinToSeconds{CallExpr: call}, nil
case "quarter":
if len(args) != 1 {
return nil, argError(method)
Expand Down

0 comments on commit b2e5ce7

Please sign in to comment.