From 0cac0526bd54df33a1d5b2ff8f323c2c8274ff26 Mon Sep 17 00:00:00 2001 From: wjhuang2016 Date: Fri, 15 Mar 2019 16:50:09 +0800 Subject: [PATCH 1/4] Fix unixtimestamp function --- expression/builtin_time.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/expression/builtin_time.go b/expression/builtin_time.go index 42b37ada48c38..f97c49a952662 100644 --- a/expression/builtin_time.go +++ b/expression/builtin_time.go @@ -3528,6 +3528,19 @@ func (c *unixTimestampFunctionClass) getFunction(ctx sessionctx.Context, args [] retDecimal = len(tmpStr) - dotIdx - 1 } } + if sf, ok := args[0].(*ScalarFunction); ok { + _, isGetVarSig := sf.Function.(*builtinGetVarSig) + if isGetVarSig { + tmpStr, _, err := sf.EvalString(ctx, chunk.Row{}) + if err != nil { + return nil, err + } + retDecimal = 0 + if dotIdx := strings.LastIndex(tmpStr, "."); dotIdx >= 0 { + retDecimal = len(tmpStr) - dotIdx - 1 + } + } + } } else { retDecimal = argType.Decimal } From 3c24c9b704c580d8d2bddb1e11c4d973dacacbd4 Mon Sep 17 00:00:00 2001 From: wjhuang2016 Date: Tue, 19 Mar 2019 16:00:00 +0800 Subject: [PATCH 2/4] Add test --- expression/builtin_time.go | 25 +++++++++++-------------- expression/builtin_time_test.go | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/expression/builtin_time.go b/expression/builtin_time.go index f97c49a952662..b60b2e30e3ebf 100644 --- a/expression/builtin_time.go +++ b/expression/builtin_time.go @@ -28,6 +28,7 @@ import ( "github.com/cznic/mathutil" "github.com/pingcap/errors" + "github.com/pingcap/parser/ast" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" "github.com/pingcap/tidb/sessionctx" @@ -3518,8 +3519,17 @@ func (c *unixTimestampFunctionClass) getFunction(ctx sessionctx.Context, args [] if argEvaltp == types.ETString { // Treat types.ETString as unspecified decimal. retDecimal = types.UnspecifiedLength + var tmpStr string + var err error + o := false if cnst, ok := args[0].(*Constant); ok { - tmpStr, _, err := cnst.EvalString(ctx, chunk.Row{}) + tmpStr, _, err = cnst.EvalString(ctx, chunk.Row{}) + o = true + } else if sf, ok := args[0].(*ScalarFunction); ok && sf.FuncName.L == ast.GetVar { + tmpStr, _, err = sf.EvalString(ctx, chunk.Row{}) + o = true + } + if o { if err != nil { return nil, err } @@ -3528,19 +3538,6 @@ func (c *unixTimestampFunctionClass) getFunction(ctx sessionctx.Context, args [] retDecimal = len(tmpStr) - dotIdx - 1 } } - if sf, ok := args[0].(*ScalarFunction); ok { - _, isGetVarSig := sf.Function.(*builtinGetVarSig) - if isGetVarSig { - tmpStr, _, err := sf.EvalString(ctx, chunk.Row{}) - if err != nil { - return nil, err - } - retDecimal = 0 - if dotIdx := strings.LastIndex(tmpStr, "."); dotIdx >= 0 { - retDecimal = len(tmpStr) - dotIdx - 1 - } - } - } } else { retDecimal = argType.Decimal } diff --git a/expression/builtin_time_test.go b/expression/builtin_time_test.go index 72f1b3b16e5f8..7574b0ee71b78 100644 --- a/expression/builtin_time_test.go +++ b/expression/builtin_time_test.go @@ -1616,6 +1616,22 @@ func (s *testEvaluatorSuite) TestUnixTimestamp(c *C) { c.Assert(err, IsNil) c.Assert(d.IsNull(), Equals, true) + // https://github.com/pingcap/tidb/issues/9729 + // Test UNIX_TIMESTAMP(@a). + resetStmtContext(s.ctx) + s.ctx.GetSessionVars().Users["a"] = "1970-01-01 08:00:01" + args = []types.Datum{types.NewStringDatum("a")} + getVarFunc, err := newFunctionForTest(s.ctx, ast.GetVar, s.datumsToConstants(args)...) + c.Assert(err, IsNil) + funcArgs := make([]Expression, 0, 1) + funcArgs = append(funcArgs, getVarFunc) + f, err = fc.getFunction(s.ctx, funcArgs) + c.Assert(err, IsNil) + d, err = evalBuiltinFunc(f, chunk.Row{}) + c.Assert(err, IsNil) + c.Assert(d.Kind(), Equals, types.KindInt64) + c.Assert(d.GetInt64(), Equals, int64(28801)) + // Set the time_zone variable, because UnixTimestamp() result depends on it. s.ctx.GetSessionVars().TimeZone = time.UTC tests := []struct { From 3768b5ed166cf8dcb83bcf992892318bdcafcf74 Mon Sep 17 00:00:00 2001 From: wjhuang2016 Date: Tue, 19 Mar 2019 16:21:08 +0800 Subject: [PATCH 3/4] Style change --- expression/builtin_time.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/expression/builtin_time.go b/expression/builtin_time.go index b60b2e30e3ebf..0e8a534c3ab87 100644 --- a/expression/builtin_time.go +++ b/expression/builtin_time.go @@ -3521,13 +3521,13 @@ func (c *unixTimestampFunctionClass) getFunction(ctx sessionctx.Context, args [] retDecimal = types.UnspecifiedLength var tmpStr string var err error - o := false + o := true if cnst, ok := args[0].(*Constant); ok { tmpStr, _, err = cnst.EvalString(ctx, chunk.Row{}) - o = true } else if sf, ok := args[0].(*ScalarFunction); ok && sf.FuncName.L == ast.GetVar { tmpStr, _, err = sf.EvalString(ctx, chunk.Row{}) - o = true + } else { + o = false } if o { if err != nil { From 17c00439a83258fcbf185c4090eac97ba7425bb8 Mon Sep 17 00:00:00 2001 From: wjhuang2016 Date: Tue, 26 Mar 2019 15:10:56 +0800 Subject: [PATCH 4/4] Fix return type according to #9861 --- expression/builtin_time.go | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/expression/builtin_time.go b/expression/builtin_time.go index 0e8a534c3ab87..251d9ab901d6d 100644 --- a/expression/builtin_time.go +++ b/expression/builtin_time.go @@ -28,7 +28,6 @@ import ( "github.com/cznic/mathutil" "github.com/pingcap/errors" - "github.com/pingcap/parser/ast" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" "github.com/pingcap/tidb/sessionctx" @@ -3517,19 +3516,10 @@ func (c *unixTimestampFunctionClass) getFunction(ctx sessionctx.Context, args [] argType := args[0].GetType() argEvaltp := argType.EvalType() if argEvaltp == types.ETString { - // Treat types.ETString as unspecified decimal. - retDecimal = types.UnspecifiedLength - var tmpStr string - var err error - o := true - if cnst, ok := args[0].(*Constant); ok { - tmpStr, _, err = cnst.EvalString(ctx, chunk.Row{}) - } else if sf, ok := args[0].(*ScalarFunction); ok && sf.FuncName.L == ast.GetVar { - tmpStr, _, err = sf.EvalString(ctx, chunk.Row{}) + if _, ok := args[0].(*Column); ok { + retDecimal = types.UnspecifiedLength } else { - o = false - } - if o { + tmpStr, _, err := args[0].EvalString(ctx, chunk.Row{}) if err != nil { return nil, err }