Skip to content

Commit

Permalink
expression: fix the panic when we use unix_time expression in `prep…
Browse files Browse the repository at this point in the history
…are and execute` statement. (#17855)

* expression: fix Const.DeferredExpr's wrong behavior

* clean the code

* FIX UT

* revert the change and add check for `funcCallToExpression`

* solve conflicts

* fix typo

* address comments

Co-authored-by: pingcap-github-bot <sre-bot@pingcap.com>
  • Loading branch information
Reminiscent and sre-bot authored Jun 15, 2020
1 parent 60dbf2b commit 8a33340
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
36 changes: 36 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6620,6 +6620,42 @@ func (s *testIntegrationSuite) TestIssue17287(c *C) {
tk.MustQuery("execute stmt7 using @val2;").Check(testkit.Rows("1589873946"))
}

func (s *testIntegrationSuite) TestIssue17727(c *C) {
tk := testkit.NewTestKit(c, s.store)
orgEnable := plannercore.PreparedPlanCacheEnabled()
defer func() {
plannercore.SetPreparedPlanCache(orgEnable)
}()
plannercore.SetPreparedPlanCache(true)
var err error
tk.Se, err = session.CreateSession4TestWithOpt(s.store, &session.Opt{
PreparedPlanCache: kvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
})
c.Assert(err, IsNil)

tk.MustExec("use test;")
tk.MustExec("DROP TABLE IF EXISTS t1;")
tk.MustExec("CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY auto_increment, a timestamp NOT NULL);")
tk.MustExec("INSERT INTO t1 VALUES (null, '2020-05-30 20:30:00');")
tk.MustExec("PREPARE mystmt FROM 'SELECT * FROM t1 WHERE UNIX_TIMESTAMP(a) >= ?';")
tk.MustExec("SET @a=1590868800;")
tk.MustQuery("EXECUTE mystmt USING @a;").Check(testkit.Rows())
tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("0"))

tk.MustExec("SET @a=1590868801;")
tk.MustQuery("EXECUTE mystmt USING @a;").Check(testkit.Rows())
tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("1"))

tk.MustExec("prepare stmt from 'select unix_timestamp(?)';")
tk.MustExec("set @a = '2020-05-30 20:30:00';")
tk.MustQuery("execute stmt using @a;").Check(testkit.Rows("1590841800"))
tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("0"))

tk.MustExec("set @a = '2020-06-12 13:47:58';")
tk.MustQuery("execute stmt using @a;").Check(testkit.Rows("1591940878"))
tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("1"))
}

func (s *testIntegrationSerialSuite) TestIssue17891(c *C) {
collate.SetNewCollationEnabledForTest(true)
defer collate.SetNewCollationEnabledForTest(false)
Expand Down
13 changes: 10 additions & 3 deletions planner/core/expression_rewriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -1526,9 +1526,16 @@ func (er *expressionRewriter) funcCallToExpression(v *ast.FuncCallExpr) {
var function expression.Expression
er.ctxStackPop(len(v.Args))
if _, ok := expression.DeferredFunctions[v.FnName.L]; er.useCache() && ok {
function, er.err = expression.NewFunctionBase(er.sctx, v.FnName.L, &v.Type, args...)
c := &expression.Constant{Value: types.NewDatum(nil), RetType: function.GetType().Clone(), DeferredExpr: function}
er.ctxStackAppend(c, types.EmptyName)
// When the expression is unix_timestamp and the number of argument is not zero,
// we deal with it as normal expression.
if v.FnName.L == ast.UnixTimestamp && len(v.Args) != 0 {
function, er.err = er.newFunction(v.FnName.L, &v.Type, args...)
er.ctxStackAppend(function, types.EmptyName)
} else {
function, er.err = expression.NewFunctionBase(er.sctx, v.FnName.L, &v.Type, args...)
c := &expression.Constant{Value: types.NewDatum(nil), RetType: function.GetType().Clone(), DeferredExpr: function}
er.ctxStackAppend(c, types.EmptyName)
}
} else {
function, er.err = er.newFunction(v.FnName.L, &v.Type, args...)
er.ctxStackAppend(function, types.EmptyName)
Expand Down

0 comments on commit 8a33340

Please sign in to comment.