diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index 55c2fd7b9943b..f66c8dd0970a3 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -703,8 +703,8 @@ func (s *testIntegrationSuite) TestIndexHintWarning(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2") - tk.MustExec("create table t1(a int, b int, c int, key a(a))") - tk.MustExec("create table t2(a int, b int, c int, key a(a))") + tk.MustExec("create table t1(a int, b int, c int, key a(a), key b(b))") + tk.MustExec("create table t2(a int, b int, c int, key a(a), key b(b))") var input []string var output []struct { SQL string diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index a4e5dcea8bc2f..777b7a08d97db 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -2689,8 +2689,37 @@ func (b *PlanBuilder) buildDataSource(ctx context.Context, tn *ast.TableName, as if hints := b.TableHints(); hints != nil { for i, hint := range hints.indexMergeHintList { if hint.tblName.L == tblName.L { - indexMergeHints = append(indexMergeHints, hint.indexHint) hints.indexMergeHintList[i].matched = true + // check whether the index names in IndexMergeHint are valid. + invalidIdxNames := make([]string, 0, len(hint.indexHint.IndexNames)) + for _, idxName := range hint.indexHint.IndexNames { + hasIdxName := false + for _, path := range possiblePaths { + if path.IsTablePath { + if idxName.L == "primary" { + hasIdxName = true + break + } + continue + } + if idxName.L == path.Index.Name.L { + hasIdxName = true + break + } + } + if !hasIdxName { + invalidIdxNames = append(invalidIdxNames, idxName.String()) + } + } + if len(invalidIdxNames) == 0 { + indexMergeHints = append(indexMergeHints, hint.indexHint) + } else { + // Append warning if there are invalid index names. + errMsg := fmt.Sprintf("use_index_merge(%s) is inapplicable, check whether the indexes (%s) "+ + "exist, or the indexes are conflicted with use_index/ignore_index hints.", + hint.indexString(), strings.Join(invalidIdxNames, ", ")) + b.ctx.GetSessionVars().StmtCtx.AppendWarning(ErrInternal.GenWithStack(errMsg)) + } } } } diff --git a/planner/core/testdata/integration_suite_in.json b/planner/core/testdata/integration_suite_in.json index 5982747656b02..5f9c9cc1fffae 100644 --- a/planner/core/testdata/integration_suite_in.json +++ b/planner/core/testdata/integration_suite_in.json @@ -80,7 +80,11 @@ "select /*+ USE_INDEX(t2) */ * from t1", "select /*+ USE_INDEX(t1, a), USE_INDEX(t2, a), USE_INDEX(t3, a) */ * from t1, t2 where t1.a=t2.a", "select /*+ USE_INDEX(t3, a), USE_INDEX(t4, b), IGNORE_INDEX(t3, a) */ * from t1, t2 where t1.a=t2.a", - "select /*+ USE_INDEX_MERGE(t3, a, b, d) */ * from t1" + "select /*+ USE_INDEX_MERGE(t3, a, b, d) */ * from t1", + "select /*+ USE_INDEX_MERGE(t1, a, b, c, d) */ * from t1", + "select /*+ USE_INDEX_MERGE(t1, a, b), USE_INDEX(t1, a) */ * from t1", + "select /*+ USE_INDEX_MERGE(t1, a, b), IGNORE_INDEX(t1, a) */ * from t1", + "select /*+ USE_INDEX_MERGE(t1, primary, a, b, c) */ * from t1" ] }, { diff --git a/planner/core/testdata/integration_suite_out.json b/planner/core/testdata/integration_suite_out.json index e1c110ce75d4b..4e4e3a3b17b6f 100644 --- a/planner/core/testdata/integration_suite_out.json +++ b/planner/core/testdata/integration_suite_out.json @@ -301,6 +301,30 @@ "Warnings": [ "[planner:1815]use_index_merge(test.t3, a, b, d) is inapplicable, check whether the table(test.t3) exists" ] + }, + { + "SQL": "select /*+ USE_INDEX_MERGE(t1, a, b, c, d) */ * from t1", + "Warnings": [ + "[planner:1815]use_index_merge(test.t1, a, b, c, d) is inapplicable, check whether the indexes (c, d) exist, or the indexes are conflicted with use_index/ignore_index hints." + ] + }, + { + "SQL": "select /*+ USE_INDEX_MERGE(t1, a, b), USE_INDEX(t1, a) */ * from t1", + "Warnings": [ + "[planner:1815]use_index_merge(test.t1, a, b) is inapplicable, check whether the indexes (b) exist, or the indexes are conflicted with use_index/ignore_index hints." + ] + }, + { + "SQL": "select /*+ USE_INDEX_MERGE(t1, a, b), IGNORE_INDEX(t1, a) */ * from t1", + "Warnings": [ + "[planner:1815]use_index_merge(test.t1, a, b) is inapplicable, check whether the indexes (a) exist, or the indexes are conflicted with use_index/ignore_index hints." + ] + }, + { + "SQL": "select /*+ USE_INDEX_MERGE(t1, primary, a, b, c) */ * from t1", + "Warnings": [ + "[planner:1815]use_index_merge(test.t1, primary, a, b, c) is inapplicable, check whether the indexes (c) exist, or the indexes are conflicted with use_index/ignore_index hints." + ] } ] },