diff --git a/ddl/multi_schema_change_test.go b/ddl/multi_schema_change_test.go index 0f8aeca87802c..e211e9d51ca77 100644 --- a/ddl/multi_schema_change_test.go +++ b/ddl/multi_schema_change_test.go @@ -719,8 +719,8 @@ func TestMultiSchemaChangeAddDropIndexes(t *testing.T) { tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a int, b int, c int, index (a), index(b), index(c));") tk.MustExec("insert into t values (1, 2, 3);") - tk.MustExec("alter table t add index aa(a), drop index a, add index cc(c), drop index b, drop index c, add index bb(b);") - tk.MustQuery("select * from t use index(aa, bb, cc);").Check(testkit.Rows("1 2 3")) + tk.MustExec("alter table t add index xa(a), drop index a, add index xc(c), drop index b, drop index c, add index xb(b);") + tk.MustQuery("select * from t use index(xa, xb, xc);").Check(testkit.Rows("1 2 3")) tk.MustGetErrCode("select * from t use index(a);", errno.ErrKeyDoesNotExist) tk.MustGetErrCode("select * from t use index(b);", errno.ErrKeyDoesNotExist) tk.MustGetErrCode("select * from t use index(c);", errno.ErrKeyDoesNotExist) diff --git a/planner/core/logical_plan_test.go b/planner/core/logical_plan_test.go index 7458c7307c19c..82786703338f4 100644 --- a/planner/core/logical_plan_test.go +++ b/planner/core/logical_plan_test.go @@ -863,7 +863,7 @@ func TestValidate(t *testing.T) { err: ErrUnknownColumn, }, { - sql: "select * from t t1 use index(e)", + sql: "select * from t t1 use index(x)", err: ErrKeyDoesNotExist, }, { diff --git a/planner/core/mock.go b/planner/core/mock.go index e96c10ca20d13..472c980fa3777 100644 --- a/planner/core/mock.go +++ b/planner/core/mock.go @@ -73,7 +73,7 @@ func MockSignedTable() *model.TableInfo { Unique: true, }, { - Name: model.NewCIStr("e"), + Name: model.NewCIStr("x"), Columns: []*model.IndexColumn{ { Name: model.NewCIStr("e"), diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index d8677ea7dd072..057ff536a7102 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -1168,7 +1168,8 @@ func (b *PlanBuilder) detectSelectWindow(sel *ast.SelectStmt) bool { } func getPathByIndexName(paths []*util.AccessPath, idxName model.CIStr, tblInfo *model.TableInfo) *util.AccessPath { - var primaryIdxPath *util.AccessPath + var primaryIdxPath, indexPrefixPath *util.AccessPath + prefixMatches := 0 for _, path := range paths { if path.StoreType == kv.TiFlash { continue @@ -1180,10 +1181,19 @@ func getPathByIndexName(paths []*util.AccessPath, idxName model.CIStr, tblInfo * if path.Index.Name.L == idxName.L { return path } + if strings.HasPrefix(path.Index.Name.L, idxName.L) { + indexPrefixPath = path + prefixMatches++ + } } if isPrimaryIndex(idxName) && tblInfo.HasClusteredIndex() { return primaryIdxPath } + + // Return only unique prefix matches + if prefixMatches == 1 { + return indexPrefixPath + } return nil } diff --git a/planner/core/planbuilder_test.go b/planner/core/planbuilder_test.go index 13494433f0fbe..8ad1d5c49c0e2 100644 --- a/planner/core/planbuilder_test.go +++ b/planner/core/planbuilder_test.go @@ -91,6 +91,11 @@ func TestGetPathByIndexName(t *testing.T) { require.NotNil(t, path) require.Equal(t, accessPath[1], path) + // "id" is a prefix of "idx" + path = getPathByIndexName(accessPath, model.NewCIStr("id"), tblInfo) + require.NotNil(t, path) + require.Equal(t, accessPath[1], path) + path = getPathByIndexName(accessPath, model.NewCIStr("primary"), tblInfo) require.NotNil(t, path) require.Equal(t, accessPath[0], path)