json: add uint64 support. (#3648)
This commit is contained in:
@ -1239,9 +1239,12 @@ func (d *Datum) convertToMysqlJSON(sc *variable.StatementContext, target *FieldT
|
||||
if j, err = json.ParseFromString(d.GetString()); err == nil {
|
||||
ret.SetMysqlJSON(j)
|
||||
}
|
||||
case KindInt64, KindUint64:
|
||||
case KindInt64:
|
||||
i64 := d.GetInt64()
|
||||
ret.SetMysqlJSON(json.CreateJSON(i64))
|
||||
case KindUint64:
|
||||
u64 := d.GetUint64()
|
||||
ret.SetMysqlJSON(json.CreateJSON(u64))
|
||||
case KindFloat32, KindFloat64:
|
||||
f64 := d.GetFloat64()
|
||||
ret.SetMysqlJSON(json.CreateJSON(f64))
|
||||
@ -1521,8 +1524,10 @@ func (d *Datum) ToMysqlJSON() (j json.JSON, err error) {
|
||||
case KindMysqlJSON:
|
||||
j = d.x.(json.JSON)
|
||||
return
|
||||
case KindInt64, KindUint64:
|
||||
case KindInt64:
|
||||
in = d.GetInt64()
|
||||
case KindUint64:
|
||||
in = d.GetUint64()
|
||||
case KindFloat32, KindFloat64:
|
||||
in = d.GetFloat64()
|
||||
case KindMysqlDecimal:
|
||||
|
||||
@ -39,25 +39,29 @@ func compareFloat64PrecisionLoss(x, y float64) int {
|
||||
// jsonTypePrecedences is for comparing two json.
|
||||
// See: https://dev.mysql.com/doc/refman/5.7/en/json.html#json-comparison
|
||||
var jsonTypePrecedences = map[string]int{
|
||||
"BLOB": -1,
|
||||
"BIT": -2,
|
||||
"OPAQUE": -3,
|
||||
"DATETIME": -4,
|
||||
"TIME": -5,
|
||||
"DATE": -6,
|
||||
"BOOLEAN": -7,
|
||||
"ARRAY": -8,
|
||||
"OBJECT": -9,
|
||||
"STRING": -10,
|
||||
"INTEGER": -11,
|
||||
"DOUBLE": -11,
|
||||
"NULL": -12,
|
||||
"BLOB": -1,
|
||||
"BIT": -2,
|
||||
"OPAQUE": -3,
|
||||
"DATETIME": -4,
|
||||
"TIME": -5,
|
||||
"DATE": -6,
|
||||
"BOOLEAN": -7,
|
||||
"ARRAY": -8,
|
||||
"OBJECT": -9,
|
||||
"STRING": -10,
|
||||
"INTEGER": -11,
|
||||
"UNSIGNED INTEGER": -11,
|
||||
"DOUBLE": -11,
|
||||
"NULL": -12,
|
||||
}
|
||||
|
||||
func i64AsFloat64(i64 int64, typeCode TypeCode) float64 {
|
||||
switch typeCode {
|
||||
case typeCodeLiteral, typeCodeInt64:
|
||||
return float64(i64)
|
||||
case typeCodeUint64:
|
||||
u64 := *(*uint64)(unsafe.Pointer(&i64))
|
||||
return float64(u64)
|
||||
case typeCodeFloat64:
|
||||
return *(*float64)(unsafe.Pointer(&i64))
|
||||
default:
|
||||
|
||||
@ -40,6 +40,8 @@ func (j JSON) Type() string {
|
||||
}
|
||||
case typeCodeInt64:
|
||||
return "INTEGER"
|
||||
case typeCodeUint64:
|
||||
return "UNSIGNED INTEGER"
|
||||
case typeCodeFloat64:
|
||||
return "DOUBLE"
|
||||
case typeCodeString:
|
||||
|
||||
@ -35,6 +35,9 @@ func (s *testJSONSuite) TestJSONType(c *C) {
|
||||
j := mustParseFromString(tt.In)
|
||||
c.Assert(j.Type(), Equals, tt.Out)
|
||||
}
|
||||
// we can't parse '9223372036854775808' to JSON::Uint64 now,
|
||||
// because go builtin JSON parser treats that as DOUBLE.
|
||||
c.Assert(CreateJSON(uint64(1<<63)).Type(), Equals, "UNSIGNED INTEGER")
|
||||
}
|
||||
|
||||
func (s *testJSONSuite) TestJSONExtract(c *C) {
|
||||
|
||||
@ -33,6 +33,7 @@ const (
|
||||
typeCodeArray TypeCode = 0x03
|
||||
typeCodeLiteral TypeCode = 0x04
|
||||
typeCodeInt64 TypeCode = 0x09
|
||||
typeCodeUint64 TypeCode = 0x0a
|
||||
typeCodeFloat64 TypeCode = 0x0b
|
||||
typeCodeString TypeCode = 0x0c
|
||||
)
|
||||
@ -96,6 +97,9 @@ func (j JSON) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
case typeCodeInt64:
|
||||
return json.Marshal(j.i64)
|
||||
case typeCodeUint64:
|
||||
u64 := *(*uint64)(unsafe.Pointer(&j.i64))
|
||||
return json.Marshal(u64)
|
||||
case typeCodeFloat64:
|
||||
f64 := *(*float64)(unsafe.Pointer(&j.i64))
|
||||
return json.Marshal(f64)
|
||||
|
||||
@ -48,6 +48,7 @@ func (s *testJSONSuite) TestParseFromString(c *C) {
|
||||
func (s *testJSONSuite) TestSerializeAndDeserialize(c *C) {
|
||||
var jsonNilValue = CreateJSON(nil)
|
||||
var jsonBoolValue = CreateJSON(true)
|
||||
var jsonUintValue = CreateJSON(uint64(1 << 63))
|
||||
var jsonDoubleValue = CreateJSON(3.24)
|
||||
var jsonStringValue = CreateJSON("hello, 世界")
|
||||
j1 := mustParseFromString(`{"aaaaaaaaaaa": [1, "2", {"aa": "bb"}, 4.0], "bbbbbbbbbb": true, "ccccccccc": "d"}`)
|
||||
@ -60,6 +61,7 @@ func (s *testJSONSuite) TestSerializeAndDeserialize(c *C) {
|
||||
}{
|
||||
{In: jsonNilValue, Out: jsonNilValue, size: 2},
|
||||
{In: jsonBoolValue, Out: jsonBoolValue, size: 2},
|
||||
{In: jsonUintValue, Out: jsonUintValue, size: 9},
|
||||
{In: jsonDoubleValue, Out: jsonDoubleValue, size: 9},
|
||||
{In: jsonStringValue, Out: jsonStringValue, size: 15},
|
||||
{In: j1, Out: j1, size: 144},
|
||||
@ -86,7 +88,7 @@ func (s *testJSONSuite) TestCompareJSON(c *C) {
|
||||
jNull := mustParseFromString(`null`)
|
||||
jBoolTrue := mustParseFromString(`true`)
|
||||
jBoolFalse := mustParseFromString(`false`)
|
||||
jIntegerLarge := mustParseFromString(`5`)
|
||||
jIntegerLarge := CreateJSON(uint64(1 << 63))
|
||||
jIntegerSmall := mustParseFromString(`3`)
|
||||
jStringLarge := mustParseFromString(`"hello, world"`)
|
||||
jStringSmall := mustParseFromString(`"hello"`)
|
||||
|
||||
@ -37,6 +37,9 @@ func normalize(in interface{}) (j JSON, err error) {
|
||||
case int64:
|
||||
j.typeCode = typeCodeInt64
|
||||
j.i64 = t
|
||||
case uint64:
|
||||
j.typeCode = typeCodeUint64
|
||||
j.i64 = *(*int64)(unsafe.Pointer(&t))
|
||||
case float64:
|
||||
j.typeCode = typeCodeFloat64
|
||||
*(*float64)(unsafe.Pointer(&j.i64)) = t
|
||||
|
||||
@ -127,7 +127,7 @@ func PeekBytesAsJSON(b []byte) (n int, err error) {
|
||||
n = int(size) + int(reader.Size()) - int(reader.Len()) + typeCodeLen
|
||||
return
|
||||
}
|
||||
case typeCodeInt64, typeCodeFloat64, typeCodeLiteral:
|
||||
case typeCodeInt64, typeCodeUint64, typeCodeFloat64, typeCodeLiteral:
|
||||
n = jsonTypeCodeLength[TypeCode(c)] + typeCodeLen
|
||||
return
|
||||
}
|
||||
@ -151,7 +151,7 @@ func encode(j JSON, buffer *bytes.Buffer) {
|
||||
encodeJSONArray(j.array, buffer)
|
||||
case typeCodeLiteral:
|
||||
encodeJSONLiteral(byte(j.i64), buffer)
|
||||
case typeCodeInt64:
|
||||
case typeCodeInt64, typeCodeUint64:
|
||||
encodeJSONInt64(j.i64, buffer)
|
||||
case typeCodeFloat64:
|
||||
f64 := *(*float64)(unsafe.Pointer(&j.i64))
|
||||
@ -179,7 +179,7 @@ func decode(typeCode byte, data []byte) (j JSON, err error) {
|
||||
case typeCodeLiteral:
|
||||
pbyte := (*byte)(unsafe.Pointer(&j.i64))
|
||||
err = decodeJSONLiteral(pbyte, data)
|
||||
case typeCodeInt64:
|
||||
case typeCodeInt64, typeCodeUint64:
|
||||
err = decodeJSONInt64(&j.i64, data)
|
||||
case typeCodeFloat64:
|
||||
pfloat := (*float64)(unsafe.Pointer(&j.i64))
|
||||
@ -388,6 +388,7 @@ var jsonTypeCodeLength = map[TypeCode]int{
|
||||
typeCodeArray: -1,
|
||||
typeCodeLiteral: 1,
|
||||
typeCodeInt64: 8,
|
||||
typeCodeUint64: 8,
|
||||
typeCodeFloat64: 8,
|
||||
typeCodeString: -1,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user