Skip to content

Commit

Permalink
stats: fix combined index low-bound check (#7814)
Browse files Browse the repository at this point in the history
  • Loading branch information
lysu authored Oct 8, 2018
1 parent 05666f5 commit d5d8ba0
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
22 changes: 20 additions & 2 deletions statistics/histogram.go
Original file line number Diff line number Diff line change
Expand Up @@ -682,9 +682,8 @@ func (hg *Histogram) outOfRange(val types.Datum) bool {
if hg.Bounds == nil {
return true
}
len := hg.Bounds.NumRows()
return chunk.Compare(hg.Bounds.GetRow(0), 0, &val) > 0 ||
chunk.Compare(hg.Bounds.GetRow(len-1), 0, &val) < 0
chunk.Compare(hg.Bounds.GetRow(hg.Bounds.NumRows()-1), 0, &val) < 0
}

// ErrorRate is the error rate of estimate row count by bucket and cm sketch.
Expand Down Expand Up @@ -857,3 +856,22 @@ func (idx *Index) getRowCount(sc *stmtctx.StatementContext, indexRanges []*range
}
return totalCount, nil
}

func (idx *Index) outOfRange(val types.Datum) bool {
if idx.Bounds == nil {
return true
}
withInLowBoundOrPrefixMatch := chunk.Compare(idx.Bounds.GetRow(0), 0, &val) <= 0 ||
matchPrefix(idx.Bounds.GetRow(0), 0, &val)
withInHighBound := chunk.Compare(idx.Bounds.GetRow(idx.Bounds.NumRows()-1), 0, &val) >= 0
return !withInLowBoundOrPrefixMatch || !withInHighBound
}

// matchPrefix checks whether ad is the prefix of value
func matchPrefix(row chunk.Row, colIdx int, ad *types.Datum) bool {
switch ad.Kind() {
case types.KindString, types.KindBytes, types.KindBinaryLiteral, types.KindMysqlBit:
return strings.HasPrefix(row.GetString(colIdx), ad.GetString())
}
return false
}
12 changes: 12 additions & 0 deletions statistics/selectivity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,18 @@ func (s *testSelectivitySuite) TestDiscreteDistribution(c *C) {
"└─IndexScan_8 0.00 cop table:t, index:a, b, range:[\"tw\" -inf,\"tw\" 0), keep order:false"))
}

func (s *testSelectivitySuite) TestSelectCombinedLowBound(c *C) {
testKit := testkit.NewTestKit(c, s.store)
testKit.MustExec("use test")
testKit.MustExec("drop table if exists t")
testKit.MustExec("create table t(id int auto_increment, kid int, pid int, primary key(id), key(kid, pid))")
testKit.MustExec("insert into t (kid, pid) values (1,2), (1,3), (1,4),(1, 11), (1, 12), (1, 13), (1, 14), (2, 2), (2, 3), (2, 4)")
testKit.MustExec("analyze table t")
testKit.MustQuery("explain select * from t where kid = 1").Check(testkit.Rows(
"IndexReader_9 7.00 root index:IndexScan_8",
"└─IndexScan_8 7.00 cop table:t, index:kid, pid, range:[1,1], keep order:false"))
}

func getRange(start, end int64) []*ranger.Range {
ran := &ranger.Range{
LowVal: []types.Datum{types.NewIntDatum(start)},
Expand Down

0 comments on commit d5d8ba0

Please sign in to comment.