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 }