Skip to content

Commit

Permalink
evalengine: Fix additional time type handling (#15614)
Browse files Browse the repository at this point in the history
Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
  • Loading branch information
dbussink authored Apr 2, 2024
1 parent 002ac54 commit 0c06cf9
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 6 deletions.
36 changes: 36 additions & 0 deletions go/vt/vtgate/evalengine/compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,42 @@ func TestCompilerSingle(t *testing.T) {
expression: `1 * unix_timestamp(utc_timestamp(1))`,
result: `DECIMAL(1698134400.1)`,
},
{
expression: `1 * unix_timestamp(CONVERT_TZ(20040101120000.10e0,'+00:00','+10:00'))`,
result: `DECIMAL(1072990800.101563)`,
},
{
expression: `1 * unix_timestamp(CONVERT_TZ(20040101120000.10,'+00:00','+10:00'))`,
result: `DECIMAL(1072990800.10)`,
},
{
expression: `1 * unix_timestamp(CONVERT_TZ(timestamp'2004-01-01 12:00:00.10','+00:00','+10:00'))`,
result: `DECIMAL(1072990800.10)`,
},
{
expression: `1 * unix_timestamp(CONVERT_TZ('2004-01-01 12:00:00.10','+00:00','+10:00'))`,
result: `DECIMAL(1072990800.10)`,
},
{
expression: `1 * unix_timestamp('2004-01-01 12:00:00.10')`,
result: `DECIMAL(1072954800.10)`,
},
{
expression: `1 * unix_timestamp(from_unixtime(1447430881.123))`,
result: `DECIMAL(1447430881.123)`,
},
{
expression: `1 * unix_timestamp(from_unixtime('1447430881.123'))`,
result: `DECIMAL(1447430881.123000)`,
},
{
expression: `1 * unix_timestamp(from_unixtime(time '31:34:58'))`,
result: `INT64(313458)`,
},
{
expression: `1 * unix_timestamp(from_unixtime(time '31:34:58.123'))`,
result: `DECIMAL(313458.123)`,
},
}

tz, _ := time.LoadLocation("Europe/Madrid")
Expand Down
4 changes: 2 additions & 2 deletions go/vt/vtgate/evalengine/fn_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (call *builtinVersion) eval(env *ExpressionEnv) (eval, error) {

func (*builtinVersion) compile(c *compiler) (ctype, error) {
c.asm.Fn_Version()
return ctype{Type: sqltypes.Datetime, Col: collationUtf8mb3}, nil
return ctype{Type: sqltypes.VarChar, Col: collationUtf8mb3}, nil
}

type builtinDatabase struct {
Expand All @@ -70,7 +70,7 @@ func (call *builtinDatabase) eval(env *ExpressionEnv) (eval, error) {

func (*builtinDatabase) compile(c *compiler) (ctype, error) {
c.asm.Fn_Database()
return ctype{Type: sqltypes.Datetime, Col: collationUtf8mb3}, nil
return ctype{Type: sqltypes.VarChar, Col: collationUtf8mb3}, nil
}

func (call *builtinDatabase) constant() bool {
Expand Down
27 changes: 23 additions & 4 deletions go/vt/vtgate/evalengine/fn_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (

var SystemTime = time.Now

const maxTimePrec = 6
const maxTimePrec = datetime.DefaultPrecision

type (
builtinNow struct {
Expand Down Expand Up @@ -424,15 +424,28 @@ func (call *builtinConvertTz) compile(c *compiler) (ctype, error) {
c.asm.Convert_xb(1, sqltypes.VarBinary, nil)
}

var prec int32
switch n.Type {
case sqltypes.Datetime, sqltypes.Date:
prec = n.Size
case sqltypes.Decimal, sqltypes.Time:
prec = n.Size
c.asm.Convert_xDT(3, -1, false)
case sqltypes.VarChar, sqltypes.VarBinary:
if lit, ok := call.Arguments[0].(*Literal); ok && !n.isHexOrBitLiteral() {
if dt := evalToDateTime(lit.inner, -1, time.Now(), c.sqlmode.AllowZeroDate()); dt != nil {
prec = int32(dt.prec)
}
}
c.asm.Convert_xDT(3, -1, false)
default:
prec = maxTimePrec
c.asm.Convert_xDT(3, -1, false)
}

c.asm.Fn_CONVERT_TZ()
c.asm.jumpDestination(skip)
return ctype{Type: sqltypes.Datetime, Col: collationBinary, Flag: n.Flag | flagNullable}, nil
return ctype{Type: sqltypes.Datetime, Col: collationBinary, Flag: n.Flag | flagNullable, Size: prec}, nil
}

func (b *builtinDate) eval(env *ExpressionEnv) (eval, error) {
Expand Down Expand Up @@ -689,17 +702,21 @@ func (call *builtinFromUnixtime) compile(c *compiler) (ctype, error) {
}
skip1 := c.compileNullCheck1(arg)

var prec int32
switch arg.Type {
case sqltypes.Int64:
c.asm.Fn_FROM_UNIXTIME_i()
case sqltypes.Uint64:
c.asm.Fn_FROM_UNIXTIME_u()
case sqltypes.Float64:
prec = maxTimePrec
c.asm.Fn_FROM_UNIXTIME_f()
case sqltypes.Decimal:
prec = arg.Size
c.asm.Fn_FROM_UNIXTIME_d()
case sqltypes.Datetime, sqltypes.Date, sqltypes.Time:
if arg.Size == 0 {
prec = arg.Size
if prec == 0 {
c.asm.Convert_Ti(1)
c.asm.Fn_FROM_UNIXTIME_i()
} else {
Expand All @@ -711,17 +728,19 @@ func (call *builtinFromUnixtime) compile(c *compiler) (ctype, error) {
c.asm.Convert_xu(1)
c.asm.Fn_FROM_UNIXTIME_u()
} else {
prec = maxTimePrec
c.asm.Convert_xf(1)
c.asm.Fn_FROM_UNIXTIME_f()
}
default:
prec = maxTimePrec
c.asm.Convert_xf(1)
c.asm.Fn_FROM_UNIXTIME_f()
}

if len(call.Arguments) == 1 {
c.asm.jumpDestination(skip1)
return ctype{Type: sqltypes.Datetime, Col: collationBinary, Flag: arg.Flag | flagNullable}, nil
return ctype{Type: sqltypes.Datetime, Col: collationBinary, Flag: arg.Flag | flagNullable, Size: prec}, nil
}

format, err := call.Arguments[1].compile(c)
Expand Down

0 comments on commit 0c06cf9

Please sign in to comment.