Skip to content

Commit 1c26f64

Browse files
committed
add conv val func
1 parent 269719f commit 1c26f64

File tree

1 file changed

+37
-24
lines changed

1 file changed

+37
-24
lines changed

sql/types/json.go

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,43 +45,59 @@ func (t JsonType) Compare(ctx context.Context, a interface{}, b interface{}) (in
4545
return CompareJSON(ctx, a, b)
4646
}
4747

48+
func convertJSONValue(v interface{}) (interface{}, sql.ConvertInRange, error) {
49+
var data []byte
50+
51+
switch x := v.(type) {
52+
case []byte:
53+
data = x
54+
case string:
55+
charsetMaxLength := sql.Collation_Default.CharacterSet().MaxLength()
56+
length := int64(len(x)) * charsetMaxLength
57+
if length > MaxJsonFieldByteLength {
58+
return nil, sql.InRange, ErrLengthTooLarge.New(length, MaxJsonFieldByteLength)
59+
}
60+
data = []byte(x)
61+
default:
62+
return nil, sql.OutOfRange, sql.ErrInvalidJson.New("unsupported JSON input type")
63+
}
64+
65+
if int64(len(data)) > MaxJsonFieldByteLength {
66+
return nil, sql.InRange, ErrLengthTooLarge.New(len(data), MaxJsonFieldByteLength)
67+
}
68+
69+
var doc interface{}
70+
if err := json.Unmarshal(data, &doc); err != nil {
71+
return nil, sql.OutOfRange, sql.ErrInvalidJson.New(err.Error())
72+
}
73+
74+
return doc, sql.InRange, nil
75+
}
76+
4877
// Convert implements Type interface.
4978
func (t JsonType) Convert(c context.Context, v interface{}) (doc interface{}, inRange sql.ConvertInRange, err error) {
5079
switch v := v.(type) {
5180
case sql.JSONWrapper:
5281
return v, sql.InRange, nil
5382
case []byte:
54-
if int64(len(v)) > MaxJsonFieldByteLength {
55-
return nil, sql.InRange, ErrLengthTooLarge.New(len(v), MaxJsonFieldByteLength)
56-
}
57-
err = json.Unmarshal(v, &doc)
83+
doc, inRange, err = convertJSONValue(v)
5884
if err != nil {
59-
return nil, sql.OutOfRange, sql.ErrInvalidJson.New(err.Error())
85+
return nil, inRange, err
6086
}
6187
case string:
62-
charsetMaxLength := sql.Collation_Default.CharacterSet().MaxLength()
63-
length := int64(len(v)) * charsetMaxLength
64-
if length > MaxJsonFieldByteLength {
65-
return nil, sql.InRange, ErrLengthTooLarge.New(length, MaxJsonFieldByteLength)
66-
}
67-
err = json.Unmarshal([]byte(v), &doc)
88+
doc, inRange, err = convertJSONValue(v)
6889
if err != nil {
69-
return nil, sql.OutOfRange, sql.ErrInvalidJson.New(err.Error())
90+
return nil, inRange, err
7091
}
7192
// Text values may be stored in wrappers (e.g. Dolt's TextStorage), so unwrap to the raw string before decoding.
7293
case sql.StringWrapper:
7394
str, err := v.Unwrap(c)
7495
if err != nil {
7596
return nil, sql.OutOfRange, err
7697
}
77-
charsetMaxLength := sql.Collation_Default.CharacterSet().MaxLength()
78-
length := int64(len(str)) * charsetMaxLength
79-
if length > MaxJsonFieldByteLength {
80-
return nil, sql.InRange, ErrLengthTooLarge.New(length, MaxJsonFieldByteLength)
81-
}
82-
err = json.Unmarshal([]byte(str), &doc)
98+
doc, inRange, err = convertJSONValue(str)
8399
if err != nil {
84-
return nil, sql.OutOfRange, sql.ErrInvalidJson.New(err.Error())
100+
return nil, inRange, err
85101
}
86102
case int8:
87103
return JSONDocument{Val: int64(v)}, sql.InRange, nil
@@ -109,12 +125,9 @@ func (t JsonType) Convert(c context.Context, v interface{}) (doc interface{}, in
109125
// if |v| can be marshalled, it contains
110126
// a valid JSON document representation
111127
if b, berr := json.Marshal(v); berr == nil {
112-
if int64(len(b)) > MaxJsonFieldByteLength {
113-
return nil, sql.InRange, ErrLengthTooLarge.New(len(b), MaxJsonFieldByteLength)
114-
}
115-
err = json.Unmarshal(b, &doc)
128+
doc, inRange, err = convertJSONValue(b)
116129
if err != nil {
117-
return nil, sql.OutOfRange, sql.ErrInvalidJson.New(err.Error())
130+
return nil, inRange, err
118131
}
119132
}
120133
}

0 commit comments

Comments
 (0)