Skip to content

Commit

Permalink
planner: fix panic when building index merge plan (#23141)
Browse files Browse the repository at this point in the history
  • Loading branch information
eurekaka authored Mar 8, 2021
1 parent ae50555 commit 3b016a9
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
16 changes: 16 additions & 0 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2607,6 +2607,22 @@ func (s *testIntegrationSuite) TestReorderSimplifiedOuterJoins(c *C) {
}
}

func (s *testIntegrationSuite) TestIndexMergeConstantTrue(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t(a int primary key, b int not null, key(b))")
tk.MustExec("delete /*+ use_index_merge(t) */ FROM t WHERE a=1 OR (b < SOME (SELECT /*+ use_index_merge(t)*/ b FROM t WHERE a<2 OR b<2))")

tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int not null, b int not null, key(a), key(b))")
tk.MustExec("delete /*+ use_index_merge(t) */ FROM t WHERE a=1 OR (b < SOME (SELECT /*+ use_index_merge(t)*/ b FROM t WHERE a<2 OR b<2))")

tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int primary key, b int not null, c int, key(a), key(b,c))")
tk.MustExec("delete /*+ use_index_merge(t) */ FROM t WHERE a=1 OR (a<2 and b<2)")
}

func (s *testIntegrationSerialSuite) TestPushDownAggForMPP(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
Expand Down
18 changes: 11 additions & 7 deletions planner/core/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,10 @@ func (ds *DataSource) accessPathsForConds(conditions []expression.Expression, us
logutil.BgLogger().Debug("can not derive statistics of a path", zap.Error(err))
continue
}
if len(path.AccessConds) == 0 {
// If AccessConds is empty, we ignore the access path.
// If `AccessConds` is empty, we ignore the access path.
// If the path contains a full range, ignore it also. This can happen when `AccessConds` is constant true, and
// it comes from the result of a subquery, so it is not folded.
if len(path.AccessConds) == 0 || ranger.HasFullRange(path.Ranges) {
continue
}
// If we have point or empty range, just remove other possible paths.
Expand All @@ -531,8 +533,10 @@ func (ds *DataSource) accessPathsForConds(conditions []expression.Expression, us
continue
}
noIntervalRanges := ds.deriveIndexPathStats(path, conditions, true)
if len(path.AccessConds) == 0 {
// If AccessConds is empty, we ignore the access path.
// If `AccessConds` is empty, we ignore the access path.
// If the path contains a full range, ignore it also. This can happen when `AccessConds` is constant true, and
// it comes from the result of a subquery, so it is not folded.
if len(path.AccessConds) == 0 || ranger.HasFullRange(path.Ranges) {
continue
}
// If we have empty range, or point range on unique index, just remove other possible paths.
Expand Down Expand Up @@ -561,9 +565,9 @@ func (ds *DataSource) buildIndexMergePartialPath(indexAccessPaths []*util.Access
minEstRowIndex := 0
minEstRow := math.MaxFloat64
for i := 0; i < len(indexAccessPaths); i++ {
rc, err := ds.stats.HistColl.GetRowCountByIndexRanges(ds.ctx.GetSessionVars().StmtCtx, indexAccessPaths[i].Index.ID, indexAccessPaths[i].Ranges)
if err != nil {
return nil, err
rc := indexAccessPaths[i].CountAfterAccess
if len(indexAccessPaths[i].IndexFilters) > 0 {
rc = indexAccessPaths[i].CountAfterIndex
}
if rc < minEstRow {
minEstRowIndex = i
Expand Down
10 changes: 10 additions & 0 deletions util/ranger/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,16 @@ func (ran *Range) IsFullRange() bool {
return true
}

// HasFullRange checks if any range in the slice is a full range.
func HasFullRange(ranges []*Range) bool {
for _, ran := range ranges {
if ran.IsFullRange() {
return true
}
}
return false
}

// String implements the Stringer interface.
func (ran *Range) String() string {
lowStrs := make([]string, 0, len(ran.LowVal))
Expand Down

0 comments on commit 3b016a9

Please sign in to comment.