github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/allegrosql/tablecodec/tablecodec_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package blockcodec
    15  
    16  import (
    17  	"fmt"
    18  	"math"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    23  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    24  	. "github.com/whtcorpsinc/check"
    25  	"github.com/whtcorpsinc/failpoint"
    26  	"github.com/whtcorpsinc/milevadb/ekv"
    27  	"github.com/whtcorpsinc/milevadb/soliton/codec"
    28  	"github.com/whtcorpsinc/milevadb/soliton/rowcodec"
    29  	"github.com/whtcorpsinc/milevadb/soliton/testleak"
    30  	"github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx"
    31  	"github.com/whtcorpsinc/milevadb/types"
    32  )
    33  
    34  func TestT(t *testing.T) {
    35  	TestingT(t)
    36  }
    37  
    38  var _ = SerialSuites(&testTableCodecSuite{})
    39  
    40  type testTableCodecSuite struct{}
    41  
    42  // TestTableCodec  tests some functions in package blockcodec
    43  // TODO: add more tests.
    44  func (s *testTableCodecSuite) TestTableCodec(c *C) {
    45  	defer testleak.AfterTest(c)()
    46  	key := EncodeRowKey(1, codec.EncodeInt(nil, 2))
    47  	h, err := DecodeRowKey(key)
    48  	c.Assert(err, IsNil)
    49  	c.Assert(h.IntValue(), Equals, int64(2))
    50  
    51  	key = EncodeRowKeyWithHandle(1, ekv.IntHandle(2))
    52  	h, err = DecodeRowKey(key)
    53  	c.Assert(err, IsNil)
    54  	c.Assert(h.IntValue(), Equals, int64(2))
    55  }
    56  
    57  // column is a structure used for test
    58  type column struct {
    59  	id int64
    60  	tp *types.FieldType
    61  }
    62  
    63  func (s *testTableCodecSuite) TestRowCodec(c *C) {
    64  	defer testleak.AfterTest(c)()
    65  
    66  	c1 := &column{id: 1, tp: types.NewFieldType(allegrosql.TypeLonglong)}
    67  	c2 := &column{id: 2, tp: types.NewFieldType(allegrosql.TypeVarchar)}
    68  	c3 := &column{id: 3, tp: types.NewFieldType(allegrosql.TypeNewDecimal)}
    69  	c4 := &column{id: 4, tp: &types.FieldType{Tp: allegrosql.TypeEnum, Elems: []string{"a"}}}
    70  	c5 := &column{id: 5, tp: &types.FieldType{Tp: allegrosql.TypeSet, Elems: []string{"a"}}}
    71  	c6 := &column{id: 6, tp: &types.FieldType{Tp: allegrosql.TypeBit, Flen: 8}}
    72  	defcaus := []*column{c1, c2, c3, c4, c5, c6}
    73  
    74  	event := make([]types.Causet, 6)
    75  	event[0] = types.NewIntCauset(100)
    76  	event[1] = types.NewBytesCauset([]byte("abc"))
    77  	event[2] = types.NewDecimalCauset(types.NewDecFromInt(1))
    78  	event[3] = types.NewMysqlEnumCauset(types.Enum{Name: "a", Value: 1})
    79  	event[4] = types.NewCauset(types.Set{Name: "a", Value: 1})
    80  	event[5] = types.NewCauset(types.BinaryLiteral{100})
    81  	// Encode
    82  	colIDs := make([]int64, 0, len(event))
    83  	for _, col := range defcaus {
    84  		colIDs = append(colIDs, col.id)
    85  	}
    86  	rd := rowcodec.CausetEncoder{Enable: true}
    87  	sc := &stmtctx.StatementContext{TimeZone: time.Local}
    88  	bs, err := EncodeRow(sc, event, colIDs, nil, nil, &rd)
    89  	c.Assert(err, IsNil)
    90  	c.Assert(bs, NotNil)
    91  
    92  	// Decode
    93  	colMap := make(map[int64]*types.FieldType, len(event))
    94  	for _, col := range defcaus {
    95  		colMap[col.id] = col.tp
    96  	}
    97  	r, err := DecodeRowToCausetMap(bs, colMap, time.UTC)
    98  	c.Assert(err, IsNil)
    99  	c.Assert(r, NotNil)
   100  	c.Assert(r, HasLen, len(event))
   101  	// Compare decoded event and original event
   102  	for i, col := range defcaus {
   103  		v, ok := r[col.id]
   104  		c.Assert(ok, IsTrue)
   105  		equal, err1 := v.CompareCauset(sc, &event[i])
   106  		c.Assert(err1, IsNil)
   107  		c.Assert(equal, Equals, 0, Commentf("expect: %v, got %v", event[i], v))
   108  	}
   109  
   110  	// colMap may contains more columns than encoded event.
   111  	//colMap[4] = types.NewFieldType(allegrosql.TypeFloat)
   112  	r, err = DecodeRowToCausetMap(bs, colMap, time.UTC)
   113  	c.Assert(err, IsNil)
   114  	c.Assert(r, NotNil)
   115  	c.Assert(r, HasLen, len(event))
   116  	for i, col := range defcaus {
   117  		v, ok := r[col.id]
   118  		c.Assert(ok, IsTrue)
   119  		equal, err1 := v.CompareCauset(sc, &event[i])
   120  		c.Assert(err1, IsNil)
   121  		c.Assert(equal, Equals, 0)
   122  	}
   123  
   124  	// colMap may contains less columns than encoded event.
   125  	delete(colMap, 3)
   126  	delete(colMap, 4)
   127  	r, err = DecodeRowToCausetMap(bs, colMap, time.UTC)
   128  	c.Assert(err, IsNil)
   129  	c.Assert(r, NotNil)
   130  	c.Assert(r, HasLen, len(event)-2)
   131  	for i, col := range defcaus {
   132  		if i > 1 {
   133  			break
   134  		}
   135  		v, ok := r[col.id]
   136  		c.Assert(ok, IsTrue)
   137  		equal, err1 := v.CompareCauset(sc, &event[i])
   138  		c.Assert(err1, IsNil)
   139  		c.Assert(equal, Equals, 0)
   140  	}
   141  
   142  	// Make sure empty event return not nil value.
   143  	bs, err = EncodeOldRow(sc, []types.Causet{}, []int64{}, nil, nil)
   144  	c.Assert(err, IsNil)
   145  	c.Assert(bs, HasLen, 1)
   146  
   147  	r, err = DecodeRowToCausetMap(bs, colMap, time.UTC)
   148  	c.Assert(err, IsNil)
   149  	c.Assert(len(r), Equals, 0)
   150  }
   151  
   152  func (s *testTableCodecSuite) TestDecodeDeferredCausetValue(c *C) {
   153  	sc := &stmtctx.StatementContext{TimeZone: time.Local}
   154  
   155  	// test timestamp
   156  	d := types.NewTimeCauset(types.NewTime(types.FromGoTime(time.Now()), allegrosql.TypeTimestamp, types.DefaultFsp))
   157  	bs, err := EncodeOldRow(sc, []types.Causet{d}, []int64{1}, nil, nil)
   158  	c.Assert(err, IsNil)
   159  	c.Assert(bs, NotNil)
   160  	_, bs, err = codec.CutOne(bs) // ignore colID
   161  	c.Assert(err, IsNil)
   162  	tp := types.NewFieldType(allegrosql.TypeTimestamp)
   163  	d1, err := DecodeDeferredCausetValue(bs, tp, sc.TimeZone)
   164  	c.Assert(err, IsNil)
   165  	cmp, err := d1.CompareCauset(sc, &d)
   166  	c.Assert(err, IsNil)
   167  	c.Assert(cmp, Equals, 0)
   168  
   169  	// test set
   170  	elems := []string{"a", "b", "c", "d", "e"}
   171  	e, _ := types.ParseSetValue(elems, uint64(1))
   172  	d = types.NewMysqlSetCauset(e, "")
   173  	bs, err = EncodeOldRow(sc, []types.Causet{d}, []int64{1}, nil, nil)
   174  	c.Assert(err, IsNil)
   175  	c.Assert(bs, NotNil)
   176  	_, bs, err = codec.CutOne(bs) // ignore colID
   177  	c.Assert(err, IsNil)
   178  	tp = types.NewFieldType(allegrosql.TypeSet)
   179  	tp.Elems = elems
   180  	d1, err = DecodeDeferredCausetValue(bs, tp, sc.TimeZone)
   181  	c.Assert(err, IsNil)
   182  	cmp, err = d1.CompareCauset(sc, &d)
   183  	c.Assert(err, IsNil)
   184  	c.Assert(cmp, Equals, 0)
   185  
   186  	// test bit
   187  	d = types.NewMysqlBitCauset(types.NewBinaryLiteralFromUint(3223600, 3))
   188  	bs, err = EncodeOldRow(sc, []types.Causet{d}, []int64{1}, nil, nil)
   189  	c.Assert(err, IsNil)
   190  	c.Assert(bs, NotNil)
   191  	_, bs, err = codec.CutOne(bs) // ignore colID
   192  	c.Assert(err, IsNil)
   193  	tp = types.NewFieldType(allegrosql.TypeBit)
   194  	tp.Flen = 24
   195  	d1, err = DecodeDeferredCausetValue(bs, tp, sc.TimeZone)
   196  	c.Assert(err, IsNil)
   197  	cmp, err = d1.CompareCauset(sc, &d)
   198  	c.Assert(err, IsNil)
   199  	c.Assert(cmp, Equals, 0)
   200  
   201  	// test empty enum
   202  	d = types.NewMysqlEnumCauset(types.Enum{})
   203  	bs, err = EncodeOldRow(sc, []types.Causet{d}, []int64{1}, nil, nil)
   204  	c.Assert(err, IsNil)
   205  	c.Assert(bs, NotNil)
   206  	_, bs, err = codec.CutOne(bs) // ignore colID
   207  	c.Assert(err, IsNil)
   208  	tp = types.NewFieldType(allegrosql.TypeEnum)
   209  	d1, err = DecodeDeferredCausetValue(bs, tp, sc.TimeZone)
   210  	c.Assert(err, IsNil)
   211  	cmp, err = d1.CompareCauset(sc, &d)
   212  	c.Assert(err, IsNil)
   213  	c.Assert(cmp, Equals, 0)
   214  }
   215  
   216  func (s *testTableCodecSuite) TestUnflattenCausets(c *C) {
   217  	sc := &stmtctx.StatementContext{TimeZone: time.UTC}
   218  	input := types.MakeCausets(int64(1))
   219  	tps := []*types.FieldType{types.NewFieldType(allegrosql.TypeLonglong)}
   220  	output, err := UnflattenCausets(input, tps, sc.TimeZone)
   221  	c.Assert(err, IsNil)
   222  	cmp, err := input[0].CompareCauset(sc, &output[0])
   223  	c.Assert(err, IsNil)
   224  	c.Assert(cmp, Equals, 0)
   225  }
   226  
   227  func (s *testTableCodecSuite) TestTimeCodec(c *C) {
   228  	defer testleak.AfterTest(c)()
   229  
   230  	c1 := &column{id: 1, tp: types.NewFieldType(allegrosql.TypeLonglong)}
   231  	c2 := &column{id: 2, tp: types.NewFieldType(allegrosql.TypeVarchar)}
   232  	c3 := &column{id: 3, tp: types.NewFieldType(allegrosql.TypeTimestamp)}
   233  	c4 := &column{id: 4, tp: types.NewFieldType(allegrosql.TypeDuration)}
   234  	defcaus := []*column{c1, c2, c3, c4}
   235  	colLen := len(defcaus)
   236  
   237  	event := make([]types.Causet, colLen)
   238  	event[0] = types.NewIntCauset(100)
   239  	event[1] = types.NewBytesCauset([]byte("abc"))
   240  	ts, err := types.ParseTimestamp(&stmtctx.StatementContext{TimeZone: time.UTC},
   241  		"2020-06-23 11:30:45")
   242  	c.Assert(err, IsNil)
   243  	event[2] = types.NewCauset(ts)
   244  	du, err := types.ParseDuration(nil, "12:59:59.999999", 6)
   245  	c.Assert(err, IsNil)
   246  	event[3] = types.NewCauset(du)
   247  
   248  	// Encode
   249  	colIDs := make([]int64, 0, colLen)
   250  	for _, col := range defcaus {
   251  		colIDs = append(colIDs, col.id)
   252  	}
   253  	rd := rowcodec.CausetEncoder{Enable: true}
   254  	sc := &stmtctx.StatementContext{TimeZone: time.UTC}
   255  	bs, err := EncodeRow(sc, event, colIDs, nil, nil, &rd)
   256  	c.Assert(err, IsNil)
   257  	c.Assert(bs, NotNil)
   258  
   259  	// Decode
   260  	colMap := make(map[int64]*types.FieldType, colLen)
   261  	for _, col := range defcaus {
   262  		colMap[col.id] = col.tp
   263  	}
   264  	r, err := DecodeRowToCausetMap(bs, colMap, time.UTC)
   265  	c.Assert(err, IsNil)
   266  	c.Assert(r, NotNil)
   267  	c.Assert(r, HasLen, colLen)
   268  	// Compare decoded event and original event
   269  	for i, col := range defcaus {
   270  		v, ok := r[col.id]
   271  		c.Assert(ok, IsTrue)
   272  		equal, err1 := v.CompareCauset(sc, &event[i])
   273  		c.Assert(err1, IsNil)
   274  		c.Assert(equal, Equals, 0)
   275  	}
   276  }
   277  
   278  func (s *testTableCodecSuite) TestCutRow(c *C) {
   279  	defer testleak.AfterTest(c)()
   280  
   281  	var err error
   282  	c1 := &column{id: 1, tp: types.NewFieldType(allegrosql.TypeLonglong)}
   283  	c2 := &column{id: 2, tp: types.NewFieldType(allegrosql.TypeVarchar)}
   284  	c3 := &column{id: 3, tp: types.NewFieldType(allegrosql.TypeNewDecimal)}
   285  	defcaus := []*column{c1, c2, c3}
   286  
   287  	event := make([]types.Causet, 3)
   288  	event[0] = types.NewIntCauset(100)
   289  	event[1] = types.NewBytesCauset([]byte("abc"))
   290  	event[2] = types.NewDecimalCauset(types.NewDecFromInt(1))
   291  
   292  	sc := &stmtctx.StatementContext{TimeZone: time.UTC}
   293  	data := make([][]byte, 3)
   294  	data[0], err = EncodeValue(sc, nil, event[0])
   295  	c.Assert(err, IsNil)
   296  	data[1], err = EncodeValue(sc, nil, event[1])
   297  	c.Assert(err, IsNil)
   298  	data[2], err = EncodeValue(sc, nil, event[2])
   299  	c.Assert(err, IsNil)
   300  	// Encode
   301  	colIDs := make([]int64, 0, 3)
   302  	for _, col := range defcaus {
   303  		colIDs = append(colIDs, col.id)
   304  	}
   305  	bs, err := EncodeOldRow(sc, event, colIDs, nil, nil)
   306  	c.Assert(err, IsNil)
   307  	c.Assert(bs, NotNil)
   308  
   309  	// Decode
   310  	colMap := make(map[int64]int, 3)
   311  	for i, col := range defcaus {
   312  		colMap[col.id] = i
   313  	}
   314  	r, err := CutRowNew(bs, colMap)
   315  	c.Assert(err, IsNil)
   316  	c.Assert(r, NotNil)
   317  	c.Assert(r, HasLen, 3)
   318  	// Compare cut event and original event
   319  	for i := range colIDs {
   320  		c.Assert(r[i], DeepEquals, data[i])
   321  	}
   322  	bs = []byte{codec.NilFlag}
   323  	r, err = CutRowNew(bs, colMap)
   324  	c.Assert(err, IsNil)
   325  	c.Assert(r, IsNil)
   326  	bs = nil
   327  	r, err = CutRowNew(bs, colMap)
   328  	c.Assert(err, IsNil)
   329  	c.Assert(r, IsNil)
   330  }
   331  
   332  func (s *testTableCodecSuite) TestCutKeyNew(c *C) {
   333  	values := []types.Causet{types.NewIntCauset(1), types.NewBytesCauset([]byte("abc")), types.NewFloat64Causet(5.5)}
   334  	handle := types.NewIntCauset(100)
   335  	values = append(values, handle)
   336  	sc := &stmtctx.StatementContext{TimeZone: time.UTC}
   337  	encodedValue, err := codec.EncodeKey(sc, nil, values...)
   338  	c.Assert(err, IsNil)
   339  	blockID := int64(4)
   340  	indexID := int64(5)
   341  	indexKey := EncodeIndexSeekKey(blockID, indexID, encodedValue)
   342  	valuesBytes, handleBytes, err := CutIndexKeyNew(indexKey, 3)
   343  	c.Assert(err, IsNil)
   344  	for i := 0; i < 3; i++ {
   345  		valueBytes := valuesBytes[i]
   346  		var val types.Causet
   347  		_, val, _ = codec.DecodeOne(valueBytes)
   348  		c.Assert(val, DeepEquals, values[i])
   349  	}
   350  	_, handleVal, _ := codec.DecodeOne(handleBytes)
   351  	c.Assert(handleVal, DeepEquals, types.NewIntCauset(100))
   352  }
   353  
   354  func (s *testTableCodecSuite) TestCutKey(c *C) {
   355  	colIDs := []int64{1, 2, 3}
   356  	values := []types.Causet{types.NewIntCauset(1), types.NewBytesCauset([]byte("abc")), types.NewFloat64Causet(5.5)}
   357  	handle := types.NewIntCauset(100)
   358  	values = append(values, handle)
   359  	sc := &stmtctx.StatementContext{TimeZone: time.UTC}
   360  	encodedValue, err := codec.EncodeKey(sc, nil, values...)
   361  	c.Assert(err, IsNil)
   362  	blockID := int64(4)
   363  	indexID := int64(5)
   364  	indexKey := EncodeIndexSeekKey(blockID, indexID, encodedValue)
   365  	valuesMap, handleBytes, err := CutIndexKey(indexKey, colIDs)
   366  	c.Assert(err, IsNil)
   367  	for i, colID := range colIDs {
   368  		valueBytes := valuesMap[colID]
   369  		var val types.Causet
   370  		_, val, _ = codec.DecodeOne(valueBytes)
   371  		c.Assert(val, DeepEquals, values[i])
   372  	}
   373  	_, handleVal, _ := codec.DecodeOne(handleBytes)
   374  	c.Assert(handleVal, DeepEquals, types.NewIntCauset(100))
   375  }
   376  
   377  func (s *testTableCodecSuite) TestDecodeBadDecical(c *C) {
   378  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/soliton/codec/errorInDecodeDecimal", `return(true)`), IsNil)
   379  	defer func() {
   380  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/soliton/codec/errorInDecodeDecimal"), IsNil)
   381  	}()
   382  	dec := types.NewDecFromStringForTest("0.111")
   383  	b, err := codec.EncodeDecimal(nil, dec, 0, 0)
   384  	c.Assert(err, IsNil)
   385  	// Expect no panic.
   386  	_, _, err = codec.DecodeOne(b)
   387  	c.Assert(err, NotNil)
   388  }
   389  
   390  func (s *testTableCodecSuite) TestIndexKey(c *C) {
   391  	blockID := int64(4)
   392  	indexID := int64(5)
   393  	indexKey := EncodeIndexSeekKey(blockID, indexID, []byte{})
   394  	tTableID, tIndexID, isRecordKey, err := DecodeKeyHead(indexKey)
   395  	c.Assert(err, IsNil)
   396  	c.Assert(tTableID, Equals, blockID)
   397  	c.Assert(tIndexID, Equals, indexID)
   398  	c.Assert(isRecordKey, IsFalse)
   399  }
   400  
   401  func (s *testTableCodecSuite) TestRecordKey(c *C) {
   402  	blockID := int64(55)
   403  	blockKey := EncodeRowKeyWithHandle(blockID, ekv.IntHandle(math.MaxUint32))
   404  	tTableID, _, isRecordKey, err := DecodeKeyHead(blockKey)
   405  	c.Assert(err, IsNil)
   406  	c.Assert(tTableID, Equals, blockID)
   407  	c.Assert(isRecordKey, IsTrue)
   408  
   409  	encodedHandle := codec.EncodeInt(nil, math.MaxUint32)
   410  	rowKey := EncodeRowKey(blockID, encodedHandle)
   411  	c.Assert([]byte(blockKey), BytesEquals, []byte(rowKey))
   412  	tTableID, handle, err := DecodeRecordKey(rowKey)
   413  	c.Assert(err, IsNil)
   414  	c.Assert(tTableID, Equals, blockID)
   415  	c.Assert(handle.IntValue(), Equals, int64(math.MaxUint32))
   416  
   417  	recordPrefix := GenTableRecordPrefix(blockID)
   418  	rowKey = EncodeRecordKey(recordPrefix, ekv.IntHandle(math.MaxUint32))
   419  	c.Assert([]byte(blockKey), BytesEquals, []byte(rowKey))
   420  
   421  	_, _, err = DecodeRecordKey(nil)
   422  	c.Assert(err, NotNil)
   423  	_, _, err = DecodeRecordKey([]byte("abcdefghijklmnopqrstuvwxyz"))
   424  	c.Assert(err, NotNil)
   425  	c.Assert(DecodeTableID(nil), Equals, int64(0))
   426  }
   427  
   428  func (s *testTableCodecSuite) TestPrefix(c *C) {
   429  	const blockID int64 = 66
   430  	key := EncodeTablePrefix(blockID)
   431  	tTableID := DecodeTableID(key)
   432  	c.Assert(tTableID, Equals, blockID)
   433  
   434  	c.Assert(TablePrefix(), BytesEquals, blockPrefix)
   435  
   436  	blockPrefix1 := GenTablePrefix(blockID)
   437  	c.Assert([]byte(blockPrefix1), BytesEquals, []byte(key))
   438  
   439  	indexPrefix := EncodeTableIndexPrefix(blockID, math.MaxUint32)
   440  	tTableID, indexID, isRecordKey, err := DecodeKeyHead(indexPrefix)
   441  	c.Assert(err, IsNil)
   442  	c.Assert(tTableID, Equals, blockID)
   443  	c.Assert(indexID, Equals, int64(math.MaxUint32))
   444  	c.Assert(isRecordKey, IsFalse)
   445  
   446  	prefixKey := GenTableIndexPrefix(blockID)
   447  	c.Assert(DecodeTableID(prefixKey), Equals, blockID)
   448  
   449  	c.Assert(TruncateToRowKeyLen(append(indexPrefix, "xyz"...)), HasLen, RecordRowKeyLen)
   450  	c.Assert(TruncateToRowKeyLen(key), HasLen, len(key))
   451  }
   452  
   453  func (s *testTableCodecSuite) TestDecodeIndexKey(c *C) {
   454  	blockID := int64(4)
   455  	indexID := int64(5)
   456  	values := []types.Causet{
   457  		types.NewIntCauset(1),
   458  		types.NewBytesCauset([]byte("abc")),
   459  		types.NewFloat64Causet(123.45),
   460  		// MysqlTime is not supported.
   461  		// types.NewTimeCauset(types.Time{
   462  		// 	Time: types.FromGoTime(time.Now()),
   463  		// 	Fsp:  6,
   464  		// 	Type: allegrosql.TypeTimestamp,
   465  		// }),
   466  	}
   467  	valueStrs := make([]string, 0, len(values))
   468  	for _, v := range values {
   469  		str, err := v.ToString()
   470  		if err != nil {
   471  			str = fmt.Sprintf("%d-%v", v.HoTT(), v.GetValue())
   472  		}
   473  		valueStrs = append(valueStrs, str)
   474  	}
   475  	sc := &stmtctx.StatementContext{TimeZone: time.UTC}
   476  	encodedValue, err := codec.EncodeKey(sc, nil, values...)
   477  	c.Assert(err, IsNil)
   478  	indexKey := EncodeIndexSeekKey(blockID, indexID, encodedValue)
   479  
   480  	decodeTableID, decodeIndexID, decodeValues, err := DecodeIndexKey(indexKey)
   481  	c.Assert(err, IsNil)
   482  	c.Assert(decodeTableID, Equals, blockID)
   483  	c.Assert(decodeIndexID, Equals, indexID)
   484  	c.Assert(decodeValues, DeepEquals, valueStrs)
   485  }
   486  
   487  func (s *testTableCodecSuite) TestCutPrefix(c *C) {
   488  	key := EncodeTableIndexPrefix(42, 666)
   489  	res := CutRowKeyPrefix(key)
   490  	c.Assert(res, BytesEquals, []byte{0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x9a})
   491  	res = CutIndexPrefix(key)
   492  	c.Assert(res, BytesEquals, []byte{})
   493  }
   494  
   495  func (s *testTableCodecSuite) TestRange(c *C) {
   496  	s1, e1 := GetTableHandleKeyRange(22)
   497  	s2, e2 := GetTableHandleKeyRange(23)
   498  	c.Assert(s1, Less, e1)
   499  	c.Assert(e1, Less, s2)
   500  	c.Assert(s2, Less, e2)
   501  
   502  	s1, e1 = GetTableIndexKeyRange(42, 666)
   503  	s2, e2 = GetTableIndexKeyRange(42, 667)
   504  	c.Assert(s1, Less, e1)
   505  	c.Assert(e1, Less, s2)
   506  	c.Assert(s2, Less, e2)
   507  }
   508  
   509  func (s *testTableCodecSuite) TestDecodeAutoIDMeta(c *C) {
   510  	keyBytes := []byte{0x6d, 0x44, 0x42, 0x3a, 0x35, 0x36, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0x54, 0x49, 0x44, 0x3a, 0x31, 0x30, 0x38, 0x0, 0xfe}
   511  	key, field, err := DecodeMetaKey(keyBytes)
   512  	c.Assert(err, IsNil)
   513  	c.Assert(string(key), Equals, "EDB:56")
   514  	c.Assert(string(field), Equals, "TID:108")
   515  }
   516  
   517  func BenchmarkHasTablePrefix(b *testing.B) {
   518  	k := ekv.Key("foobar")
   519  	for i := 0; i < b.N; i++ {
   520  		hasTablePrefix(k)
   521  	}
   522  }
   523  
   524  func BenchmarkHasTablePrefixBuiltin(b *testing.B) {
   525  	k := ekv.Key("foobar")
   526  	for i := 0; i < b.N; i++ {
   527  		k.HasPrefix(blockPrefix)
   528  	}
   529  }
   530  
   531  // Bench result:
   532  // BenchmarkEncodeValue      5000000           368 ns/op
   533  func BenchmarkEncodeValue(b *testing.B) {
   534  	event := make([]types.Causet, 7)
   535  	event[0] = types.NewIntCauset(100)
   536  	event[1] = types.NewBytesCauset([]byte("abc"))
   537  	event[2] = types.NewDecimalCauset(types.NewDecFromInt(1))
   538  	event[3] = types.NewMysqlEnumCauset(types.Enum{Name: "a", Value: 0})
   539  	event[4] = types.NewCauset(types.Set{Name: "a", Value: 0})
   540  	event[5] = types.NewCauset(types.BinaryLiteral{100})
   541  	event[6] = types.NewFloat32Causet(1.5)
   542  	b.ResetTimer()
   543  	encodedDefCaus := make([]byte, 0, 16)
   544  	for i := 0; i < b.N; i++ {
   545  		for _, d := range event {
   546  			encodedDefCaus = encodedDefCaus[:0]
   547  			EncodeValue(nil, encodedDefCaus, d)
   548  		}
   549  	}
   550  }
   551  
   552  func (s *testTableCodecSuite) TestError(c *C) {
   553  	ekvErrs := []*terror.Error{
   554  		errInvalidKey,
   555  		errInvalidRecordKey,
   556  		errInvalidIndexKey,
   557  	}
   558  	for _, err := range ekvErrs {
   559  		code := terror.ToALLEGROSQLError(err).Code
   560  		c.Assert(code != allegrosql.ErrUnknown && code == uint16(err.Code()), IsTrue, Commentf("err: %v", err))
   561  	}
   562  }