From db798765ef26ef4de8dd0cdfd1eec28119fde624 Mon Sep 17 00:00:00 2001 From: ti-srebot <66930949+ti-srebot@users.noreply.github.com> Date: Tue, 11 May 2021 18:35:40 +0800 Subject: [PATCH] planner: fix incorrect duration between compare (#22830) (#23233) --- expression/builtin_compare.go | 18 +++++++++++------- planner/core/expression_rewriter.go | 5 +++++ planner/core/expression_rewriter_test.go | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/expression/builtin_compare.go b/expression/builtin_compare.go index 671073dfcf37e..5fe32e958249f 100644 --- a/expression/builtin_compare.go +++ b/expression/builtin_compare.go @@ -385,14 +385,18 @@ func ResolveType4Between(args [3]Expression) types.EvalType { hasTemporal := false if cmpTp == types.ETString { - for _, arg := range args { - if types.IsTypeTemporal(arg.GetType().Tp) { - hasTemporal = true - break + if args[0].GetType().Tp == mysql.TypeDuration { + cmpTp = types.ETDuration + } else { + for _, arg := range args { + if types.IsTypeTemporal(arg.GetType().Tp) { + hasTemporal = true + break + } + } + if hasTemporal { + cmpTp = types.ETDatetime } - } - if hasTemporal { - cmpTp = types.ETDatetime } } diff --git a/planner/core/expression_rewriter.go b/planner/core/expression_rewriter.go index df9b73a778178..e36eb6efac784 100644 --- a/planner/core/expression_rewriter.go +++ b/planner/core/expression_rewriter.go @@ -1548,6 +1548,11 @@ func (er *expressionRewriter) wrapExpWithCast() (expr, lexp, rexp expression.Exp } return expression.WrapWithCastAsString(ctx, e) } + case types.ETDuration: + expr = expression.WrapWithCastAsTime(er.sctx, expr, types.NewFieldType(mysql.TypeDuration)) + lexp = expression.WrapWithCastAsTime(er.sctx, lexp, types.NewFieldType(mysql.TypeDuration)) + rexp = expression.WrapWithCastAsTime(er.sctx, rexp, types.NewFieldType(mysql.TypeDuration)) + return case types.ETDatetime: expr = expression.WrapWithCastAsTime(er.sctx, expr, types.NewFieldType(mysql.TypeDatetime)) lexp = expression.WrapWithCastAsTime(er.sctx, lexp, types.NewFieldType(mysql.TypeDatetime)) diff --git a/planner/core/expression_rewriter_test.go b/planner/core/expression_rewriter_test.go index 874aba58f7686..66bb860a52f0b 100644 --- a/planner/core/expression_rewriter_test.go +++ b/planner/core/expression_rewriter_test.go @@ -377,3 +377,21 @@ func (s *testExpressionRewriterSuite) TestCompareMultiFieldsInSubquery(c *C) { tk.MustQuery("SELECT * FROM t3 WHERE (SELECT c1, c2 FROM t3 LIMIT 1) != ALL(SELECT c1, c2 FROM t4);").Check(testkit.Rows()) } + +func (s *testExpressionRewriterSuite) TestIssue22818(c *C) { + defer testleak.AfterTest(c)() + store, dom, err := newStoreWithBootstrap() + c.Assert(err, IsNil) + tk := testkit.NewTestKit(c, store) + defer func() { + dom.Close() + store.Close() + }() + + tk.MustExec("use test;") + tk.MustExec("drop table if exists t;") + tk.MustExec("create table t(a time);") + tk.MustExec("insert into t values(\"23:22:22\");") + tk.MustQuery("select * from t where a between \"23:22:22\" and \"23:22:22\"").Check( + testkit.Rows("23:22:22")) +}