Skip to content

Commit

Permalink
plan: make USE INDEX(PRIMARY) works on the integer primary key (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
zz-jason authored Aug 8, 2018
1 parent 478d990 commit 15be7e5
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
22 changes: 17 additions & 5 deletions plan/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,15 +270,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})
Expand All @@ -298,7 +310,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)
}
Expand All @@ -319,7 +331,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.
Expand All @@ -329,13 +341,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)
}
}
Expand Down
32 changes: 32 additions & 0 deletions plan/planbuilder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package plan
import (
. "github.com/pingcap/check"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/model"
)

var _ = Suite(&testPlanBuilderSuite{})
Expand Down Expand Up @@ -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{
{isTablePath: true},
{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)
}

0 comments on commit 15be7e5

Please sign in to comment.