diff --git a/executor/join_test.go b/executor/join_test.go index a78f6ac93a30d..2a740d7255f20 100644 --- a/executor/join_test.go +++ b/executor/join_test.go @@ -912,3 +912,14 @@ func (s *testSuite) TestMergejoinOrder(c *C) { `2.02`, )) } + +func (s *testSuite) TestEmbeddedOuterJoin(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("create table t1(a int, b int)") + tk.MustExec("create table t2(a int, b int)") + tk.MustExec("insert into t1 values(1, 1)") + tk.MustQuery("select * from (t1 left join t2 on t1.a = t2.a) left join (t2 t3 left join t2 t4 on t3.a = t4.a) on t2.b = 1"). + Check(testkit.Rows("1 1 ")) +} diff --git a/plan/predicate_push_down.go b/plan/predicate_push_down.go index 6ba9803e0e862..8265de74b8dce 100644 --- a/plan/predicate_push_down.go +++ b/plan/predicate_push_down.go @@ -245,20 +245,12 @@ func simplifyOuterJoin(p *LogicalJoin, predicates []expression.Expression) { innerTable, outerTable = outerTable, innerTable } - var fullConditions []expression.Expression - // first simplify embedded outer join. - // When trying to simplify an embedded outer join operation in a query, - // we must take into account the join condition for the embedding outer join together with the WHERE condition. if innerPlan, ok := innerTable.(*LogicalJoin); ok { - fullConditions = concatOnAndWhereConds(p, predicates) - simplifyOuterJoin(innerPlan, fullConditions) + simplifyOuterJoin(innerPlan, predicates) } if outerPlan, ok := outerTable.(*LogicalJoin); ok { - if fullConditions != nil { - fullConditions = concatOnAndWhereConds(p, predicates) - } - simplifyOuterJoin(outerPlan, fullConditions) + simplifyOuterJoin(outerPlan, predicates) } if p.JoinType == InnerJoin { @@ -298,20 +290,6 @@ func isNullRejected(ctx sessionctx.Context, schema *expression.Schema, expr expr return false } -// concatOnAndWhereConds concatenate ON conditions with WHERE conditions. -func concatOnAndWhereConds(join *LogicalJoin, predicates []expression.Expression) []expression.Expression { - numAllFilters := len(join.EqualConditions) + len(join.LeftConditions) + len(join.RightConditions) + len(join.OtherConditions) + len(predicates) - allFilters := make([]expression.Expression, 0, numAllFilters) - for _, equalCond := range join.EqualConditions { - allFilters = append(allFilters, equalCond) - } - allFilters = append(allFilters, join.LeftConditions...) - allFilters = append(allFilters, join.RightConditions...) - allFilters = append(allFilters, join.OtherConditions...) - allFilters = append(allFilters, predicates...) - return allFilters -} - // PredicatePushDown implements LogicalPlan PredicatePushDown interface. func (p *LogicalProjection) PredicatePushDown(predicates []expression.Expression) (ret []expression.Expression, retPlan LogicalPlan) { var push = make([]expression.Expression, 0, p.Schema().Len())