@@ -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.
4978func (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