Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

planner/core: make TIDB_INLJ to specify the inner table #8243

Merged
merged 9 commits into from
Nov 13, 2018
2 changes: 1 addition & 1 deletion executor/index_lookup_join_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (s *testSuite) TestIndexLookupJoinHang(c *C) {
tk.Se.GetSessionVars().IndexJoinBatchSize = 1
tk.Se.GetSessionVars().IndexLookupJoinConcurrency = 1

rs, err := tk.Exec("select /*+ TIDB_INLJ(o, i)*/ * from idxJoinOuter o left join idxJoinInner i on o.a = i.a where o.a in (1, 2) and (i.a - 3) > 0")
rs, err := tk.Exec("select /*+ TIDB_INLJ(i)*/ * from idxJoinOuter o left join idxJoinInner i on o.a = i.a where o.a in (1, 2) and (i.a - 3) > 0")
c.Assert(err, IsNil)
chk := rs.NewChunk()
for i := 0; i < 5; i++ {
Expand Down
22 changes: 11 additions & 11 deletions executor/join_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@ func (s *testSuite) TestJoin(c *C) {

// The physical plans of the two sql are tested at physical_plan_test.go
tk.MustQuery("select /*+ TIDB_INLJ(t, t1) */ * from t join t1 on t.a=t1.a").Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4"))
tk.MustQuery("select /*+ TIDB_INLJ(t1) */ * from t1 join t on t.a=t1.a and t.a < t1.b").Check(testkit.Rows("1 2 1 1", "1 3 1 1", "1 4 1 1", "3 4 3 3"))
tk.MustQuery("select /*+ TIDB_INLJ(t) */ * from t1 join t on t.a=t1.a and t.a < t1.b").Check(testkit.Rows("1 2 1 1", "1 3 1 1", "1 4 1 1", "3 4 3 3"))
// Test single index reader.
tk.MustQuery("select /*+ TIDB_INLJ(t, t1) */ t1.b from t1 join t on t.b=t1.b").Check(testkit.Rows("2", "3"))
tk.MustQuery("select /*+ TIDB_INLJ(t, t1) */ * from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", "<nil> <nil> 4 5"))
tk.MustQuery("select /*+ TIDB_INLJ(t, t1) */ avg(t.b) from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1.5000"))
tk.MustQuery("select /*+ TIDB_INLJ(t1) */ * from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", "<nil> <nil> 4 5"))
tk.MustQuery("select /*+ TIDB_INLJ(t) */ avg(t.b) from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1.5000"))

// Test that two conflict hints will return error.
_, err = tk.Exec("select /*+ TIDB_INLJ(t) TIDB_SMJ(t) */ * from t join t1 on t.a=t1.a")
Expand All @@ -169,8 +169,8 @@ func (s *testSuite) TestJoin(c *C) {
tk.MustExec("create table t1(a int, b int)")
tk.MustExec("insert into t values(1, 3), (2, 2), (3, 1)")
tk.MustExec("insert into t1 values(0, 0), (1, 2), (1, 3), (3, 4)")
tk.MustQuery("select /*+ TIDB_INLJ(t) */ * from t join t1 on t.a=t1.a order by t.b").Check(testkit.Rows("3 1 3 4", "1 3 1 2", "1 3 1 3"))
tk.MustQuery("select /*+ TIDB_INLJ(t1) */ t.a, t.b from t join t1 on t.a=t1.a where t1.b = 4 limit 1").Check(testkit.Rows("3 1"))
tk.MustQuery("select /*+ TIDB_INLJ(t1) */ * from t join t1 on t.a=t1.a order by t.b").Check(testkit.Rows("3 1 3 4", "1 3 1 2", "1 3 1 3"))
tk.MustQuery("select /*+ TIDB_INLJ(t) */ t.a, t.b from t join t1 on t.a=t1.a where t1.b = 4 limit 1").Check(testkit.Rows("3 1"))
tk.MustQuery("select /*+ TIDB_INLJ(t, t1) */ * from t right join t1 on t.a=t1.a order by t.b").Check(testkit.Rows("<nil> <nil> 0 0", "3 1 3 4", "1 3 1 2", "1 3 1 3"))

// join reorder will disorganize the resulting schema
Expand All @@ -187,7 +187,7 @@ func (s *testSuite) TestJoin(c *C) {
tk.MustExec("create table t1(a int)")
tk.MustExec("insert into t values(1,2), (5,3), (6,4)")
tk.MustExec("insert into t1 values(1), (2), (3)")
tk.MustQuery("select /*+ TIDB_INLJ(t1) */ t1.a from t1, t where t.a = 5 and t.b = t1.a").Check(testkit.Rows("3"))
tk.MustQuery("select /*+ TIDB_INLJ(t) */ t1.a from t1, t where t.a = 5 and t.b = t1.a").Check(testkit.Rows("3"))

// test issue#4997
tk.MustExec("drop table if exists t1, t2")
Expand Down Expand Up @@ -326,7 +326,7 @@ func (s *testSuite) TestJoinCast(c *C) {
tk.MustExec("create index k1 on t1(c1)")
tk.MustExec("insert into t values(0), (2)")
tk.MustExec("insert into t1 values(0), (9)")
result = tk.MustQuery("select /*+ TIDB_INLJ(t) */ * from t left join t1 on t1.c1 = t.c1")
result = tk.MustQuery("select /*+ TIDB_INLJ(t1) */ * from t left join t1 on t1.c1 = t.c1")
result.Sort().Check(testkit.Rows("0.0 0.00", "2.0 <nil>"))

tk.MustExec("drop table if exists t")
Expand Down Expand Up @@ -672,7 +672,7 @@ func (s *testSuite) TestSubquery(c *C) {
tk.MustExec("CREATE TABLE t1(a int, b int default 0)")
tk.MustExec("create index k1 on t1(a)")
tk.MustExec("INSERT INTO t1 (a) values(1), (2), (3), (4), (5)")
result = tk.MustQuery("select (select /*+ TIDB_INLJ(x1) */ x2.a from t1 x1, t1 x2 where x1.a = t1.a and x1.a = x2.a) from t1")
result = tk.MustQuery("select (select /*+ TIDB_INLJ(x2) */ x2.a from t1 x1, t1 x2 where x1.a = t1.a and x1.a = x2.a) from t1")
result.Check(testkit.Rows("1", "2", "3", "4", "5"))

tk.MustExec("drop table if exists t1, t2")
Expand Down Expand Up @@ -809,7 +809,7 @@ func (s *testSuite) TestIssue5255(c *C) {
tk.MustExec("create table t2(a int primary key)")
tk.MustExec("insert into t1 values(1, '2017-11-29', 2.2)")
tk.MustExec("insert into t2 values(1)")
tk.MustQuery("select /*+ TIDB_INLJ(t2) */ * from t1 join t2 on t1.a=t2.a").Check(testkit.Rows("1 2017-11-29 2.2 1"))
tk.MustQuery("select /*+ TIDB_INLJ(t1) */ * from t1 join t2 on t1.a=t2.a").Check(testkit.Rows("1 2017-11-29 2.2 1"))
}

func (s *testSuite) TestIssue5278(c *C) {
Expand Down Expand Up @@ -847,7 +847,7 @@ func (s *testSuite) TestIndexLookupJoin(c *C) {
tk.MustExec(`drop table if exists t;`)
tk.MustExec(`create table t(a decimal(6,2), index idx(a));`)
tk.MustExec(`insert into t values(1.01), (2.02), (NULL);`)
tk.MustQuery(`select /*+ TIDB_INLJ(t1) */ t1.a from t t1 join t t2 on t1.a=t2.a order by t1.a;`).Check(testkit.Rows(
tk.MustQuery(`select /*+ TIDB_INLJ(t2) */ t1.a from t t1 join t t2 on t1.a=t2.a order by t1.a;`).Check(testkit.Rows(
`1.01`,
`2.02`,
))
Expand All @@ -856,7 +856,7 @@ func (s *testSuite) TestIndexLookupJoin(c *C) {
tk.MustExec(`create table t(a bigint, b bigint, unique key idx1(a, b));`)
tk.MustExec(`insert into t values(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6);`)
tk.MustExec(`set @@tidb_max_chunk_size = 2;`)
tk.MustQuery(`select /*+ TIDB_INLJ(t1) */ * from t t1 left join t t2 on t1.a = t2.a and t1.b = t2.b + 4;`).Check(testkit.Rows(
tk.MustQuery(`select /*+ TIDB_INLJ(t2) */ * from t t1 left join t t2 on t1.a = t2.a and t1.b = t2.b + 4;`).Check(testkit.Rows(
`1 1 <nil> <nil>`,
`1 2 <nil> <nil>`,
`1 3 <nil> <nil>`,
Expand Down
4 changes: 2 additions & 2 deletions planner/core/exhaust_physical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,8 @@ func (p *LogicalJoin) tryToGetIndexJoin(prop *property.PhysicalProperty) ([]Phys
return nil, false
}
plans := make([]PhysicalPlan, 0, 2)
leftOuter := (p.preferJoinType & preferLeftAsIndexOuter) > 0
rightOuter := (p.preferJoinType & preferRightAsIndexOuter) > 0
rightOuter := (p.preferJoinType & preferLeftAsIndexInner) > 0
leftOuter := (p.preferJoinType & preferRightAsIndexInner) > 0
switch p.JoinType {
case SemiJoin, AntiSemiJoin, LeftOuterSemiJoin, AntiLeftOuterSemiJoin, LeftOuterJoin:
join := p.getIndexJoinByOuterIdx(prop, 0)
Expand Down
11 changes: 5 additions & 6 deletions planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,15 +258,15 @@ func (p *LogicalJoin) setPreferredJoinType(hintInfo *tableHintInfo) error {
p.preferJoinType |= preferHashJoin
}
if hintInfo.ifPreferINLJ(lhsAlias) {
p.preferJoinType |= preferLeftAsIndexOuter
p.preferJoinType |= preferLeftAsIndexInner
}
if hintInfo.ifPreferINLJ(rhsAlias) {
p.preferJoinType |= preferRightAsIndexOuter
p.preferJoinType |= preferRightAsIndexInner
}

// If there're multiple join types and one of them is not index join hint,
// then there is a conflict of join types.
if bits.OnesCount(p.preferJoinType) > 1 && (p.preferJoinType^preferRightAsIndexOuter^preferLeftAsIndexOuter) > 0 {
if bits.OnesCount(p.preferJoinType) > 1 && (p.preferJoinType^preferRightAsIndexInner^preferLeftAsIndexInner) > 0 {
return errors.New("Join hints are conflict, you can only specify one type of join")
}
return nil
Expand Down Expand Up @@ -2031,9 +2031,8 @@ func (b *PlanBuilder) buildSemiJoin(outerPlan, innerPlan LogicalPlan, onConditio
if b.TableHints().ifPreferHashJoin(outerAlias, innerAlias) {
joinPlan.preferJoinType |= preferHashJoin
}
// semi join's outer is always the left side.
if b.TableHints().ifPreferINLJ(outerAlias) {
joinPlan.preferJoinType = preferLeftAsIndexOuter
if b.TableHints().ifPreferINLJ(innerAlias) {
joinPlan.preferJoinType = preferLeftAsIndexInner
}
// If there're multiple join hints, they're conflict.
if bits.OnesCount(joinPlan.preferJoinType) > 1 {
Expand Down
4 changes: 2 additions & 2 deletions planner/core/logical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ func (tp JoinType) String() string {
}

const (
preferLeftAsIndexOuter = 1 << iota
preferRightAsIndexOuter
preferLeftAsIndexInner = 1 << iota
preferRightAsIndexInner
preferHashJoin
preferMergeJoin
)
Expand Down
16 changes: 8 additions & 8 deletions planner/core/physical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ func (s *testPlanSuite) TestDAGPlanBuilderJoin(c *C) {
},
// Test Index Join + TableScan + Rotate.
{
sql: "select /*+ TIDB_INLJ(t2) */ t1.a , t2.a from t t1, t t2 where t1.a = t2.c",
sql: "select /*+ TIDB_INLJ(t1) */ t1.a , t2.a from t t1, t t2 where t1.a = t2.c",
best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t2.c,t1.a)->Projection",
},
// Test Index Join + OuterJoin + TableScan.
Expand All @@ -383,33 +383,33 @@ func (s *testPlanSuite) TestDAGPlanBuilderJoin(c *C) {
},
// Test Index Join failed.
{
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 right outer join t t2 on t1.a = t2.b",
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 right outer join t t2 on t1.a = t2.b",
best: "RightHashJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.b)",
},
// Test Semi Join hint success.
{
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 where t1.a in (select a from t t2)",
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 where t1.a in (select a from t t2)",
best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.a)->Projection",
},
// Test Semi Join hint fail.
{
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 where t1.a in (select a from t t2)",
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 where t1.a in (select a from t t2)",
best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t2.a,t1.a)->Projection",
},
{
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 join t t2 where t1.c=t2.c and t1.f=t2.f",
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.c=t2.c and t1.f=t2.f",
best: "IndexJoin{TableReader(Table(t))->IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))}(t1.c,t2.c)",
},
{
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 join t t2 where t1.a = t2.a and t1.f=t2.f",
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.a = t2.a and t1.f=t2.f",
best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.a)",
},
{
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 join t t2 where t1.f=t2.f and t1.a=t2.a",
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.f=t2.f and t1.a=t2.a",
best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(t1.a,t2.a)",
},
{
sql: "select /*+ TIDB_INLJ(t1) */ * from t t1 join t t2 where t1.a=t2.a and t2.a in (1, 2)",
sql: "select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 where t1.a=t2.a and t2.a in (1, 2)",
best: "IndexJoin{TableReader(Table(t))->TableReader(Table(t)->Sel([in(t2.a, 1, 2)]))}(t1.a,t2.a)",
},
}
Expand Down