diff --git a/planner/core/physical_plan_test.go b/planner/core/physical_plan_test.go index f0d5a44e437d7..6de6f5b51bbf5 100644 --- a/planner/core/physical_plan_test.go +++ b/planner/core/physical_plan_test.go @@ -661,3 +661,51 @@ func (s *testPlanSuite) TestIndexJoinHint(c *C) { } } } + +func (s *testPlanSuite) TestHintFromDiffDatabase(c *C) { + defer testleak.AfterTest(c)() + store, dom, err := newStoreWithBootstrap() + c.Assert(err, IsNil) + defer func() { + dom.Close() + store.Close() + }() + se, err := session.CreateSession4Test(store) + c.Assert(err, IsNil) + ctx := context.Background() + _, err = se.Execute(ctx, "use test") + c.Assert(err, IsNil) + _, err = se.Execute(ctx, `drop table if exists test.t1`) + c.Assert(err, IsNil) + _, err = se.Execute(ctx, `create table test.t1(a bigint, index idx_a(a));`) + c.Assert(err, IsNil) + _, err = se.Execute(ctx, `create table test.t2(a bigint, index idx_a(a));`) + c.Assert(err, IsNil) + + _, err = se.Execute(ctx, "drop database if exists test2") + c.Assert(err, IsNil) + _, err = se.Execute(ctx, "create database test2") + c.Assert(err, IsNil) + _, err = se.Execute(ctx, "use test2") + c.Assert(err, IsNil) + + var input []string + var output []struct { + SQL string + Plan string + } + is := domain.GetDomain(se).InfoSchema() + s.testData.GetTestCases(c, &input, &output) + for i, tt := range input { + comment := Commentf("case:%v sql: %s", i, tt) + stmt, err := s.ParseOneStmt(tt, "", "") + c.Assert(err, IsNil, comment) + p, _, err := planner.Optimize(ctx, se, stmt, is) + c.Assert(err, IsNil, comment) + s.testData.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = core.ToString(p) + }) + c.Assert(core.ToString(p), Equals, output[i].Plan, comment) + } +} diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index b49ae3b3eed87..32274f561bbdd 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -67,9 +67,20 @@ func tableNames2HintTableInfo(tableNames []model.CIStr) []hintTableInfo { if len(tableNames) == 0 { return nil } +<<<<<<< HEAD hintTables := make([]hintTableInfo, 0, len(tableNames)) for _, tableName := range tableNames { hintTables = append(hintTables, hintTableInfo{name: tableName}) +======= + hintTableInfos := make([]hintTableInfo, len(hintTables)) + defaultDBName := model.NewCIStr(ctx.GetSessionVars().CurrentDB) + for i, hintTable := range hintTables { + tableInfo := hintTableInfo{dbName: hintTable.DBName, tblName: hintTable.TableName, selectOffset: p.getHintOffset(hintTable.QBName, nodeType, currentOffset)} + if tableInfo.dbName.L == "" { + tableInfo.dbName = defaultDBName + } + hintTableInfos[i] = tableInfo +>>>>>>> 5268094... planner: correct the dbName for hint (#15319) } return hintTables } diff --git a/planner/core/testdata/plan_suite_in.json b/planner/core/testdata/plan_suite_in.json index a6aaf2907db64..d4a7c54332150 100644 --- a/planner/core/testdata/plan_suite_in.json +++ b/planner/core/testdata/plan_suite_in.json @@ -429,5 +429,73 @@ "cases": [ "select t1.a, (select count(t2.a) from t t2 where t2.g in (select t3.d from t t3 where t3.c = t1.a)) as agg_col from t t1;" ] +<<<<<<< HEAD +======= + }, + { + "name": "TestIndexJoinHint", + "cases": [ + "select /*+ INL_JOIN(t1) */ * from t1 join t2 on t1.a = t2.a;", + "select /*+ INL_HASH_JOIN(t1) */ * from t1 join t2 on t1.a = t2.a;", + "select /*+ INL_MERGE_JOIN(t1) */ * from t1 join t2 on t1.a = t2.a;" + ] + }, + { + "name": "TestAggToCopHint", + "cases": [ + "select /*+ AGG_TO_COP(), HASH_AGG(), USE_INDEX(t) */ sum(a) from ta group by a", + "select /*+ AGG_TO_COP(), USE_INDEX(t) */ sum(b) from ta group by b", + "select /*+ AGG_TO_COP(), HASH_AGG(), USE_INDEX(t) */ distinct a from ta group by a", + "select /*+ AGG_TO_COP(), HASH_AGG(), HASH_JOIN(t1), USE_INDEX(t1), USE_INDEX(t2) */ sum(t1.a) from ta t1, ta t2 where t1.a = t2.b group by t1.a" + ] + }, + { + "name": "TestDAGPlanBuilderWindow", + "cases":[ + "select lead(a, 1) over (partition by null) as c from t" + ] + }, + { + "name": "TestDAGPlanBuilderWindowParallel", + "cases":[ + "select lead(a, 1) over (partition by null) as c from t", + "select lead(a, 1) over (partition by b) as c from t" + ] + }, + { + "name": "TestNominalSort", + "cases": [ + "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by t1.a", + "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by t1.a+1", + "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by t1.a-1", + "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by -t1.a", + "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by -t1.a+3", + "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by 1+t1.a", + "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by 1-t1.a", + "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by 1-t1.a+3", + "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by 1+t1.a+3", + "select /*+ TIDB_SMJ(t1, t2) */ t1.a from t t1, t t2 where t1.a = t2.b order by 3*t1.a" + ] + }, + { + "name": "TestInlineProjection", + "cases":[ + "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1, t2 where t1.a = t2.a;", + "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;", + "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1 left outer join t2 on t1.a = t2.a;", + "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1 right outer join t2 on t1.a = t2.a;", + "select 1 from (select /*+ HASH_JOIN(t1) */ t1.a in (select t2.a from t2) from t1) x;", + "select 1 from (select /*+ HASH_JOIN(t1) */ t1.a not in (select t2.a from t2) from t1) x;", + "select /*+ INL_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;", + "select /*+ INL_HASH_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;", + "select /*+ INL_MERGE_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;" + ] + }, + { + "name": "TestHintFromDiffDatabase", + "cases": [ + "select /*+ inl_hash_join(test.t1) */ * from test.t2 join test.t1 on test.t2.a = test.t1.a" + ] +>>>>>>> 5268094... planner: correct the dbName for hint (#15319) } ] diff --git a/planner/core/testdata/plan_suite_out.json b/planner/core/testdata/plan_suite_out.json index 7cd0e753e5d64..5a5f2942cf770 100644 --- a/planner/core/testdata/plan_suite_out.json +++ b/planner/core/testdata/plan_suite_out.json @@ -1013,5 +1013,14 @@ "Best": "Apply{TableReader(Table(t))->IndexJoin{IndexReader(Index(t.c_d_e)[[NULL,+inf]]->HashAgg)->HashAgg->IndexReader(Index(t.g)[[NULL,+inf]])}(test.t3.d,test.t2.g)}->StreamAgg" } ] + }, + { + "Name": "TestHintFromDiffDatabase", + "Cases": [ + { + "SQL": "select /*+ inl_hash_join(test.t1) */ * from test.t2 join test.t1 on test.t2.a = test.t1.a", + "Plan": "IndexHashJoin{IndexReader(Index(t2.idx_a)[[-inf,+inf]])->IndexReader(Index(t1.idx_a)[[NULL,+inf]]->Sel([not(isnull(test.t1.a))]))}(test.t2.a,test.t1.a)" + } + ] } ]