From 88f57d817c02657c2f7e9a8da3d9deb149ff644d Mon Sep 17 00:00:00 2001 From: Zhuhe Fang Date: Thu, 16 Apr 2020 22:27:16 +0800 Subject: [PATCH] planner: cannot simply outer join if a predicate just refers to the outer table (#16444) --- planner/core/logical_plan_test.go | 20 ++++++++++++++++++++ planner/core/rule_predicate_push_down.go | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/planner/core/logical_plan_test.go b/planner/core/logical_plan_test.go index 02757eac9b4e2..7c0d9dafc0af8 100644 --- a/planner/core/logical_plan_test.go +++ b/planner/core/logical_plan_test.go @@ -1578,3 +1578,23 @@ func (s *testPlanSuite) TestConflictedJoinTypeHints(c *C) { c.Assert(join.hintInfo, IsNil) c.Assert(join.preferJoinType, Equals, uint(0)) } + +func (s *testPlanSuite) TestSimplyOuterJoinWithOnlyOuterExpr(c *C) { + defer testleak.AfterTest(c)() + sql := "select * from t t1 right join t t0 ON TRUE where CONCAT_WS(t0.e=t0.e, 0, NULL) IS NULL" + ctx := context.TODO() + stmt, err := s.ParseOneStmt(sql, "", "") + c.Assert(err, IsNil) + Preprocess(s.ctx, stmt, s.is) + builder := NewPlanBuilder(MockContext(), s.is, &hint.BlockHintProcessor{}) + p, err := builder.Build(ctx, stmt) + c.Assert(err, IsNil) + p, err = logicalOptimize(ctx, builder.optFlag, p.(LogicalPlan)) + c.Assert(err, IsNil) + proj, ok := p.(*LogicalProjection) + c.Assert(ok, IsTrue) + join, ok := proj.Children()[0].(*LogicalJoin) + c.Assert(ok, IsTrue) + // previous wrong JoinType is InnerJoin + c.Assert(join.JoinType, Equals, RightOuterJoin) +} diff --git a/planner/core/rule_predicate_push_down.go b/planner/core/rule_predicate_push_down.go index b5d0291ee01fc..812a373c7889b 100644 --- a/planner/core/rule_predicate_push_down.go +++ b/planner/core/rule_predicate_push_down.go @@ -316,6 +316,10 @@ func simplifyOuterJoin(p *LogicalJoin, predicates []expression.Expression) { // then simplify embedding outer join. canBeSimplified := false for _, expr := range predicates { + // avoid the case where the expr only refers to the schema of outerTable + if expression.ExprFromSchema(expr, outerTable.Schema()) { + continue + } isOk := isNullRejected(p.ctx, innerTable.Schema(), expr) if isOk { canBeSimplified = true