From 3e3b90580f588eb0b3c72b11f635e6ec9b2384db Mon Sep 17 00:00:00 2001 From: Kenan Yao Date: Thu, 18 Oct 2018 18:25:26 +0800 Subject: [PATCH] expression: maintain `DeferredExpr` in aggressive constant folding. (#7926) --- expression/constant_fold.go | 6 ++++++ expression/constant_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/expression/constant_fold.go b/expression/constant_fold.go index 0553b2c8c0c2a..0f7e85fa18ba9 100644 --- a/expression/constant_fold.go +++ b/expression/constant_fold.go @@ -118,9 +118,15 @@ func foldConstant(expr Expression) (Expression, bool) { return expr, isDeferredConst } if value.IsNull() { + if isDeferredConst { + return &Constant{Value: value, RetType: x.RetType, DeferredExpr: x}, true + } return &Constant{Value: value, RetType: x.RetType}, false } if isTrue, err := value.ToBool(sc); err == nil && isTrue == 0 { + if isDeferredConst { + return &Constant{Value: value, RetType: x.RetType, DeferredExpr: x}, true + } return &Constant{Value: value, RetType: x.RetType}, false } return expr, isDeferredConst diff --git a/expression/constant_test.go b/expression/constant_test.go index a2f4376afeeb2..bda66eb8b3f46 100644 --- a/expression/constant_test.go +++ b/expression/constant_test.go @@ -202,3 +202,31 @@ func (*testExpressionSuite) TestConstantFolding(c *C) { c.Assert(newConds.String(), Equals, tt.result, Commentf("different for expr %s", tt.condition)) } } + +func (*testExpressionSuite) TestDeferredExprNullConstantFold(c *C) { + defer testleak.AfterTest(c)() + nullConst := &Constant{ + Value: types.NewDatum(nil), + RetType: types.NewFieldType(mysql.TypeTiny), + DeferredExpr: Null, + } + tests := []struct { + condition Expression + deferred string + }{ + { + condition: newFunction(ast.LT, newColumn(0), nullConst), + deferred: "lt(test.t.0, )", + }, + } + for _, tt := range tests { + comment := Commentf("different for expr %s", tt.condition) + sf, ok := tt.condition.(*ScalarFunction) + c.Assert(ok, IsTrue, comment) + sf.GetCtx().GetSessionVars().StmtCtx.InNullRejectCheck = true + newConds := FoldConstant(tt.condition) + newConst, ok := newConds.(*Constant) + c.Assert(ok, IsTrue, comment) + c.Assert(newConst.DeferredExpr.String(), Equals, tt.deferred, comment) + } +}