From 7bbb70860822c2417794370fe4342572acd959c8 Mon Sep 17 00:00:00 2001 From: wjhuang2016 Date: Thu, 18 Jul 2019 18:47:42 +0800 Subject: [PATCH 1/2] planner: reject invalid conversion from like to = --- go.sum | 1 + planner/core/expression_rewriter.go | 2 +- planner/core/expression_rewriter_test.go | 17 +++++++++++++++++ planner/core/logical_plan_test.go | 2 +- planner/core/physical_plan_test.go | 5 ++--- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/go.sum b/go.sum index 1bc02a5605926..246e269e5d2de 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,7 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f h1:5ZfJxyXo8KyX8DgGXC5B7ILL8y51fci/qYz2B4j8iLY= github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= diff --git a/planner/core/expression_rewriter.go b/planner/core/expression_rewriter.go index d6b6a680498cf..dab2c03c3eb2a 100644 --- a/planner/core/expression_rewriter.go +++ b/planner/core/expression_rewriter.go @@ -1239,7 +1239,7 @@ func (er *expressionRewriter) patternLikeToExpression(v *ast.PatternLikeExpr) { } if !isNull { patValue, patTypes := stringutil.CompilePattern(patString, v.Escape) - if stringutil.IsExactMatch(patTypes) { + if stringutil.IsExactMatch(patTypes) && er.ctxStack[l-2].GetType().EvalType().IsStringKind() { op := ast.EQ if v.Not { op = ast.NE diff --git a/planner/core/expression_rewriter_test.go b/planner/core/expression_rewriter_test.go index 034634685e237..b9c59a67b5884 100644 --- a/planner/core/expression_rewriter_test.go +++ b/planner/core/expression_rewriter_test.go @@ -242,3 +242,20 @@ func (s *testExpressionRewriterSuite) TestCheckFullGroupBy(c *C) { err = tk.ExecToErr("select t1.a, (select t2.a, max(t2.b) from t t2) from t t1") c.Assert(terror.ErrorEqual(err, core.ErrMixOfGroupFuncAndFields), IsTrue, Commentf("err %v", err)) } + +func (s *testExpressionRewriterSuite) TestPatternLikeToExpression(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.MustQuery("select 0 like 'a string';").Check(testkit.Rows("0")) + tk.MustQuery("select 0.0 like 'a string';").Check(testkit.Rows("0")) + tk.MustQuery("select 0 like '0.00';").Check(testkit.Rows("0")) + tk.MustQuery("select 1 like '1';").Check(testkit.Rows("1")) + tk.MustQuery("select 0 like '0';").Check(testkit.Rows("1")) + tk.MustQuery("select 0.00 like '0.00';").Check(testkit.Rows("1")) +} diff --git a/planner/core/logical_plan_test.go b/planner/core/logical_plan_test.go index 683f2cdbe5d00..228ed07bde88e 100644 --- a/planner/core/logical_plan_test.go +++ b/planner/core/logical_plan_test.go @@ -84,7 +84,7 @@ func (s *testPlanSuite) TestPredicatePushDown(c *C) { }, { sql: "select * from t t1, t t2 where t1.a = t2.b and t2.b > 0 and t1.a = t1.c and t1.d like 'abc' and t2.d = t1.d", - best: "Join{DataScan(t1)->Sel([eq(cast(test.t1.d), cast(abc))])->DataScan(t2)->Sel([eq(cast(test.t2.d), cast(abc))])}(test.t1.a,test.t2.b)(test.t1.d,test.t2.d)->Projection", + best: "Join{DataScan(t1)->Sel([like(cast(test.t1.d), abc, 92)])->DataScan(t2)->Sel([like(cast(test.t2.d), abc, 92)])}(test.t1.a,test.t2.b)(test.t1.d,test.t2.d)->Projection", }, { sql: "select * from t ta join t tb on ta.d = tb.d and ta.d > 1 where tb.a = 0", diff --git a/planner/core/physical_plan_test.go b/planner/core/physical_plan_test.go index fec7136ebb46e..9b183c715fd2e 100644 --- a/planner/core/physical_plan_test.go +++ b/planner/core/physical_plan_test.go @@ -1162,11 +1162,10 @@ func (s *testPlanSuite) TestRefine(c *C) { sql: `select a from t where c_str like 123`, best: "IndexReader(Index(t.c_d_e_str)[[\"123\",\"123\"]])->Projection", }, - // c is type int which will be added cast to specified type when building function signature, - // and rewrite predicate like to predicate '=' when exact match , index still can be used. + // c is type int which will be added cast to specified type when building function signature, no index can be used. { sql: `select a from t where c like '1'`, - best: "IndexReader(Index(t.c_d_e)[[1,1]])->Projection", + best: "TableReader(Table(t))->Sel([like(cast(test.t.c), 1, 92)])->Projection", }, { sql: `select a from t where c = 1.9 and d > 3`, From 651870d4458622b7b952f2f876eefec7ca7eb94e Mon Sep 17 00:00:00 2001 From: wjhuang2016 Date: Tue, 23 Jul 2019 17:37:12 +0800 Subject: [PATCH 2/2] planner: reject invalid conversion from like to = --- planner/core/expression_rewriter.go | 2 +- planner/core/expression_rewriter_test.go | 1 + planner/core/physical_plan_test.go | 5 ----- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/planner/core/expression_rewriter.go b/planner/core/expression_rewriter.go index dab2c03c3eb2a..3d0b48cb32897 100644 --- a/planner/core/expression_rewriter.go +++ b/planner/core/expression_rewriter.go @@ -1239,7 +1239,7 @@ func (er *expressionRewriter) patternLikeToExpression(v *ast.PatternLikeExpr) { } if !isNull { patValue, patTypes := stringutil.CompilePattern(patString, v.Escape) - if stringutil.IsExactMatch(patTypes) && er.ctxStack[l-2].GetType().EvalType().IsStringKind() { + if stringutil.IsExactMatch(patTypes) && er.ctxStack[l-2].GetType().EvalType() == types.ETString { op := ast.EQ if v.Not { op = ast.NE diff --git a/planner/core/expression_rewriter_test.go b/planner/core/expression_rewriter_test.go index b9c59a67b5884..c180b6aea50cc 100644 --- a/planner/core/expression_rewriter_test.go +++ b/planner/core/expression_rewriter_test.go @@ -255,6 +255,7 @@ func (s *testExpressionRewriterSuite) TestPatternLikeToExpression(c *C) { tk.MustQuery("select 0 like 'a string';").Check(testkit.Rows("0")) tk.MustQuery("select 0.0 like 'a string';").Check(testkit.Rows("0")) tk.MustQuery("select 0 like '0.00';").Check(testkit.Rows("0")) + tk.MustQuery("select cast(\"2011-5-3\" as datetime) like \"2011-05-03\";").Check(testkit.Rows("0")) tk.MustQuery("select 1 like '1';").Check(testkit.Rows("1")) tk.MustQuery("select 0 like '0';").Check(testkit.Rows("1")) tk.MustQuery("select 0.00 like '0.00';").Check(testkit.Rows("1")) diff --git a/planner/core/physical_plan_test.go b/planner/core/physical_plan_test.go index 9b183c715fd2e..915de4c557d53 100644 --- a/planner/core/physical_plan_test.go +++ b/planner/core/physical_plan_test.go @@ -1162,11 +1162,6 @@ func (s *testPlanSuite) TestRefine(c *C) { sql: `select a from t where c_str like 123`, best: "IndexReader(Index(t.c_d_e_str)[[\"123\",\"123\"]])->Projection", }, - // c is type int which will be added cast to specified type when building function signature, no index can be used. - { - sql: `select a from t where c like '1'`, - best: "TableReader(Table(t))->Sel([like(cast(test.t.c), 1, 92)])->Projection", - }, { sql: `select a from t where c = 1.9 and d > 3`, best: "Dual",