Skip to content

Commit

Permalink
plan: return table dual when filter is false/null (#7756)
Browse files Browse the repository at this point in the history
  • Loading branch information
eurekaka committed Sep 25, 2018
1 parent 16864f9 commit 0001d2a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
5 changes: 5 additions & 0 deletions plan/logical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,11 @@ func (s *testPlanSuite) TestPredicatePushDown(c *C) {
sql: "select t1.a, t2.a from t as t1 left join t as t2 on t1.a = t2.a where t1.a < 1.0",
best: "Join{DataScan(t1)->DataScan(t2)}(t1.a,t2.a)->Projection",
},
// issue #7728
{
sql: "select * from t t1 join t t2 on t1.a = t2.a where t2.a = null",
best: "Dual->Projection",
},
}
for _, ca := range tests {
comment := Commentf("for %s", ca.sql)
Expand Down
37 changes: 36 additions & 1 deletion plan/rule_predicate_push_down.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ func addSelection(p LogicalPlan, child LogicalPlan, conditions []expression.Expr
return
}
conditions = expression.PropagateConstant(p.context(), conditions)
// Return table dual when filter is constant false or null.
dual := conds2TableDual(child, conditions)
if dual != nil {
p.Children()[chIdx] = dual
return
}
selection := LogicalSelection{Conditions: conditions}.init(p.context())
selection.SetChildren(child)
p.Children()[chIdx] = selection
Expand All @@ -55,6 +61,11 @@ func (p *LogicalSelection) PredicatePushDown(predicates []expression.Expression)
retConditions, child := p.children[0].PredicatePushDown(append(p.Conditions, predicates...))
if len(retConditions) > 0 {
p.Conditions = expression.PropagateConstant(p.ctx, retConditions)
// Return table dual when filter is constant false or null.
dual := conds2TableDual(p, p.Conditions)
if dual != nil {
return nil, dual
}
return nil, p
}
return nil, child
Expand Down Expand Up @@ -129,7 +140,13 @@ func (p *LogicalJoin) PredicatePushDown(predicates []expression.Expression) (ret
tempCond = append(tempCond, p.OtherConditions...)
tempCond = append(tempCond, predicates...)
tempCond = expression.ExtractFiltersFromDNFs(p.ctx, tempCond)
equalCond, leftPushCond, rightPushCond, otherCond = extractOnCondition(expression.PropagateConstant(p.ctx, tempCond), leftPlan, rightPlan, true, true)
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
}
equalCond, leftPushCond, rightPushCond, otherCond = extractOnCondition(tempCond, leftPlan, rightPlan, true, true)
p.LeftConditions = nil
p.RightConditions = nil
p.EqualConditions = equalCond
Expand Down Expand Up @@ -378,3 +395,21 @@ func deriveOtherConditions(p *LogicalJoin, deriveLeft bool, deriveRight bool) (l
}
return
}

// conds2TableDual builds a LogicalTableDual if cond is constant false or null.
func conds2TableDual(p LogicalPlan, conds []expression.Expression) LogicalPlan {
if len(conds) != 1 {
return nil
}
con, ok := conds[0].(*expression.Constant)
if !ok {
return nil
}
sc := p.context().GetSessionVars().StmtCtx
if isTrue, err := con.Value.ToBool(sc); (err == nil && isTrue == 0) || con.Value.IsNull() {
dual := LogicalTableDual{}.init(p.context())
dual.SetSchema(p.Schema())
return dual
}
return nil
}

0 comments on commit 0001d2a

Please sign in to comment.