@@ -286,9 +286,8 @@ func mockContext() sessionctx.Context {
286286func (s * testPlanSuite ) TestPredicatePushDown (c * C ) {
287287 defer testleak .AfterTest (c )()
288288 tests := []struct {
289- sql string
290- first string
291- best string
289+ sql string
290+ best string
292291 }{
293292 {
294293 sql : "select count(*) from t a, t b where a.a = b.a" ,
@@ -567,11 +566,6 @@ func (s *testPlanSuite) TestOuterWherePredicatePushDown(c *C) {
567566 },
568567 }
569568 for _ , ca := range tests {
570- comment := Commentf ("for %s" , ca .sql )
571- stmt , err := s .ParseOneStmt (ca .sql , "" , "" )
572- c .Assert (err , IsNil , comment )
573- p , err := BuildLogicalPlan (s .ctx , stmt , s .is )
574- c .Assert (err , IsNil , comment )
575569 p , err = logicalOptimize (flagPredicatePushDown | flagDecorrelate | flagPrunColumns , p .(LogicalPlan ))
576570 c .Assert (err , IsNil , comment )
577571 proj , ok := p .(* LogicalProjection )
@@ -593,6 +587,58 @@ func (s *testPlanSuite) TestOuterWherePredicatePushDown(c *C) {
593587 }
594588}
595589
590+ func (s * testPlanSuite ) TestSimplifyOuterJoin (c * C ) {
591+ defer testleak .AfterTest (c )()
592+ tests := []struct {
593+ sql string
594+ best string
595+ joinType string
596+ }{
597+ {
598+ sql : "select * from t t1 left join t t2 on t1.b = t2.b where t1.c > 1 or t2.c > 1;" ,
599+ best : "Join{DataScan(t1)->DataScan(t2)}(t1.b,t2.b)->Sel([or(gt(t1.c, 1), gt(t2.c, 1))])->Projection" ,
600+ joinType : "left outer join" ,
601+ },
602+ {
603+ sql : "select * from t t1 left join t t2 on t1.b = t2.b where t1.c > 1 and t2.c > 1;" ,
604+ best : "Join{DataScan(t1)->DataScan(t2)}(t1.b,t2.b)->Projection" ,
605+ joinType : "inner join" ,
606+ },
607+ {
608+ sql : "select * from t t1 left join t t2 on t1.b = t2.b where not (t1.c > 1 or t2.c > 1);" ,
609+ best : "Join{DataScan(t1)->DataScan(t2)}(t1.b,t2.b)->Projection" ,
610+ joinType : "inner join" ,
611+ },
612+ {
613+ sql : "select * from t t1 left join t t2 on t1.b = t2.b where not (t1.c > 1 and t2.c > 1);" ,
614+ best : "Join{DataScan(t1)->DataScan(t2)}(t1.b,t2.b)->Sel([not(and(le(t1.c, 1), le(t2.c, 1)))])->Projection" ,
615+ joinType : "left outer join" ,
616+ },
617+ {
618+ sql : "select * from t t1 left join t t2 on t1.b > 1 where t1.c = t2.c;" ,
619+ best : "Join{DataScan(t1)->DataScan(t2)}(t1.c,t2.c)->Projection" ,
620+ joinType : "inner join" ,
621+ },
622+ }
623+ for _ , ca := range tests {
624+ comment := Commentf ("for %s" , ca .sql )
625+ stmt , err := s .ParseOneStmt (ca .sql , "" , "" )
626+ c .Assert (err , IsNil , comment )
627+ p , err := BuildLogicalPlan (s .ctx , stmt , s .is )
628+ c .Assert (err , IsNil , comment )
629+ p , err = logicalOptimize (flagPredicatePushDown | flagPrunColumns , p .(LogicalPlan ))
630+ c .Assert (err , IsNil , comment )
631+ c .Assert (ToString (p ), Equals , ca .best , comment )
632+ join , ok := p .(LogicalPlan ).Children ()[0 ].(* LogicalJoin )
633+ if ! ok {
634+ join , ok = p .(LogicalPlan ).Children ()[0 ].Children ()[0 ].(* LogicalJoin )
635+ c .Assert (ok , IsTrue , comment )
636+ }
637+ joinType := fmt .Sprintf ("%s" , join .JoinType .String ())
638+ c .Assert (joinType , Equals , ca .joinType , comment )
639+ }
640+ }
641+
596642func newPartitionInfoSchema (definitions []model.PartitionDefinition ) infoschema.InfoSchema {
597643 tableInfo := * MockTable ()
598644 cols := make ([]* model.ColumnInfo , 0 , len (tableInfo .Columns ))
0 commit comments