From d4c688f8f89ca496bcb4b61d5150151fdfb3a3ed Mon Sep 17 00:00:00 2001 From: ti-srebot <66930949+ti-srebot@users.noreply.github.com> Date: Sun, 27 Sep 2020 13:51:56 +0800 Subject: [PATCH] executor, expression: set the evalType of hybrid type as ETInt in VecEvalBool (#20221) --- executor/aggregate.go | 4 ++-- executor/executor_test.go | 14 ++++++++++++++ expression/expression.go | 10 +++++++--- expression/expression_test.go | 4 ++-- expression/util_test.go | 2 +- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/executor/aggregate.go b/executor/aggregate.go index 58fd9b9cb613a..e1311636c0326 100644 --- a/executor/aggregate.go +++ b/executor/aggregate.go @@ -452,7 +452,7 @@ func getGroupKey(ctx sessionctx.Context, input *chunk.Chunk, groupKey [][]byte, return nil, err } - if err := expression.EvalExpr(ctx, item, input, buf); err != nil { + if err := expression.EvalExpr(ctx, item, tp.EvalType(), input, buf); err != nil { expression.PutColumn(buf) return nil, err } @@ -1110,7 +1110,7 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express return err } defer e.releaseBuffer(col) - err = expression.EvalExpr(e.ctx, item, chk, col) + err = expression.EvalExpr(e.ctx, item, eType, chk, col) if err != nil { return err } diff --git a/executor/executor_test.go b/executor/executor_test.go index cf83ebd453ca1..035d7631bfa31 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -3167,6 +3167,12 @@ func (s *testSuite) TestBit(c *C) { tk.MustExec("insert into t values ('12345678')") _, err = tk.Exec("insert into t values ('123456789')") c.Assert(err, NotNil) + + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (c1 bit(64))") + tk.MustExec("insert into t values (0xffffffffffffffff)") + tk.MustExec("insert into t values ('12345678')") + tk.MustQuery("select * from t where c1").Check(testkit.Rows("\xff\xff\xff\xff\xff\xff\xff\xff", "12345678")) } func (s *testSuite) TestEnum(c *C) { @@ -3183,6 +3189,10 @@ func (s *testSuite) TestEnum(c *C) { tk.MustExec("insert into t values ()") tk.MustExec("insert into t values (null), ('1')") tk.MustQuery("select c + 1 from t where c = 1").Check(testkit.Rows("2")) + + tk.MustExec("delete from t") + tk.MustExec("insert into t values(1), (2), (3)") + tk.MustQuery("select * from t where c").Check(testkit.Rows("a", "b", "c")) } func (s *testSuite) TestSet(c *C) { @@ -3201,6 +3211,10 @@ func (s *testSuite) TestSet(c *C) { tk.MustExec("insert into t values ()") tk.MustExec("insert into t values (null), ('1')") tk.MustQuery("select c + 1 from t where c = 1").Check(testkit.Rows("2")) + + tk.MustExec("delete from t") + tk.MustExec("insert into t values(3)") + tk.MustQuery("select * from t where c").Check(testkit.Rows("a,b")) } func (s *testSuite) TestSubqueryInValues(c *C) { diff --git a/expression/expression.go b/expression/expression.go index 36be2a14475fc..7062e6fedf5d3 100644 --- a/expression/expression.go +++ b/expression/expression.go @@ -322,12 +322,15 @@ func VecEvalBool(ctx sessionctx.Context, exprList CNFExprs, input *chunk.Chunk, defer deallocateZeroSlice(isZero) for _, expr := range exprList { eType := expr.GetType().EvalType() + if expr.GetType().Hybrid() { + eType = types.ETInt + } buf, err := globalColumnAllocator.get(eType, n) if err != nil { return nil, nil, err } - if err := EvalExpr(ctx, expr, input, buf); err != nil { + if err := EvalExpr(ctx, expr, eType, input, buf); err != nil { return nil, nil, err } @@ -463,8 +466,9 @@ func toBool(sc *stmtctx.StatementContext, eType types.EvalType, buf *chunk.Colum // EvalExpr evaluates this expr according to its type. // And it selects the method for evaluating expression based on // the environment variables and whether the expression can be vectorized. -func EvalExpr(ctx sessionctx.Context, expr Expression, input *chunk.Chunk, result *chunk.Column) (err error) { - evalType := expr.GetType().EvalType() +// Note: the input argument `evalType` is needed because of that when `expr` is +// of the hybrid type(ENUM/SET/BIT), we need the invoker decide the actual EvalType. +func EvalExpr(ctx sessionctx.Context, expr Expression, evalType types.EvalType, input *chunk.Chunk, result *chunk.Column) (err error) { if expr.Vectorized() && ctx.GetSessionVars().EnableVectorizedExpression { switch evalType { case types.ETInt: diff --git a/expression/expression_test.go b/expression/expression_test.go index b6b88506fabc5..2ecdc12f465eb 100644 --- a/expression/expression_test.go +++ b/expression/expression_test.go @@ -203,12 +203,12 @@ func (s *testEvaluatorSuite) TestEvalExpr(c *C) { var err error c.Assert(colExpr.Vectorized(), IsTrue) ctx.GetSessionVars().EnableVectorizedExpression = false - err = EvalExpr(ctx, colExpr, input, colBuf) + err = EvalExpr(ctx, colExpr, colExpr.GetType().EvalType(), input, colBuf) if err != nil { c.Fatal(err) } ctx.GetSessionVars().EnableVectorizedExpression = true - err = EvalExpr(ctx, colExpr, input, colBuf2) + err = EvalExpr(ctx, colExpr, colExpr.GetType().EvalType(), input, colBuf2) if err != nil { c.Fatal(err) } diff --git a/expression/util_test.go b/expression/util_test.go index 0b3c4242e9fc6..b86968c9675db 100644 --- a/expression/util_test.go +++ b/expression/util_test.go @@ -371,7 +371,7 @@ func (s *testUtilSuite) TestHashGroupKey(c *check.C) { bufs[j] = bufs[j][:0] } var err error - err = EvalExpr(ctx, colExpr, input, colBuf) + err = EvalExpr(ctx, colExpr, colExpr.GetType().EvalType(), input, colBuf) if err != nil { c.Fatal(err) }