From af0ce2944e6f2a15b4a8ddd2fc820cbbe99944f1 Mon Sep 17 00:00:00 2001 From: Jian Zhang Date: Tue, 7 Aug 2018 15:46:24 +0800 Subject: [PATCH 1/3] plan: make `USE INDEX(`PRIMARY`)` works on the integer primary key --- plan/planbuilder.go | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/plan/planbuilder.go b/plan/planbuilder.go index 30cc7e8d2524e..fc6a0856163cf 100644 --- a/plan/planbuilder.go +++ b/plan/planbuilder.go @@ -267,15 +267,27 @@ func (b *planBuilder) detectSelectAgg(sel *ast.SelectStmt) bool { return false } -func getPathByIndexName(paths []*accessPath, idxName model.CIStr) *accessPath { +func getPathByIndexName(paths []*accessPath, idxName model.CIStr, tblInfo *model.TableInfo) *accessPath { + var tablePath *accessPath for _, path := range paths { + if path.isTablePath { + tablePath = path + continue + } if path.index.Name.L == idxName.L { return path } } + if isPrimaryIndexHint(idxName) && tblInfo.PKIsHandle { + return tablePath + } return nil } +func isPrimaryIndexHint(indexName model.CIStr) bool { + return indexName.L == "primary" +} + func getPossibleAccessPaths(indexHints []*ast.IndexHint, tblInfo *model.TableInfo) ([]*accessPath, error) { publicPaths := make([]*accessPath, 0, len(tblInfo.Indices)+1) publicPaths = append(publicPaths, &accessPath{isTablePath: true}) @@ -295,7 +307,7 @@ func getPossibleAccessPaths(indexHints []*ast.IndexHint, tblInfo *model.TableInf hasScanHint = true for _, idxName := range hint.IndexNames { - path := getPathByIndexName(publicPaths[1:], idxName) + path := getPathByIndexName(publicPaths, idxName, tblInfo) if path == nil { return nil, ErrKeyDoesNotExist.GenByArgs(idxName, tblInfo.Name) } @@ -316,7 +328,7 @@ func getPossibleAccessPaths(indexHints []*ast.IndexHint, tblInfo *model.TableInf available = publicPaths } - available = removeIgnoredPaths(available, ignored) + available = removeIgnoredPaths(available, ignored, tblInfo) // If we have got "FORCE" or "USE" index hint but got no available index, // we have to use table scan. @@ -326,13 +338,13 @@ func getPossibleAccessPaths(indexHints []*ast.IndexHint, tblInfo *model.TableInf return available, nil } -func removeIgnoredPaths(paths, ignoredPaths []*accessPath) []*accessPath { +func removeIgnoredPaths(paths, ignoredPaths []*accessPath, tblInfo *model.TableInfo) []*accessPath { if len(ignoredPaths) == 0 { return paths } remainedPaths := make([]*accessPath, 0, len(paths)) for _, path := range paths { - if path.isTablePath || getPathByIndexName(ignoredPaths, path.index.Name) == nil { + if path.isTablePath || getPathByIndexName(ignoredPaths, path.index.Name, tblInfo) == nil { remainedPaths = append(remainedPaths, path) } } From 07a56ae21137dea39ec08b68604eedbdbcad23f3 Mon Sep 17 00:00:00 2001 From: Jian Zhang Date: Tue, 7 Aug 2018 16:08:55 +0800 Subject: [PATCH 2/3] add ut --- plan/planbuilder_test.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/plan/planbuilder_test.go b/plan/planbuilder_test.go index e5cfae3d2aac6..ef1ebe7f4fda4 100644 --- a/plan/planbuilder_test.go +++ b/plan/planbuilder_test.go @@ -16,6 +16,7 @@ package plan import ( . "github.com/pingcap/check" "github.com/pingcap/tidb/ast" + "github.com/pingcap/tidb/model" ) var _ = Suite(&testPlanBuilderSuite{}) @@ -56,3 +57,34 @@ func (s *testPlanBuilderSuite) TestShow(c *C) { } } } + +func (s *testPlanBuilderSuite) TestGetPathByIndexName(c *C) { + tblInfo := &model.TableInfo{ + Indices: make([]*model.IndexInfo, 0), + PKIsHandle: true, + } + + accessPath := []*accessPath{ + &accessPath{isTablePath: true}, + &accessPath{index: &model.IndexInfo{Name: model.NewCIStr("idx")}}, + } + + path := getPathByIndexName(accessPath, model.NewCIStr("idx"), tblInfo) + c.Assert(path, NotNil) + c.Assert(path, Equals, accessPath[1]) + + path = getPathByIndexName(accessPath, model.NewCIStr("primary"), tblInfo) + c.Assert(path, NotNil) + c.Assert(path, Equals, accessPath[0]) + + path = getPathByIndexName(accessPath, model.NewCIStr("not exists"), tblInfo) + c.Assert(path, IsNil) + + tblInfo = &model.TableInfo{ + Indices: make([]*model.IndexInfo, 0), + PKIsHandle: false, + } + + path = getPathByIndexName(accessPath, model.NewCIStr("primary"), tblInfo) + c.Assert(path, IsNil) +} From 31ad8183cfb8447e0085f9b1f92c8b7b62e53356 Mon Sep 17 00:00:00 2001 From: Jian Zhang Date: Wed, 8 Aug 2018 13:14:38 +0800 Subject: [PATCH 3/3] make gofmt happy --- plan/planbuilder_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plan/planbuilder_test.go b/plan/planbuilder_test.go index ef1ebe7f4fda4..4e26a9b701f8f 100644 --- a/plan/planbuilder_test.go +++ b/plan/planbuilder_test.go @@ -65,8 +65,8 @@ func (s *testPlanBuilderSuite) TestGetPathByIndexName(c *C) { } accessPath := []*accessPath{ - &accessPath{isTablePath: true}, - &accessPath{index: &model.IndexInfo{Name: model.NewCIStr("idx")}}, + {isTablePath: true}, + {index: &model.IndexInfo{Name: model.NewCIStr("idx")}}, } path := getPathByIndexName(accessPath, model.NewCIStr("idx"), tblInfo)