From 61ae9038bd6fec4370aaae9fda62567918f82b98 Mon Sep 17 00:00:00 2001 From: Ziqian Qin Date: Wed, 23 Feb 2022 16:57:43 +0800 Subject: [PATCH] cherry pick #32372 to release-5.1 Signed-off-by: ti-srebot --- util/codec/codec.go | 69 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/util/codec/codec.go b/util/codec/codec.go index 4d16470d56537..3affcd8d258ae 100644 --- a/util/codec/codec.go +++ b/util/codec/codec.go @@ -156,9 +156,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)) @@ -352,11 +352,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. @@ -566,11 +566,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. @@ -1292,3 +1292,60 @@ func ConvertByCollationStr(str string, tp *types.FieldType) string { collator := collate.GetCollator(tp.Collate) return string(hack.String(collator.Key(str))) } +<<<<<<< HEAD +======= + +// HashCode encodes a Datum into a unique byte slice. +// It is mostly the same as EncodeValue, but it doesn't contain truncation or verification logic in order +// to make the encoding lossless. +func HashCode(b []byte, d types.Datum) []byte { + switch d.Kind() { + case types.KindInt64: + b = encodeSignedInt(b, d.GetInt64(), false) + case types.KindUint64: + b = encodeUnsignedInt(b, d.GetUint64(), false) + case types.KindFloat32, types.KindFloat64: + b = append(b, floatFlag) + b = EncodeFloat(b, d.GetFloat64()) + case types.KindString: + b = encodeString(b, d, false) + case types.KindBytes: + b = encodeBytes(b, d.GetBytes(), false) + case types.KindMysqlTime: + b = append(b, uintFlag) + t := d.GetMysqlTime().CoreTime() + b = encodeUnsignedInt(b, uint64(t), true) + case types.KindMysqlDuration: + // duration may have negative value, so we cannot use String to encode directly. + b = append(b, durationFlag) + b = EncodeInt(b, int64(d.GetMysqlDuration().Duration)) + case types.KindMysqlDecimal: + b = append(b, decimalFlag) + decStr := d.GetMysqlDecimal().ToString() + b = encodeBytes(b, decStr, false) + case types.KindMysqlEnum: + b = encodeUnsignedInt(b, d.GetMysqlEnum().Value, false) + case types.KindMysqlSet: + b = encodeUnsignedInt(b, d.GetMysqlSet().Value, false) + case types.KindMysqlBit, types.KindBinaryLiteral: + val := d.GetBinaryLiteral() + b = encodeBytes(b, val, false) + case types.KindMysqlJSON: + b = append(b, jsonFlag) + j := d.GetMysqlJSON() + b = append(b, j.TypeCode) + b = append(b, j.Value...) + case types.KindNull: + b = append(b, NilFlag) + case types.KindMinNotNull: + b = append(b, bytesFlag) + case types.KindMaxValue: + b = append(b, maxFlag) + default: + logutil.BgLogger().Warn("trying to calculate HashCode of an unexpected type of Datum", + zap.Uint8("Datum Kind", d.Kind()), + zap.Stack("stack")) + } + return b +} +>>>>>>> cc789d078... codec: Don't convert set or enum datum to float64 (#32372)