github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/types/json.go (about) 1 // Copyright 2021 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package types 16 17 import ( 18 "context" 19 "errors" 20 "fmt" 21 "strings" 22 23 "github.com/dolthub/dolt/go/store/d" 24 ) 25 26 type JSON struct { 27 valueImpl 28 } 29 30 // NewJSONDoc wraps |value| in a JSON value. 31 func NewJSONDoc(nbf *NomsBinFormat, vrw ValueReadWriter, value Value) (JSON, error) { 32 w := newBinaryNomsWriter() 33 if err := JSONKind.writeTo(&w, nbf); err != nil { 34 return EmptyJSONDoc(nbf), err 35 } 36 37 if err := value.writeTo(&w, nbf); err != nil { 38 return EmptyJSONDoc(nbf), err 39 } 40 41 return JSON{valueImpl{vrw, nbf, w.data(), nil}}, nil 42 } 43 44 // EmptyJSONDoc creates and empty JSON value. 45 func EmptyJSONDoc(nbf *NomsBinFormat) JSON { 46 w := newBinaryNomsWriter() 47 if err := JSONKind.writeTo(&w, nbf); err != nil { 48 d.PanicIfError(err) 49 } 50 51 return JSON{valueImpl{nil, nbf, w.data(), nil}} 52 } 53 54 // readJSON reads the data provided by a decoder and moves the decoder forward. 55 func readJSON(nbf *NomsBinFormat, dec *valueDecoder) (JSON, error) { 56 start := dec.pos() 57 58 k := dec.PeekKind() 59 if k == NullKind { 60 dec.skipKind() 61 return EmptyJSONDoc(nbf), nil 62 } 63 if k != JSONKind { 64 return JSON{}, errors.New("current value is not a JSON") 65 } 66 67 if err := skipJSON(nbf, dec); err != nil { 68 return JSON{}, err 69 } 70 71 end := dec.pos() 72 return JSON{valueImpl{dec.vrw, nbf, dec.byteSlice(start, end), nil}}, nil 73 } 74 75 func skipJSON(nbf *NomsBinFormat, dec *valueDecoder) error { 76 dec.skipKind() 77 return dec.SkipValue(nbf) 78 } 79 80 func walkJSON(nbf *NomsBinFormat, r *refWalker, cb RefCallback) error { 81 r.skipKind() 82 return r.walkValue(nbf, cb) 83 } 84 85 // CopyOf creates a copy of a JSON. This is necessary in cases where keeping a reference to the original JSON is 86 // preventing larger objects from being collected. 87 func (t JSON) CopyOf(vrw ValueReadWriter) JSON { 88 buff := make([]byte, len(t.buff)) 89 offsets := make([]uint32, len(t.offsets)) 90 91 copy(buff, t.buff) 92 copy(offsets, t.offsets) 93 94 return JSON{ 95 valueImpl{ 96 buff: buff, 97 offsets: offsets, 98 vrw: vrw, 99 nbf: t.nbf, 100 }, 101 } 102 } 103 104 // Empty implements the Emptyable interface. 105 func (t JSON) Empty() bool { 106 return t.Len() == 0 107 } 108 109 // Format returns this values NomsBinFormat. 110 func (t JSON) Format() *NomsBinFormat { 111 return t.format() 112 } 113 114 // Value implements the Value interface. 115 func (t JSON) Value(ctx context.Context) (Value, error) { 116 return t, nil 117 } 118 119 // Inner returns the JSON value's inner value. 120 func (t JSON) Inner() (Value, error) { 121 dec := newValueDecoder(t.buff, t.vrw) 122 dec.skipKind() 123 return dec.readValue(t.nbf) 124 } 125 126 // WalkValues implements the Value interface. 127 func (t JSON) WalkValues(ctx context.Context, cb ValueCallback) error { 128 val, err := t.Inner() 129 if err != nil { 130 return err 131 } 132 return val.WalkValues(ctx, cb) 133 } 134 135 // typeOf implements the Value interface. 136 func (t JSON) typeOf() (*Type, error) { 137 val, err := t.Inner() 138 if err != nil { 139 return nil, err 140 } 141 return val.typeOf() 142 } 143 144 // Kind implements the Valuable interface. 145 func (t JSON) Kind() NomsKind { 146 return JSONKind 147 } 148 149 func (t JSON) decoderSkipToFields() (valueDecoder, uint64) { 150 dec := t.decoder() 151 dec.skipKind() 152 return dec, uint64(1) 153 } 154 155 // Len implements the Value interface. 156 func (t JSON) Len() uint64 { 157 // TODO(andy): is this ever 0? 158 return 1 159 } 160 161 func (t JSON) isPrimitive() bool { 162 return false 163 } 164 165 // Less implements the LesserValuable interface. 166 func (t JSON) Less(nbf *NomsBinFormat, other LesserValuable) (bool, error) { 167 otherJSONDoc, ok := other.(JSON) 168 if !ok { 169 return JSONKind < other.Kind(), nil 170 } 171 172 cmp, err := t.Compare(otherJSONDoc) 173 if err != nil { 174 return false, err 175 } 176 177 return cmp == -1, nil 178 } 179 180 // Compare implements MySQL JSON type compare semantics. 181 func (t JSON) Compare(other JSON) (int, error) { 182 left, err := t.Inner() 183 if err != nil { 184 return 0, err 185 } 186 187 right, err := other.Inner() 188 if err != nil { 189 return 0, err 190 } 191 192 return compareJSON(left, right) 193 } 194 195 func (t JSON) readFrom(nbf *NomsBinFormat, b *binaryNomsReader) (Value, error) { 196 panic("unreachable") 197 } 198 199 func (t JSON) skip(nbf *NomsBinFormat, b *binaryNomsReader) { 200 panic("unreachable") 201 } 202 203 // HumanReadableString implements the Value interface. 204 func (t JSON) HumanReadableString() string { 205 val, err := t.Inner() 206 if err != nil { 207 d.PanicIfError(err) 208 } 209 h, err := val.Hash(t.nbf) 210 if err != nil { 211 d.PanicIfError(err) 212 } 213 return fmt.Sprintf("JSON(%s)", h.String()) 214 } 215 216 func compareJSON(a, b Value) (int, error) { 217 aNull := a.Kind() == NullKind 218 bNull := b.Kind() == NullKind 219 if aNull && bNull { 220 return 0, nil 221 } else if aNull && !bNull { 222 return -1, nil 223 } else if !aNull && bNull { 224 return 1, nil 225 } 226 227 switch a := a.(type) { 228 case Bool: 229 return compareJSONBool(a, b) 230 case List: 231 return compareJSONArray(a, b) 232 case Map: 233 return compareJSONObject(a, b) 234 case String: 235 return compareJSONString(a, b) 236 case Float: 237 return compareJSONNumber(a, b) 238 default: 239 return 0, fmt.Errorf("unexpected type: %v", a) 240 } 241 } 242 243 func compareJSONBool(a Bool, b Value) (int, error) { 244 switch b := b.(type) { 245 case Bool: 246 // The JSON false literal is less than the JSON true literal. 247 if a == b { 248 return 0, nil 249 } 250 if a { 251 // a > b 252 return 1, nil 253 } else { 254 // a < b 255 return -1, nil 256 } 257 258 default: 259 // a is higher precedence 260 return 1, nil 261 } 262 } 263 264 func compareJSONArray(a List, b Value) (int, error) { 265 switch b := b.(type) { 266 case Bool: 267 // a is lower precedence 268 return -1, nil 269 270 case List: 271 // Two JSON arrays are equal if they have the same length and values in corresponding positions in the arrays 272 // are equal. If the arrays are not equal, their order is determined by the elements in the first position 273 // where there is a difference. The array with the smaller value in that position is ordered first. 274 275 // TODO(andy): this diverges from GMS 276 aLess, err := a.Less(a.format(), b) 277 if err != nil { 278 return 0, err 279 } 280 if aLess { 281 return -1, nil 282 } 283 284 bLess, err := b.Less(b.format(), a) 285 if err != nil { 286 return 0, err 287 } 288 if bLess { 289 return 1, nil 290 } 291 292 return 0, nil 293 294 default: 295 // a is higher precedence 296 return 1, nil 297 } 298 } 299 300 func compareJSONObject(a Map, b Value) (int, error) { 301 switch b := b.(type) { 302 case 303 Bool, 304 List: 305 // a is lower precedence 306 return -1, nil 307 308 case Map: 309 // Two JSON objects are equal if they have the same set of keys, and each key has the same value in both 310 // objects. The order of two objects that are not equal is unspecified but deterministic. 311 312 // TODO(andy): this diverges from GMS 313 aLess, err := a.Less(a.format(), b) 314 if err != nil { 315 return 0, err 316 } 317 if aLess { 318 return -1, nil 319 } 320 321 bLess, err := b.Less(b.format(), a) 322 if err != nil { 323 return 0, err 324 } 325 if bLess { 326 return 1, nil 327 } 328 329 return 0, nil 330 331 default: 332 // a is higher precedence 333 return 1, nil 334 } 335 } 336 337 func compareJSONString(a String, b Value) (int, error) { 338 switch b := b.(type) { 339 case 340 Bool, 341 List, 342 Map: 343 // a is lower precedence 344 return -1, nil 345 346 case String: 347 return strings.Compare(string(a), string(b)), nil 348 349 default: 350 // a is higher precedence 351 return 1, nil 352 } 353 } 354 355 func compareJSONNumber(a Float, b Value) (int, error) { 356 switch b := b.(type) { 357 case 358 Bool, 359 List, 360 Map, 361 String: 362 // a is lower precedence 363 return -1, nil 364 365 case Float: 366 if a > b { 367 return 1, nil 368 } else if a < b { 369 return -1, nil 370 } 371 return 0, nil 372 373 default: 374 // a is higher precedence 375 return 1, nil 376 } 377 }