diff --git a/distsql/request_builder.go b/distsql/request_builder.go index 3c2a9abe16586..da1bd1ffc0e57 100644 --- a/distsql/request_builder.go +++ b/distsql/request_builder.go @@ -269,7 +269,7 @@ func IndexRangesToKVRanges(sc *stmtctx.StatementContext, tid, idxID int64, range feedbackRanges = append(feedbackRanges, &ranger.Range{LowVal: []types.Datum{types.NewBytesDatum(low)}, HighVal: []types.Datum{types.NewBytesDatum(high)}, LowExclude: false, HighExclude: true}) } - feedbackRanges = fb.Hist().SplitRange(feedbackRanges) + feedbackRanges = fb.Hist().SplitRange(sc, feedbackRanges) krs := make([]kv.KeyRange, 0, len(feedbackRanges)) for _, ran := range feedbackRanges { low, high := ran.LowVal[0].GetBytes(), ran.HighVal[0].GetBytes() diff --git a/executor/table_reader.go b/executor/table_reader.go index 600f391cc5643..00bc3d87dc3a7 100644 --- a/executor/table_reader.go +++ b/executor/table_reader.go @@ -96,8 +96,9 @@ func (e *TableReaderExecutor) Open(ctx context.Context) error { } e.resultHandler = &tableResultHandler{} + // Split ranges here since the unsigned part and signed part will swap their position when encoding the range to kv ranges. if e.feedback != nil && e.feedback.Hist() != nil { - e.ranges = e.feedback.Hist().SplitRange(e.ranges) + e.ranges = e.feedback.Hist().SplitRange(e.ctx.GetSessionVars().StmtCtx, e.ranges) } firstPartRanges, secondPartRanges := splitRanges(e.ranges, e.keepOrder, e.desc) firstResult, err := e.buildResp(ctx, firstPartRanges) diff --git a/statistics/histogram.go b/statistics/histogram.go index 370e270e828d7..2bbc4c8a07387 100644 --- a/statistics/histogram.go +++ b/statistics/histogram.go @@ -503,7 +503,7 @@ func (hg *Histogram) getIncreaseFactor(totalCount int64) float64 { // validRange checks if the range is valid, it is used by `SplitRange` to remove the invalid range, // the possible types of range are index key range and handle key range. -func validRange(ran *ranger.Range) bool { +func validRange(sc *stmtctx.StatementContext, ran *ranger.Range) bool { var low, high []byte if ran.LowVal[0].Kind() == types.KindBytes { low, high = ran.LowVal[0].GetBytes(), ran.HighVal[0].GetBytes() @@ -530,7 +530,7 @@ func validRange(ran *ranger.Range) bool { // SplitRange splits the range according to the histogram upper bound. Note that we treat last bucket's upper bound // as inf, so all the split ranges will totally fall in one of the (-inf, u(0)], (u(0), u(1)],...(u(n-3), u(n-2)], // (u(n-2), +inf), where n is the number of buckets, u(i) is the i-th bucket's upper bound. -func (hg *Histogram) SplitRange(ranges []*ranger.Range) []*ranger.Range { +func (hg *Histogram) SplitRange(sc *stmtctx.StatementContext, ranges []*ranger.Range) []*ranger.Range { split := make([]*ranger.Range, 0, len(ranges)) for len(ranges) > 0 { // Find the last bound that greater or equal to the LowVal. @@ -574,7 +574,7 @@ func (hg *Histogram) SplitRange(ranges []*ranger.Range) []*ranger.Range { HighExclude: false}) ranges[0].LowVal[0] = upper ranges[0].LowExclude = true - if !validRange(ranges[0]) { + if !validRange(sc, ranges[0]) { ranges = ranges[1:] } } diff --git a/statistics/update_test.go b/statistics/update_test.go index 1977993a97757..816aef606d7f0 100644 --- a/statistics/update_test.go +++ b/statistics/update_test.go @@ -604,7 +604,7 @@ func (s *testStatsUpdateSuite) TestSplitRange(c *C) { HighExclude: t.exclude[i+1], }) } - ranges = h.SplitRange(ranges) + ranges = h.SplitRange(nil, ranges) var ranStrs []string for _, ran := range ranges { ranStrs = append(ranStrs, ran.String()) @@ -1344,7 +1344,7 @@ func (s *testStatsUpdateSuite) TestUnsignedFeedbackRanges(c *C) { statistics.FeedbackProbability = 1 testKit.MustExec("use test") - testKit.MustExec("create table t (a tinyint unsigned, primary key(a))") + testKit.MustExec("create table t (a bigint unsigned, primary key(a))") for i := 0; i < 20; i++ { testKit.MustExec(fmt.Sprintf("insert into t values (%d)", i)) } @@ -1371,7 +1371,7 @@ func (s *testStatsUpdateSuite) TestUnsignedFeedbackRanges(c *C) { hist: "column:1 ndv:30 totColSize:0\n" + "num: 8 lower_bound: 0 upper_bound: 7 repeats: 0\n" + "num: 8 lower_bound: 8 upper_bound: 15 repeats: 0\n" + - "num: 14 lower_bound: 16 upper_bound: 255 repeats: 0", + "num: 14 lower_bound: 16 upper_bound: 18446744073709551615 repeats: 0", }, } is := s.do.InfoSchema()