Skip to content

Commit

Permalink
stats: support display invalid key in stats buckets (#12064) (#12094)
Browse files Browse the repository at this point in the history
  • Loading branch information
sre-bot authored and zz-jason committed Sep 12, 2019
1 parent 842c81c commit 299da1b
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 15 deletions.
2 changes: 1 addition & 1 deletion executor/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,7 @@ type analyzeIndexIncrementalExec struct {

func analyzeIndexIncremental(idxExec *analyzeIndexIncrementalExec) analyzeResult {
startPos := idxExec.oldHist.GetUpper(idxExec.oldHist.Len() - 1)
values, err := codec.DecodeRange(startPos.GetBytes(), len(idxExec.idxInfo.Columns))
values, _, err := codec.DecodeRange(startPos.GetBytes(), len(idxExec.idxInfo.Columns))
if err != nil {
return analyzeResult{Err: err, job: idxExec.job}
}
Expand Down
6 changes: 3 additions & 3 deletions statistics/feedback.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ func (q *QueryFeedback) DecodeToRanges(isIndex bool) ([]*ranger.Range, error) {
if isIndex {
var err error
// As we do not know the origin length, just use a custom value here.
lowVal, err = codec.DecodeRange(low.GetBytes(), 4)
lowVal, _, err = codec.DecodeRange(low.GetBytes(), 4)
if err != nil {
return nil, errors.Trace(err)
}
highVal, err = codec.DecodeRange(high.GetBytes(), 4)
highVal, _, err = codec.DecodeRange(high.GetBytes(), 4)
if err != nil {
return nil, errors.Trace(err)
}
Expand Down Expand Up @@ -837,7 +837,7 @@ func ConvertDatumsType(vals []types.Datum, ft *types.FieldType, loc *time.Locati
}

func decodeColumnBounds(data []byte, ft *types.FieldType) ([]types.Datum, error) {
vals, err := codec.DecodeRange(data, 1)
vals, _, err := codec.DecodeRange(data, 1)
if err != nil {
return nil, err
}
Expand Down
7 changes: 4 additions & 3 deletions statistics/histogram.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,10 @@ func ValueToString(value *types.Datum, idxCols int) (string, error) {
if idxCols == 0 {
return value.ToString()
}
decodedVals, err := codec.DecodeRange(value.GetBytes(), idxCols)
if err != nil {
return "", errors.Trace(err)
// Treat remaining part that cannot decode successfully as bytes.
decodedVals, remained, err := codec.DecodeRange(value.GetBytes(), idxCols)
if err != nil && len(remained) > 0 {
decodedVals = append(decodedVals, types.NewBytesDatum(remained))
}
str, err := types.DatumsToString(decodedVals, true)
if err != nil {
Expand Down
11 changes: 11 additions & 0 deletions statistics/histogram_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,14 @@ num: 30 lower_bound: 12 upper_bound: 14 repeats: 10`
c.Assert(err, IsNil, Commentf("Test failed: %v", err))
c.Assert(newIdx.String(), Equals, idxResult)
}

func (s *testStatisticsSuite) TestValueToString4InvalidKey(c *C) {
bytes, err := codec.EncodeKey(nil, nil, types.NewDatum(1), types.NewDatum(0.5))
c.Assert(err, IsNil)
// Append invalid flag.
bytes = append(bytes, 20)
datum := types.NewDatum(bytes)
res, err := ValueToString(&datum, 3)
c.Assert(err, IsNil)
c.Assert(res, Equals, "(1, 0.5, \x14)")
}
10 changes: 5 additions & 5 deletions util/codec/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ func Decode(b []byte, size int) ([]types.Datum, error) {

// DecodeRange decodes the range values from a byte slice that generated by EncodeKey.
// It handles some special values like `MinNotNull` and `MaxValueDatum`.
func DecodeRange(b []byte, size int) ([]types.Datum, error) {
func DecodeRange(b []byte, size int) ([]types.Datum, []byte, error) {
if len(b) < 1 {
return nil, errors.New("invalid encoded key: length of key is zero")
return nil, b, errors.New("invalid encoded key: length of key is zero")
}

var (
Expand All @@ -326,7 +326,7 @@ func DecodeRange(b []byte, size int) ([]types.Datum, error) {
var d types.Datum
b, d, err = DecodeOne(b)
if err != nil {
return nil, errors.Trace(err)
return values, b, errors.Trace(err)
}
values = append(values, d)
}
Expand All @@ -341,10 +341,10 @@ func DecodeRange(b []byte, size int) ([]types.Datum, error) {
case maxFlag, maxFlag + 1:
values = append(values, types.MaxValueDatum())
default:
return nil, errors.Errorf("invalid encoded key flag %v", b[0])
return values, b, errors.Errorf("invalid encoded key flag %v", b[0])
}
}
return values, nil
return values, nil, nil
}

// DecodeOne decodes on datum from a byte slice generated with EncodeKey or EncodeValue.
Expand Down
6 changes: 3 additions & 3 deletions util/codec/codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -985,14 +985,14 @@ func chunkForTest(c *C, sc *stmtctx.StatementContext, datums []types.Datum, tps
}

func (s *testCodecSuite) TestDecodeRange(c *C) {
_, err := DecodeRange(nil, 0)
_, _, err := DecodeRange(nil, 0)
c.Assert(err, NotNil)

datums := types.MakeDatums(1, "abc", 1.1, []byte("def"))
rowData, err := EncodeValue(nil, nil, datums...)
c.Assert(err, IsNil)

datums1, err := DecodeRange(rowData, len(datums))
datums1, _, err := DecodeRange(rowData, len(datums))
c.Assert(err, IsNil)
for i, datum := range datums1 {
cmp, err := datum.CompareDatum(nil, &datums[i])
Expand All @@ -1002,7 +1002,7 @@ func (s *testCodecSuite) TestDecodeRange(c *C) {

for _, b := range []byte{NilFlag, bytesFlag, maxFlag, maxFlag + 1} {
newData := append(rowData, b)
_, err := DecodeRange(newData, len(datums)+1)
_, _, err := DecodeRange(newData, len(datums)+1)
c.Assert(err, IsNil)
}
}
Expand Down

0 comments on commit 299da1b

Please sign in to comment.