Skip to content

Commit

Permalink
Planner: Avoid injecting redundant projection below LogicalJoin (ping…
Browse files Browse the repository at this point in the history
  • Loading branch information
foreyes authored and sre-bot committed Aug 19, 2019
1 parent fb166e8 commit 69c0c3b
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 22 deletions.
18 changes: 9 additions & 9 deletions cmd/explaintest/r/explain_easy.result
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ set @@session.tidb_hashagg_partial_concurrency = 1;
set @@session.tidb_hashagg_final_concurrency = 1;
explain select * from t3 where exists (select s.a from t3 s having sum(s.a) = t3.a );
id count task operator info
Projection_12 8000.00 root test.t3.a, test.t3.b, test.t3.c, test.t3.d
└─HashLeftJoin_13 8000.00 root semi join, inner:StreamAgg_29, equal:[eq(cast(test.t3.a), sel_agg_1)]
├─Projection_14 10000.00 root test.t3.a, test.t3.b, test.t3.c, test.t3.d, cast(test.t3.a)
│ └─TableReader_16 10000.00 root data:TableScan_15
│ └─TableScan_15 10000.00 cop table:t3, range:[-inf,+inf], keep order:false, stats:pseudo
└─StreamAgg_29 1.00 root funcs:sum(col_0)
└─TableReader_30 1.00 root data:StreamAgg_21
└─StreamAgg_21 1.00 cop funcs:sum(test.s.a)
└─TableScan_28 10000.00 cop table:s, range:[-inf,+inf], keep order:false, stats:pseudo
Projection_11 8000.00 root test.t3.a, test.t3.b, test.t3.c, test.t3.d
└─HashLeftJoin_12 8000.00 root semi join, inner:StreamAgg_27, equal:[eq(cast(test.t3.a), sel_agg_1)]
├─Projection_13 10000.00 root test.t3.a, test.t3.b, test.t3.c, test.t3.d, cast(test.t3.a)
│ └─TableReader_15 10000.00 root data:TableScan_14
│ └─TableScan_14 10000.00 cop table:t3, range:[-inf,+inf], keep order:false, stats:pseudo
└─StreamAgg_27 1.00 root funcs:sum(col_0)
└─TableReader_28 1.00 root data:StreamAgg_19
└─StreamAgg_19 1.00 cop funcs:sum(test.s.a)
└─TableScan_26 10000.00 cop table:s, range:[-inf,+inf], keep order:false, stats:pseudo
explain select * from t1;
id count task operator info
TableReader_5 10000.00 root data:TableScan_4
Expand Down
18 changes: 9 additions & 9 deletions cmd/explaintest/r/explain_easy_stats.result
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ set @@session.tidb_hashagg_partial_concurrency = 1;
set @@session.tidb_hashagg_final_concurrency = 1;
explain select * from t3 where exists (select s.a from t3 s having sum(s.a) = t3.a );
id count task operator info
Projection_12 1600.00 root test.t3.a, test.t3.b, test.t3.c, test.t3.d
└─HashLeftJoin_13 1600.00 root semi join, inner:StreamAgg_29, equal:[eq(cast(test.t3.a), sel_agg_1)]
├─Projection_14 2000.00 root test.t3.a, test.t3.b, test.t3.c, test.t3.d, cast(test.t3.a)
│ └─TableReader_16 2000.00 root data:TableScan_15
│ └─TableScan_15 2000.00 cop table:t3, range:[-inf,+inf], keep order:false
└─StreamAgg_29 1.00 root funcs:sum(col_0)
└─TableReader_30 1.00 root data:StreamAgg_21
└─StreamAgg_21 1.00 cop funcs:sum(test.s.a)
└─TableScan_28 2000.00 cop table:s, range:[-inf,+inf], keep order:false
Projection_11 1600.00 root test.t3.a, test.t3.b, test.t3.c, test.t3.d
└─HashLeftJoin_12 1600.00 root semi join, inner:StreamAgg_27, equal:[eq(cast(test.t3.a), sel_agg_1)]
├─Projection_13 2000.00 root test.t3.a, test.t3.b, test.t3.c, test.t3.d, cast(test.t3.a)
│ └─TableReader_15 2000.00 root data:TableScan_14
│ └─TableScan_14 2000.00 cop table:t3, range:[-inf,+inf], keep order:false
└─StreamAgg_27 1.00 root funcs:sum(col_0)
└─TableReader_28 1.00 root data:StreamAgg_19
└─StreamAgg_19 1.00 cop funcs:sum(test.s.a)
└─TableScan_26 2000.00 cop table:s, range:[-inf,+inf], keep order:false
explain select * from t1;
id count task operator info
TableReader_5 1999.00 root data:TableScan_4
Expand Down
26 changes: 26 additions & 0 deletions planner/core/logical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2642,3 +2642,29 @@ func (s *testPlanSuite) TestFastPlanContextTables(c *C) {
}
}
}

func (s *testPlanSuite) TestUpdateEQCond(c *C) {
defer testleak.AfterTest(c)()
tests := []struct {
sql string
best string
}{
{
sql: "select t1.a from t t1, t t2 where t1.a = t2.a+1",
best: "Join{DataScan(t1)->DataScan(t2)->Projection}(test.t1.a,plus(test.t2.a, 1))->Projection",
},
}
ctx := context.TODO()
for i, tt := range tests {
comment := Commentf("case:%v sql:%s", i, tt.sql)
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)
Preprocess(s.ctx, stmt, s.is)
builder := NewPlanBuilder(MockContext(), s.is)
p, err := builder.Build(ctx, stmt)
c.Assert(err, IsNil)
p, err = logicalOptimize(ctx, builder.optFlag, p.(LogicalPlan))
c.Assert(err, IsNil)
c.Assert(ToString(p), Equals, tt.best, comment)
}
}
26 changes: 22 additions & 4 deletions planner/core/rule_predicate_push_down.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,29 @@ func (p *LogicalJoin) updateEQCond() {
}
}
if len(lKeys) > 0 {
lProj := p.getProj(0)
rProj := p.getProj(1)
needLProj, needRProj := false, false
for i := range lKeys {
lKey := lProj.appendExpr(lKeys[i])
rKey := rProj.appendExpr(rKeys[i])
_, lOk := lKeys[i].(*expression.Column)
_, rOk := rKeys[i].(*expression.Column)
needLProj = needLProj || !lOk
needRProj = needRProj || !rOk
}

var lProj, rProj *LogicalProjection
if needLProj {
lProj = p.getProj(0)
}
if needRProj {
rProj = p.getProj(1)
}
for i := range lKeys {
lKey, rKey := lKeys[i], rKeys[i]
if lProj != nil {
lKey = lProj.appendExpr(lKey)
}
if rProj != nil {
rKey = rProj.appendExpr(rKey)
}
eqCond := expression.NewFunctionInternal(p.ctx, ast.EQ, types.NewFieldType(mysql.TypeTiny), lKey, rKey)
p.EqualConditions = append(p.EqualConditions, eqCond.(*expression.ScalarFunction))
}
Expand Down

0 comments on commit 69c0c3b

Please sign in to comment.