plan: not build dual for AntiSemiJoin when condition is constant false (#8648)
This commit is contained in:
@ -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))
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user