From cf3591f9269abc35a5f814515fbdc4caacfaa421 Mon Sep 17 00:00:00 2001 From: ti-srebot <66930949+ti-srebot@users.noreply.github.com> Date: Fri, 29 Apr 2022 11:04:52 +0800 Subject: [PATCH] codec: Don't convert set or enum datum to float64 when encoding them (#32308) (#32355) close pingcap/tidb#32302 --- executor/executor_test.go | 14 ++++++++++++++ util/codec/codec.go | 20 ++++++++++---------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/executor/executor_test.go b/executor/executor_test.go index 0ebc6d8c9a925..88dc938736ad1 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -9823,6 +9823,20 @@ func (s *testSerialSuite) TestIssue30971(c *C) { } } +func (s *testSerialSuite) TestEncodingSet(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("CREATE TABLE `enum-set` (`set` SET(" + + "'x00','x01','x02','x03','x04','x05','x06','x07','x08','x09','x10','x11','x12','x13','x14','x15'," + + "'x16','x17','x18','x19','x20','x21','x22','x23','x24','x25','x26','x27','x28','x29','x30','x31'," + + "'x32','x33','x34','x35','x36','x37','x38','x39','x40','x41','x42','x43','x44','x45','x46','x47'," + + "'x48','x49','x50','x51','x52','x53','x54','x55','x56','x57','x58','x59','x60','x61','x62','x63'" + + ")NOT NULL PRIMARY KEY)") + tk.MustExec("INSERT INTO `enum-set` VALUES\n(\"x00,x59\");") + tk.MustQuery("select `set` from `enum-set` use index(PRIMARY)").Check(testkit.Rows("x00,x59")) + tk.MustExec("admin check table `enum-set`") +} + func (s *testSuite) TestDeleteWithMulTbl(c *C) { tk := testkit.NewTestKit(c, s.store) diff --git a/util/codec/codec.go b/util/codec/codec.go index 454e9dd28a9c9..11d0b0b9283ba 100644 --- a/util/codec/codec.go +++ b/util/codec/codec.go @@ -116,9 +116,9 @@ func encode(sc *stmtctx.StatementContext, b []byte, vals []types.Datum, comparab err = sc.HandleOverflow(err, err) } case types.KindMysqlEnum: - b = encodeUnsignedInt(b, uint64(vals[i].GetMysqlEnum().ToNumber()), comparable) + b = encodeUnsignedInt(b, vals[i].GetMysqlEnum().Value, comparable) case types.KindMysqlSet: - b = encodeUnsignedInt(b, uint64(vals[i].GetMysqlSet().ToNumber()), comparable) + b = encodeUnsignedInt(b, vals[i].GetMysqlSet().Value, comparable) case types.KindMysqlBit, types.KindBinaryLiteral: // We don't need to handle errors here since the literal is ensured to be able to store in uint64 in convertToMysqlBit. var val uint64 @@ -159,9 +159,9 @@ func EstimateValueSize(sc *stmtctx.StatementContext, val types.Datum) (int, erro case types.KindMysqlDecimal: l = valueSizeOfDecimal(val.GetMysqlDecimal(), val.Length(), val.Frac()) + 1 case types.KindMysqlEnum: - l = valueSizeOfUnsignedInt(uint64(val.GetMysqlEnum().ToNumber())) + l = valueSizeOfUnsignedInt(val.GetMysqlEnum().Value) case types.KindMysqlSet: - l = valueSizeOfUnsignedInt(uint64(val.GetMysqlSet().ToNumber())) + l = valueSizeOfUnsignedInt(val.GetMysqlSet().Value) case types.KindMysqlBit, types.KindBinaryLiteral: val, err := val.GetBinaryLiteral().ToInt(sc) terror.Log(errors.Trace(err)) @@ -355,11 +355,11 @@ func encodeHashChunkRowIdx(sc *stmtctx.StatementContext, row chunk.Row, tp *type case mysql.TypeEnum: if mysql.HasEnumSetAsIntFlag(tp.Flag) { flag = uvarintFlag - v := uint64(row.GetEnum(idx).ToNumber()) + v := row.GetEnum(idx).Value b = (*[sizeUint64]byte)(unsafe.Pointer(&v))[:] } else { flag = compactBytesFlag - v := uint64(row.GetEnum(idx).ToNumber()) + v := row.GetEnum(idx).Value str := "" if enum, err := types.ParseEnumValue(tp.Elems, v); err == nil { // str will be empty string if v out of definition of enum. @@ -570,11 +570,11 @@ func HashChunkSelected(sc *stmtctx.StatementContext, h []hash.Hash64, chk *chunk isNull[i] = !ignoreNull } else if mysql.HasEnumSetAsIntFlag(tp.Flag) { buf[0] = uvarintFlag - v := uint64(column.GetEnum(i).ToNumber()) + v := column.GetEnum(i).Value b = (*[sizeUint64]byte)(unsafe.Pointer(&v))[:] } else { buf[0] = compactBytesFlag - v := uint64(column.GetEnum(i).ToNumber()) + v := column.GetEnum(i).Value str := "" if enum, err := types.ParseEnumValue(tp.Elems, v); err == nil { // str will be empty string if v out of definition of enum. @@ -1326,9 +1326,9 @@ func HashCode(b []byte, d types.Datum) []byte { decStr := d.GetMysqlDecimal().ToString() b = encodeBytes(b, decStr, false) case types.KindMysqlEnum: - b = encodeUnsignedInt(b, uint64(d.GetMysqlEnum().ToNumber()), false) + b = encodeUnsignedInt(b, d.GetMysqlEnum().Value, false) case types.KindMysqlSet: - b = encodeUnsignedInt(b, uint64(d.GetMysqlSet().ToNumber()), false) + b = encodeUnsignedInt(b, d.GetMysqlSet().Value, false) case types.KindMysqlBit, types.KindBinaryLiteral: val := d.GetBinaryLiteral() b = encodeBytes(b, val, false)