From 2b2f226309ee41c30913d05303212eeee3ff3b45 Mon Sep 17 00:00:00 2001 From: justarandomstring <847426363@qq.com> Date: Tue, 15 Oct 2019 01:42:30 +0800 Subject: [PATCH 1/3] add a test for left outer join --- planner/core/physical_plan_test.go | 37 +++++++++++++++++++++++ planner/core/testdata/plan_suite_in.json | 6 ++++ planner/core/testdata/plan_suite_out.json | 9 ++++++ 3 files changed, 52 insertions(+) diff --git a/planner/core/physical_plan_test.go b/planner/core/physical_plan_test.go index bba9dcb22f576..17e0e0e069f0b 100644 --- a/planner/core/physical_plan_test.go +++ b/planner/core/physical_plan_test.go @@ -1073,3 +1073,40 @@ func testDAGPlanBuilderSplitAvg(c *C, root core.PhysicalPlan) { testDAGPlanBuilderSplitAvg(c, son) } } + +func (s *testPlanSuite) TestSimplifyOuterJoinWithCast(c *C) { + defer testleak.AfterTest(c)() + store, dom, err := newStoreWithBootstrap() + c.Assert(err, IsNil) + defer func() { + dom.Close() + store.Close() + }() + se, err := session.CreateSession4Test(store) + c.Assert(err, IsNil) + _, err = se.Execute(context.Background(), "use test") + c.Assert(err, IsNil) + + var input []string + var output []struct { + SQL string + Best string + } + s.testData.GetTestCases(c, &input, &output) + for i, test := range input { + comment := Commentf("case:%v sql:%s", i, test) + stmt, err := s.ParseOneStmt(test, "", "") + c.Assert(err, IsNil, comment) + + p, err := planner.Optimize(context.Background(), se, stmt, s.is) + c.Assert(err, IsNil) + s.testData.OnRecord(func() { + output[i].SQL = test + output[i].Best = core.ToString(p) + }) + c.Assert(core.ToString(p), Equals, output[i].Best) + + warnings := se.GetSessionVars().StmtCtx.GetWarnings() + c.Assert(warnings, HasLen, 0, comment) + } +} diff --git a/planner/core/testdata/plan_suite_in.json b/planner/core/testdata/plan_suite_in.json index 55a6d826fad64..6c4fcbae7c956 100644 --- a/planner/core/testdata/plan_suite_in.json +++ b/planner/core/testdata/plan_suite_in.json @@ -481,5 +481,11 @@ "cases": [ "select t1.a, (select count(t2.a) from t t2 where t2.g in (select t3.d from t t3 where t3.c = t1.a)) as agg_col from t t1;" ] + }, + { + "name": "TestSimplifyOuterJoinWithCast", + "cases": [ + "select * from t t1 left join t t2 on t1.a = t2.a where cast(t1.c_str as float) = '2.3'" + ] } ] diff --git a/planner/core/testdata/plan_suite_out.json b/planner/core/testdata/plan_suite_out.json index 011f2a8f49524..420dcc7b9253c 100644 --- a/planner/core/testdata/plan_suite_out.json +++ b/planner/core/testdata/plan_suite_out.json @@ -1241,5 +1241,14 @@ "Best": "Apply{IndexReader(Index(t.f)[[NULL,+inf]])->IndexMergeJoin{IndexReader(Index(t.c_d_e)[[NULL,+inf]]->HashAgg)->HashAgg->IndexReader(Index(t.g)[[NULL,+inf]])}(Column#29,Column#23)}->HashAgg" } ] + }, + { + "Name": "TestSimplifyOuterJoinWithCast", + "Cases": [ + { + "SQL": "select * from t t1 left join t t2 on t1.a = t2.a where cast(t1.c_str as float) = '2.3'", + "Best": "MergeLeftOuterJoin{TableReader(Table(t))->Sel([eq(cast(Column#6), 2.3)])->TableReader(Table(t))}(Column#1,Column#13)" + } + ] } ] From fb0ecee8b47a374399d18cb5c6aea6d3dd21ddf7 Mon Sep 17 00:00:00 2001 From: justarandomstring <847426363@qq.com> Date: Tue, 15 Oct 2019 01:55:13 +0800 Subject: [PATCH 2/3] fix simplify outer join --- expression/expression.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/expression/expression.go b/expression/expression.go index 67c002622c192..5332a11c9e930 100644 --- a/expression/expression.go +++ b/expression/expression.go @@ -542,6 +542,9 @@ func EvaluateExprWithNull(ctx sessionctx.Context, schema *Schema, expr Expressio for i, arg := range x.GetArgs() { args[i] = EvaluateExprWithNull(ctx, schema, arg) } + if x.FuncName.L == ast.Cast { + return NewFunctionInternal(ctx, x.FuncName.L, x.RetType, args...) + } return NewFunctionInternal(ctx, x.FuncName.L, types.NewFieldType(mysql.TypeTiny), args...) case *Column: if !schema.Contains(x) { From ef000f45f3daf9f5744346aeba168406725cc27a Mon Sep 17 00:00:00 2001 From: justarandomstring <847426363@qq.com> Date: Tue, 15 Oct 2019 15:59:15 +0800 Subject: [PATCH 3/3] simplify the logic --- expression/expression.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/expression/expression.go b/expression/expression.go index 5332a11c9e930..b1d0345cfa0e8 100644 --- a/expression/expression.go +++ b/expression/expression.go @@ -542,10 +542,7 @@ func EvaluateExprWithNull(ctx sessionctx.Context, schema *Schema, expr Expressio for i, arg := range x.GetArgs() { args[i] = EvaluateExprWithNull(ctx, schema, arg) } - if x.FuncName.L == ast.Cast { - return NewFunctionInternal(ctx, x.FuncName.L, x.RetType, args...) - } - return NewFunctionInternal(ctx, x.FuncName.L, types.NewFieldType(mysql.TypeTiny), args...) + return NewFunctionInternal(ctx, x.FuncName.L, x.RetType, args...) case *Column: if !schema.Contains(x) { return x