Skip to content

Commit

Permalink
plan: push property across semijoin. (pingcap#4083)
Browse files Browse the repository at this point in the history
  • Loading branch information
hanfei1991 authored Aug 8, 2017
1 parent 3c11ac5 commit 3e1efa6
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
10 changes: 10 additions & 0 deletions executor/join_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,16 @@ func (s *testSuite) TestInSubquery(c *C) {
result.Check(testkit.Rows())
result = tk.MustQuery("select * from t1 where a not in (select * from t2 where false)")
result.Check(testkit.Rows("1", "2"))

tk.MustExec("drop table if exists t1, t2")
tk.MustExec("create table t1 (a int, key b (a))")
tk.MustExec("create table t2 (a int, key b (a))")
tk.MustExec("insert into t1 values (1),(2),(2)")
tk.MustExec("insert into t2 values (1),(2),(2)")
result = tk.MustQuery("select * from t1 where a in (select * from t2) order by a desc")
result.Check(testkit.Rows("2", "2", "1"))
result = tk.MustQuery("select * from t1 where a in (select count(*) from t2 where t1.a = t2.a) order by a desc")
result.Check(testkit.Rows("2", "2", "1"))
}

func (s *testSuite) TestJoinLeak(c *C) {
Expand Down
12 changes: 11 additions & 1 deletion plan/dag_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@ func (s *testPlanSuite) TestDAGPlanBuilderJoin(c *C) {
sql: "select /*+ TIDB_SMJ(t1,t2)*/ * from t t1, t t2 where t1.a = t2.a order by t2.a",
best: "MergeJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.a)",
},
// Test Single Merge Join + Sort + desc.
{
sql: "select /*+ TIDB_SMJ(t1,t2)*/ * from t t1, t t2 where t1.a = t2.a order by t2.a desc",
best: "MergeJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.a)->Sort",
},
// Test Multi Merge Join.
{
sql: "select /*+ TIDB_SMJ(t1,t2,t3)*/ * from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a",
Expand Down Expand Up @@ -367,11 +372,16 @@ func (s *testPlanSuite) TestDAGPlanBuilderSubquery(c *C) {
sql: "select * from t where a in (select s.a from t s) order by t.a",
best: "SemiJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,s.a)",
},
// Test Nested sub query.
{
// Test Nested sub query.
sql: "select * from t where exists (select s.a from t s where s.c in (select c from t as k where k.d = s.d) having sum(s.a) = t.a )",
best: "SemiJoin{TableReader(Table(t))->Projection->SemiJoin{TableReader(Table(t))->TableReader(Table(t))}(s.d,k.d)(s.c,k.c)->HashAgg}(cast(test.t.a),sel_agg_1)->Projection",
},
// Test Semi Join + Order by.
{
sql: "select * from t where a in (select a from t) order by b",
best: "SemiJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->Sort",
},
// Test Apply.
{
sql: "select t.c in (select count(*) from t s , t t1 where s.a = t.a and s.a = t1.a) from t",
Expand Down
9 changes: 6 additions & 3 deletions plan/new_physical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ func (p *PhysicalMergeJoin) getChildrenPossibleProps(prop *requiredProp) [][]*re
lProp := &requiredProp{taskTp: rootTaskType, cols: p.leftKeys, expectedCnt: math.MaxFloat64}
rProp := &requiredProp{taskTp: rootTaskType, cols: p.rightKeys, expectedCnt: math.MaxFloat64}
if !prop.isEmpty() {
if prop.desc {
return nil
}
if !prop.equal(lProp) && !prop.equal(rProp) {
return nil
}
Expand Down Expand Up @@ -973,19 +976,19 @@ func (p *PhysicalHashJoin) getChildrenPossibleProps(prop *requiredProp) [][]*req

func (p *PhysicalHashSemiJoin) getChildrenPossibleProps(prop *requiredProp) [][]*requiredProp {
p.expectedCnt = prop.expectedCnt
lProp := &requiredProp{taskTp: rootTaskType, cols: prop.cols, expectedCnt: prop.expectedCnt}
lProp := &requiredProp{taskTp: rootTaskType, cols: prop.cols, expectedCnt: prop.expectedCnt, desc: prop.desc}
for _, col := range lProp.cols {
idx := p.Schema().ColumnIndex(col)
if idx == -1 || idx >= p.rightChOffset {
return nil
}
}
return [][]*requiredProp{{&requiredProp{taskTp: rootTaskType, expectedCnt: math.MaxFloat64}, &requiredProp{taskTp: rootTaskType, expectedCnt: math.MaxFloat64}}}
return [][]*requiredProp{{lProp, &requiredProp{taskTp: rootTaskType, expectedCnt: math.MaxFloat64}}}
}

func (p *PhysicalApply) getChildrenPossibleProps(prop *requiredProp) [][]*requiredProp {
p.expectedCnt = prop.expectedCnt
lProp := &requiredProp{taskTp: rootTaskType, cols: prop.cols, expectedCnt: prop.expectedCnt}
lProp := &requiredProp{taskTp: rootTaskType, cols: prop.cols, expectedCnt: prop.expectedCnt, desc: prop.desc}
for _, col := range lProp.cols {
idx := p.Schema().ColumnIndex(col)
if idx == -1 || idx >= p.rightChOffset {
Expand Down

0 comments on commit 3e1efa6

Please sign in to comment.