Skip to content

Commit

Permalink
plan: not build dual for AntiSemiJoin when condition is constant false (
Browse files Browse the repository at this point in the history
  • Loading branch information
eurekaka authored and iamzhoug37 committed Dec 13, 2018
1 parent f4e0929 commit 338200f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
28 changes: 28 additions & 0 deletions planner/core/logical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,34 @@ func (s *testPlanSuite) TestSimplifyOuterJoin(c *C) {
}
}

func (s *testPlanSuite) TestAntiSemiJoinConstFalse(c *C) {
defer testleak.AfterTest(c)()
tests := []struct {
sql string
best string
joinType string
}{
{
sql: "select a from t t1 where not exists (select a from t t2 where t1.a = t2.a and t2.b = 1 and t2.b = 2)",
best: "Join{DataScan(t1)->DataScan(t2)}->Projection",
joinType: "anti semi join",
},
}
for _, ca := range tests {
comment := Commentf("for %s", ca.sql)
stmt, err := s.ParseOneStmt(ca.sql, "", "")
c.Assert(err, IsNil, comment)
p, err := BuildLogicalPlan(s.ctx, stmt, s.is)
c.Assert(err, IsNil, comment)
p, err = logicalOptimize(flagDecorrelate|flagPredicatePushDown|flagPrunColumns, p.(LogicalPlan))
c.Assert(err, IsNil, comment)
c.Assert(ToString(p), Equals, ca.best, comment)
join, _ := p.(LogicalPlan).Children()[0].(*LogicalJoin)
joinType := fmt.Sprintf("%s", join.JoinType.String())
c.Assert(joinType, Equals, ca.joinType, comment)
}
}

func newPartitionInfoSchema(definitions []model.PartitionDefinition) infoschema.InfoSchema {
tableInfo := *MockTable()
cols := make([]*model.ColumnInfo, 0, len(tableInfo.Columns))
Expand Down
11 changes: 7 additions & 4 deletions planner/core/rule_predicate_push_down.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,13 @@ func (p *LogicalJoin) PredicatePushDown(predicates []expression.Expression) (ret
tempCond = append(tempCond, predicates...)
tempCond = expression.ExtractFiltersFromDNFs(p.ctx, tempCond)
tempCond = expression.PropagateConstant(p.ctx, tempCond)
// Return table dual when filter is constant false or null.
dual := conds2TableDual(p, tempCond)
if dual != nil {
return ret, dual
// Return table dual when filter is constant false or null. Not applicable to AntiSemiJoin.
// TODO: For AntiSemiJoin, we can use outer plan to substitute LogicalJoin actually.
if p.JoinType != AntiSemiJoin {
dual := conds2TableDual(p, tempCond)
if dual != nil {
return ret, dual
}
}
equalCond, leftPushCond, rightPushCond, otherCond = extractOnCondition(tempCond, leftPlan, rightPlan, true, true)
p.LeftConditions = nil
Expand Down

0 comments on commit 338200f

Please sign in to comment.