encode will encode a datum and append it to a byte slice. If comparable1 is true, the encoded bytes can be sorted as it's original order. If hash is true, the encoded bytes can be checked equal as it's original value.
(loc *time.Location, b []byte, vals []types.Datum, comparable1 bool)
| 89 | // encode will encode a datum and append it to a byte slice. If comparable1 is true, the encoded bytes can be sorted as it's original order. |
| 90 | // If hash is true, the encoded bytes can be checked equal as it's original value. |
| 91 | func encode(loc *time.Location, b []byte, vals []types.Datum, comparable1 bool) (_ []byte, err error) { |
| 92 | b = preRealloc(b, vals, comparable1) |
| 93 | for i, length := 0, len(vals); i < length; i++ { |
| 94 | switch vals[i].Kind() { |
| 95 | case types.KindInt64: |
| 96 | b = encodeSignedInt(b, vals[i].GetInt64(), comparable1) |
| 97 | case types.KindUint64: |
| 98 | b = encodeUnsignedInt(b, vals[i].GetUint64(), comparable1) |
| 99 | case types.KindFloat32, types.KindFloat64: |
| 100 | b = append(b, floatFlag) |
| 101 | b = EncodeFloat(b, vals[i].GetFloat64()) |
| 102 | case types.KindString: |
| 103 | b = encodeString(b, vals[i], comparable1) |
| 104 | case types.KindBytes: |
| 105 | b = encodeBytes(b, vals[i].GetBytes(), comparable1) |
| 106 | case types.KindMysqlTime: |
| 107 | b = append(b, uintFlag) |
| 108 | b, err = EncodeMySQLTime(loc, vals[i].GetMysqlTime(), mysql.TypeUnspecified, b) |
| 109 | if err != nil { |
| 110 | return b, err |
| 111 | } |
| 112 | case types.KindMysqlDuration: |
| 113 | // duration may have negative value, so we cannot use String to encode directly. |
| 114 | b = append(b, durationFlag) |
| 115 | b = EncodeInt(b, int64(vals[i].GetMysqlDuration().Duration)) |
| 116 | case types.KindMysqlDecimal: |
| 117 | b = append(b, decimalFlag) |
| 118 | b, err = EncodeDecimal(b, vals[i].GetMysqlDecimal(), vals[i].Length(), vals[i].Frac()) |
| 119 | case types.KindMysqlEnum: |
| 120 | b = encodeUnsignedInt(b, vals[i].GetMysqlEnum().Value, comparable1) |
| 121 | case types.KindMysqlSet: |
| 122 | b = encodeUnsignedInt(b, vals[i].GetMysqlSet().Value, comparable1) |
| 123 | case types.KindMysqlBit, types.KindBinaryLiteral: |
| 124 | // We don't need to handle errors here since the literal is ensured to be able to store in uint64 in convertToMysqlBit. |
| 125 | var val uint64 |
| 126 | val, err = vals[i].GetBinaryLiteral().ToInt(types.StrictContext) |
| 127 | terror.Log(errors.Trace(err)) |
| 128 | b = encodeUnsignedInt(b, val, comparable1) |
| 129 | case types.KindMysqlJSON: |
| 130 | b = append(b, jsonFlag) |
| 131 | j := vals[i].GetMysqlJSON() |
| 132 | b = append(b, j.TypeCode) |
| 133 | b = append(b, j.Value...) |
| 134 | case types.KindVectorFloat32: |
| 135 | // Always do a small deser + ser for sanity check |
| 136 | b = append(b, vectorFloat32Flag) |
| 137 | v := vals[i].GetVectorFloat32() |
| 138 | b = v.SerializeTo(b) |
| 139 | case types.KindNull: |
| 140 | b = append(b, NilFlag) |
| 141 | case types.KindMinNotNull: |
| 142 | b = append(b, bytesFlag) |
| 143 | case types.KindMaxValue: |
| 144 | b = append(b, maxFlag) |
| 145 | default: |
| 146 | return b, errors.Errorf("unsupport encode type %d", vals[i].Kind()) |
| 147 | } |
| 148 | } |