github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/util/json/json.go (about) 1 // Copyright 2017 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package json 12 13 import ( 14 "bytes" 15 "encoding/json" 16 "fmt" 17 "math/big" 18 "reflect" 19 "sort" 20 "strconv" 21 "strings" 22 "unicode/utf8" 23 "unsafe" 24 25 "github.com/cockroachdb/apd" 26 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" 27 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" 28 "github.com/cockroachdb/cockroach/pkg/util/encoding" 29 "github.com/cockroachdb/cockroach/pkg/util/unique" 30 "github.com/cockroachdb/errors" 31 ) 32 33 // Type represents a JSON type. 34 type Type int 35 36 // This enum defines the ordering of types. It should not be reordered. 37 const ( 38 _ Type = iota 39 NullJSONType 40 StringJSONType 41 NumberJSONType 42 FalseJSONType 43 TrueJSONType 44 ArrayJSONType 45 ObjectJSONType 46 ) 47 48 const ( 49 wordSize = unsafe.Sizeof(big.Word(0)) 50 decimalSize = unsafe.Sizeof(apd.Decimal{}) 51 stringHeaderSize = unsafe.Sizeof(reflect.StringHeader{}) 52 sliceHeaderSize = unsafe.Sizeof(reflect.SliceHeader{}) 53 keyValuePairSize = unsafe.Sizeof(jsonKeyValuePair{}) 54 jsonInterfaceSize = unsafe.Sizeof((JSON)(nil)) 55 ) 56 57 const ( 58 msgModifyAfterBuild = "modify after Build()" 59 ) 60 61 // JSON represents a JSON value. 62 type JSON interface { 63 fmt.Stringer 64 65 Compare(JSON) (int, error) 66 // Type returns the JSON type. 67 Type() Type 68 // Format writes out the JSON document to the specified buffer. 69 Format(buf *bytes.Buffer) 70 // Size returns the size of the JSON document in bytes. 71 Size() uintptr 72 73 // EncodeInvertedIndexKeys takes in a key prefix and returns a slice of inverted index keys, 74 // one per path through the receiver. 75 encodeInvertedIndexKeys(b []byte) ([][]byte, error) 76 77 // numInvertedIndexEntries returns the number of entries that will be 78 // produced if this JSON gets included in an inverted index. 79 numInvertedIndexEntries() (int, error) 80 81 // allPaths returns a slice of new JSON documents, each a path to a leaf 82 // through the receiver. Note that leaves include the empty object and array 83 // in addition to scalars. 84 allPaths() ([]JSON, error) 85 86 // FetchValKey implements the `->` operator for strings, returning nil if the 87 // key is not found. 88 FetchValKey(key string) (JSON, error) 89 90 // FetchValIdx implements the `->` operator for ints, returning nil if the 91 // key is not found. 92 FetchValIdx(idx int) (JSON, error) 93 94 // FetchValKeyOrIdx is used for path access, if obj is an object, it tries to 95 // access the given field. If it's an array, it interprets the key as an int 96 // and tries to access the given index. 97 FetchValKeyOrIdx(key string) (JSON, error) 98 99 // RemoveString implements the `-` operator for strings, returning JSON after removal, 100 // whether removal is valid and error message. 101 RemoveString(s string) (JSON, bool, error) 102 103 // RemoveIndex implements the `-` operator for ints, returning JSON after removal, 104 // whether removal is valid and error message. 105 RemoveIndex(idx int) (JSON, bool, error) 106 107 // RemovePath and doRemovePath implement the `#-` operator for strings, returning JSON after removal, 108 // whether removal is valid and error message. 109 RemovePath(path []string) (JSON, bool, error) 110 doRemovePath(path []string) (JSON, bool, error) 111 112 // Concat implements the `||` operator. 113 Concat(other JSON) (JSON, error) 114 115 // AsText returns the JSON document as a string, with quotes around strings removed, and null as nil. 116 AsText() (*string, error) 117 118 // Exists implements the `?` operator. 119 Exists(string) (bool, error) 120 121 // StripNulls returns the JSON document with all object fields that have null values omitted 122 // and whether it needs to strip nulls. Stripping nulls is needed only if it contains some 123 // object fields having null values. 124 StripNulls() (JSON, bool, error) 125 126 // ObjectIter returns an *ObjectKeyIterator, nil if json is not an object. 127 ObjectIter() (*ObjectIterator, error) 128 129 // isScalar returns whether the JSON document is null, true, false, a string, 130 // or a number. 131 isScalar() bool 132 133 // preprocessForContains converts a JSON document to an internal interface 134 // which is used to efficiently implement the @> operator. 135 preprocessForContains() (containsable, error) 136 137 // encode appends the encoding of the JSON document to appendTo, returning 138 // the result alongside the JEntry for the document. Note that some values 139 // (true/false/null) are encoded with 0 bytes and are purely defined by their 140 // JEntry. 141 encode(appendTo []byte) (jEntry jEntry, b []byte, err error) 142 143 // MaybeDecode returns an equivalent JSON which is not a jsonEncoded. 144 MaybeDecode() JSON 145 146 // toGoRepr returns the Go-style representation of this JSON value 147 // (map[string]interface{} for objects, etc.). 148 toGoRepr() (interface{}, error) 149 150 // tryDecode returns an equivalent JSON which is not a jsonEncoded, returning 151 // an error if the encoded data was corrupt. 152 tryDecode() (JSON, error) 153 154 // Len returns the number of outermost elements in the JSON document if it is an object or an array. 155 // Otherwise, Len returns 0. 156 Len() int 157 158 // HasContainerLeaf returns whether this document contains in it somewhere 159 // either the empty array or the empty object. 160 HasContainerLeaf() (bool, error) 161 } 162 163 type jsonTrue struct{} 164 165 // TrueJSONValue is JSON `true` 166 var TrueJSONValue = jsonTrue{} 167 168 type jsonFalse struct{} 169 170 // FalseJSONValue is JSON `false` 171 var FalseJSONValue = jsonFalse{} 172 173 type jsonNull struct{} 174 175 // NullJSONValue is JSON `null` 176 var NullJSONValue = jsonNull{} 177 178 type jsonNumber apd.Decimal 179 type jsonString string 180 181 type jsonArray []JSON 182 183 type jsonKeyValuePair struct { 184 k jsonString 185 v JSON 186 } 187 188 // ArrayBuilder builds JSON Array by a JSON sequence. 189 type ArrayBuilder struct { 190 jsons []JSON 191 } 192 193 // NewArrayBuilder returns an ArrayBuilder. The builder will reserve spaces 194 // based on hint about number of adds to reduce times of growing capacity. 195 func NewArrayBuilder(numAddsHint int) *ArrayBuilder { 196 return &ArrayBuilder{ 197 jsons: make([]JSON, 0, numAddsHint), 198 } 199 } 200 201 // Add appends JSON to the sequence. 202 func (b *ArrayBuilder) Add(j JSON) { 203 b.jsons = append(b.jsons, j) 204 } 205 206 // Build returns the constructed JSON array. A caller may not modify the array, 207 // and the ArrayBuilder reserves the right to re-use the array returned (though 208 // the data will not be modified). This is important in the case of a window 209 // function, which might want to incrementally update an aggregation. 210 func (b *ArrayBuilder) Build() JSON { 211 return jsonArray(b.jsons) 212 } 213 214 // ArrayBuilderWithCounter builds JSON Array by a JSON sequence with a size counter. 215 type ArrayBuilderWithCounter struct { 216 ab *ArrayBuilder 217 size uintptr 218 } 219 220 // NewArrayBuilderWithCounter returns an ArrayBuilderWithCounter. 221 func NewArrayBuilderWithCounter() *ArrayBuilderWithCounter { 222 return &ArrayBuilderWithCounter{ 223 ab: NewArrayBuilder(0), 224 size: sliceHeaderSize, 225 } 226 } 227 228 // Add appends JSON to the sequence and updates the size counter. 229 func (b *ArrayBuilderWithCounter) Add(j JSON) { 230 oldCap := cap(b.ab.jsons) 231 b.ab.Add(j) 232 b.size += j.Size() + (uintptr)(cap(b.ab.jsons)-oldCap)*jsonInterfaceSize 233 } 234 235 // Build returns a JSON array built from a JSON sequence. After that, it should 236 // not be modified any longer. 237 func (b *ArrayBuilderWithCounter) Build() JSON { 238 return b.ab.Build() 239 } 240 241 // Size returns the size in bytes of the JSON Array the builder is going to build. 242 func (b *ArrayBuilderWithCounter) Size() uintptr { 243 return b.size 244 } 245 246 // ObjectBuilder builds JSON Object by a key value pair sequence. 247 type ObjectBuilder struct { 248 pairs []jsonKeyValuePair 249 } 250 251 // NewObjectBuilder returns an ObjectBuilder. The builder will reserve spaces 252 // based on hint about number of adds to reduce times of growing capacity. 253 func NewObjectBuilder(numAddsHint int) *ObjectBuilder { 254 return &ObjectBuilder{ 255 pairs: make([]jsonKeyValuePair, 0, numAddsHint), 256 } 257 } 258 259 // Add appends key value pair to the sequence. 260 func (b *ObjectBuilder) Add(k string, v JSON) { 261 if b.pairs == nil { 262 panic(errors.AssertionFailedf(msgModifyAfterBuild)) 263 } 264 b.pairs = append(b.pairs, jsonKeyValuePair{k: jsonString(k), v: v}) 265 } 266 267 // Build returns a JSON object built from a key value pair sequence. After that, 268 // it should not be modified any longer. 269 func (b *ObjectBuilder) Build() JSON { 270 if b.pairs == nil { 271 panic(errors.AssertionFailedf(msgModifyAfterBuild)) 272 } 273 orders := make([]int, len(b.pairs)) 274 for i := range orders { 275 orders[i] = i 276 } 277 sorter := pairSorter{ 278 pairs: b.pairs, 279 orders: orders, 280 hasNonUnique: false, 281 } 282 b.pairs = nil 283 sort.Sort(&sorter) 284 sorter.unique() 285 return jsonObject(sorter.pairs) 286 } 287 288 // pairSorter sorts and uniqueifies JSON pairs. In order to keep 289 // the last one for pairs with the same key while sort.Sort is 290 // not stable, pairSorter uses []int orders to maintain order and 291 // bool hasNonUnique to skip unnecessary uniqueifying. 292 type pairSorter struct { 293 pairs []jsonKeyValuePair 294 orders []int 295 hasNonUnique bool 296 } 297 298 func (s *pairSorter) Len() int { 299 return len(s.pairs) 300 } 301 302 func (s *pairSorter) Less(i, j int) bool { 303 cmp := strings.Compare(string(s.pairs[i].k), string(s.pairs[j].k)) 304 if cmp != 0 { 305 return cmp == -1 306 } 307 s.hasNonUnique = true 308 // The element with greater order has lower rank when their keys 309 // are same, since unique algorithm will prefer first element. 310 return s.orders[i] > s.orders[j] 311 } 312 313 func (s *pairSorter) Swap(i, j int) { 314 s.pairs[i], s.orders[i], s.pairs[j], s.orders[j] = s.pairs[j], s.orders[j], s.pairs[i], s.orders[i] 315 } 316 317 func (s *pairSorter) unique() { 318 // If there are any duplicate keys, then in sorted order it will have 319 // two pairs with rank i and i + 1 whose keys are same. 320 // For sorting based on comparisons, if two unique elements (pair.k, order) 321 // have rank i and i + 1, they have to compare once to figure out their 322 // relative order in the final position i and i + 1. So if there are any 323 // equal elements, then the sort must have compared them at some point. 324 if !s.hasNonUnique { 325 return 326 } 327 top := 0 328 for i := 1; i < len(s.pairs); i++ { 329 if s.pairs[top].k != s.pairs[i].k { 330 top++ 331 if top != i { 332 s.pairs[top] = s.pairs[i] 333 } 334 } 335 } 336 s.pairs = s.pairs[:top+1] 337 } 338 339 // jsonObject represents a JSON object as a sorted-by-key list of key-value 340 // pairs, which are unique by key. 341 type jsonObject []jsonKeyValuePair 342 343 func (jsonNull) Type() Type { return NullJSONType } 344 func (jsonFalse) Type() Type { return FalseJSONType } 345 func (jsonTrue) Type() Type { return TrueJSONType } 346 func (jsonNumber) Type() Type { return NumberJSONType } 347 func (jsonString) Type() Type { return StringJSONType } 348 func (jsonArray) Type() Type { return ArrayJSONType } 349 func (jsonObject) Type() Type { return ObjectJSONType } 350 351 func (j jsonNull) MaybeDecode() JSON { return j } 352 func (j jsonFalse) MaybeDecode() JSON { return j } 353 func (j jsonTrue) MaybeDecode() JSON { return j } 354 func (j jsonNumber) MaybeDecode() JSON { return j } 355 func (j jsonString) MaybeDecode() JSON { return j } 356 func (j jsonArray) MaybeDecode() JSON { return j } 357 func (j jsonObject) MaybeDecode() JSON { return j } 358 359 func (j jsonNull) tryDecode() (JSON, error) { return j, nil } 360 func (j jsonFalse) tryDecode() (JSON, error) { return j, nil } 361 func (j jsonTrue) tryDecode() (JSON, error) { return j, nil } 362 func (j jsonNumber) tryDecode() (JSON, error) { return j, nil } 363 func (j jsonString) tryDecode() (JSON, error) { return j, nil } 364 func (j jsonArray) tryDecode() (JSON, error) { return j, nil } 365 func (j jsonObject) tryDecode() (JSON, error) { return j, nil } 366 367 func cmpJSONTypes(a Type, b Type) int { 368 if b > a { 369 return -1 370 } 371 if b < a { 372 return 1 373 } 374 return 0 375 } 376 377 func (j jsonNull) Compare(other JSON) (int, error) { return cmpJSONTypes(j.Type(), other.Type()), nil } 378 func (j jsonFalse) Compare(other JSON) (int, error) { return cmpJSONTypes(j.Type(), other.Type()), nil } 379 func (j jsonTrue) Compare(other JSON) (int, error) { return cmpJSONTypes(j.Type(), other.Type()), nil } 380 381 func decodeIfNeeded(j JSON) (JSON, error) { 382 if enc, ok := j.(*jsonEncoded); ok { 383 var err error 384 j, err = enc.decode() 385 if err != nil { 386 return nil, err 387 } 388 } 389 return j, nil 390 } 391 392 func (j jsonNumber) Compare(other JSON) (int, error) { 393 cmp := cmpJSONTypes(j.Type(), other.Type()) 394 if cmp != 0 { 395 return cmp, nil 396 } 397 var err error 398 if other, err = decodeIfNeeded(other); err != nil { 399 return 0, err 400 } 401 dec := apd.Decimal(j) 402 o := apd.Decimal(other.(jsonNumber)) 403 return dec.Cmp(&o), nil 404 } 405 406 func (j jsonString) Compare(other JSON) (int, error) { 407 cmp := cmpJSONTypes(j.Type(), other.Type()) 408 if cmp != 0 { 409 return cmp, nil 410 } 411 // TODO(justin): we should optimize this, we don't have to decode the whole thing. 412 var err error 413 if other, err = decodeIfNeeded(other); err != nil { 414 return 0, err 415 } 416 o := other.(jsonString) 417 if o > j { 418 return -1, nil 419 } 420 if o < j { 421 return 1, nil 422 } 423 return 0, nil 424 } 425 426 func (j jsonArray) Compare(other JSON) (int, error) { 427 cmp := cmpJSONTypes(j.Type(), other.Type()) 428 if cmp != 0 { 429 return cmp, nil 430 } 431 lenJ := j.Len() 432 lenO := other.Len() 433 if lenJ < lenO { 434 return -1, nil 435 } 436 if lenJ > lenO { 437 return 1, nil 438 } 439 // TODO(justin): we should optimize this, we don't have to decode the whole thing. 440 var err error 441 if other, err = decodeIfNeeded(other); err != nil { 442 return 0, err 443 } 444 o := other.(jsonArray) 445 for i := 0; i < lenJ; i++ { 446 cmp, err := j[i].Compare(o[i]) 447 if err != nil { 448 return 0, err 449 } 450 if cmp != 0 { 451 return cmp, nil 452 } 453 } 454 return 0, nil 455 } 456 457 func (j jsonObject) Compare(other JSON) (int, error) { 458 cmp := cmpJSONTypes(j.Type(), other.Type()) 459 if cmp != 0 { 460 return cmp, nil 461 } 462 lenJ := j.Len() 463 lenO := other.Len() 464 if lenJ < lenO { 465 return -1, nil 466 } 467 if lenJ > lenO { 468 return 1, nil 469 } 470 // TODO(justin): we should optimize this, we don't have to decode the whole thing. 471 var err error 472 if other, err = decodeIfNeeded(other); err != nil { 473 return 0, err 474 } 475 o := other.(jsonObject) 476 for i := 0; i < lenJ; i++ { 477 cmpKey, err := j[i].k.Compare(o[i].k) 478 if err != nil { 479 return 0, err 480 } 481 if cmpKey != 0 { 482 return cmpKey, nil 483 } 484 cmpVal, err := j[i].v.Compare(o[i].v) 485 if err != nil { 486 return 0, err 487 } 488 if cmpVal != 0 { 489 return cmpVal, nil 490 } 491 } 492 return 0, nil 493 } 494 495 var errTrailingCharacters = pgerror.WithCandidateCode(errors.New("trailing characters after JSON document"), pgcode.InvalidTextRepresentation) 496 497 func (jsonNull) Format(buf *bytes.Buffer) { buf.WriteString("null") } 498 499 func (jsonFalse) Format(buf *bytes.Buffer) { buf.WriteString("false") } 500 501 func (jsonTrue) Format(buf *bytes.Buffer) { buf.WriteString("true") } 502 503 func (j jsonNumber) Format(buf *bytes.Buffer) { 504 dec := apd.Decimal(j) 505 // Make sure non-finite values are encoded as valid strings by 506 // quoting them. Unfortunately, since this is JSON, there's no 507 // defined way to express the three special numeric values (+inf, 508 // -inf, nan) except as a string. This means that the decoding 509 // side can't tell whether the field should be a float or a 510 // string. Testing for exact types is thus tricky. As of this 511 // comment, our current tests for this behavior happen it the SQL 512 // package, not here in the JSON package. 513 nonfinite := dec.Form != apd.Finite 514 if nonfinite { 515 buf.WriteByte('"') 516 } 517 buf.WriteString(dec.String()) 518 if nonfinite { 519 buf.WriteByte('"') 520 } 521 } 522 523 func (j jsonString) Format(buf *bytes.Buffer) { 524 encodeJSONString(buf, string(j)) 525 } 526 527 func asString(j JSON) string { 528 var buf bytes.Buffer 529 j.Format(&buf) 530 return buf.String() 531 } 532 533 func (j jsonNull) String() string { return asString(j) } 534 func (j jsonTrue) String() string { return asString(j) } 535 func (j jsonFalse) String() string { return asString(j) } 536 func (j jsonString) String() string { return asString(j) } 537 func (j jsonNumber) String() string { return asString(j) } 538 func (j jsonArray) String() string { return asString(j) } 539 func (j jsonObject) String() string { return asString(j) } 540 541 const hexAlphabet = "0123456789abcdef" 542 543 // encodeJSONString writes a string literal to buf as a JSON string. 544 // Cribbed from https://github.com/golang/go/blob/7badae85f20f1bce4cc344f9202447618d45d414/src/encoding/json/encode.go. 545 func encodeJSONString(buf *bytes.Buffer, s string) { 546 buf.WriteByte('"') 547 start := 0 548 for i := 0; i < len(s); { 549 if b := s[i]; b < utf8.RuneSelf { 550 if safeSet[b] { 551 i++ 552 continue 553 } 554 if start < i { 555 buf.WriteString(s[start:i]) 556 } 557 switch b { 558 case '\\', '"': 559 buf.WriteByte('\\') 560 buf.WriteByte(b) 561 case '\n': 562 buf.WriteByte('\\') 563 buf.WriteByte('n') 564 case '\r': 565 buf.WriteByte('\\') 566 buf.WriteByte('r') 567 case '\t': 568 buf.WriteByte('\\') 569 buf.WriteByte('t') 570 default: 571 // This encodes bytes < 0x20 except for \t, \n and \r. 572 // If escapeHTML is set, it also escapes <, >, and & 573 // because they can lead to security holes when 574 // user-controlled strings are rendered into JSON 575 // and served to some browsers. 576 buf.WriteString(`\u00`) 577 buf.WriteByte(hexAlphabet[b>>4]) 578 buf.WriteByte(hexAlphabet[b&0xF]) 579 } 580 i++ 581 start = i 582 continue 583 } 584 c, size := utf8.DecodeRuneInString(s[i:]) 585 if c == utf8.RuneError && size == 1 { 586 if start < i { 587 buf.WriteString(s[start:i]) 588 } 589 buf.WriteString(`\ufffd`) 590 i += size 591 start = i 592 continue 593 } 594 i += size 595 } 596 if start < len(s) { 597 buf.WriteString(s[start:]) 598 } 599 buf.WriteByte('"') 600 } 601 602 func (j jsonArray) Format(buf *bytes.Buffer) { 603 buf.WriteByte('[') 604 for i := range j { 605 if i != 0 { 606 buf.WriteString(", ") 607 } 608 j[i].Format(buf) 609 } 610 buf.WriteByte(']') 611 } 612 613 func (j jsonObject) Format(buf *bytes.Buffer) { 614 buf.WriteByte('{') 615 for i := range j { 616 if i != 0 { 617 buf.WriteString(", ") 618 } 619 encodeJSONString(buf, string(j[i].k)) 620 buf.WriteString(": ") 621 j[i].v.Format(buf) 622 } 623 buf.WriteByte('}') 624 } 625 626 func (jsonNull) Size() uintptr { return 0 } 627 628 func (jsonFalse) Size() uintptr { return 0 } 629 630 func (jsonTrue) Size() uintptr { return 0 } 631 632 func (j jsonNumber) Size() uintptr { 633 intVal := j.Coeff 634 return decimalSize + uintptr(cap(intVal.Bits()))*wordSize 635 } 636 637 func (j jsonString) Size() uintptr { 638 return stringHeaderSize + uintptr(len(j)) 639 } 640 641 func (j jsonArray) Size() uintptr { 642 valSize := sliceHeaderSize + uintptr(cap(j))*jsonInterfaceSize 643 for _, elem := range j { 644 valSize += elem.Size() 645 } 646 return valSize 647 } 648 649 func (j jsonObject) Size() uintptr { 650 valSize := sliceHeaderSize + uintptr(cap(j))*keyValuePairSize 651 // jsonKeyValuePair consists of jsonString(i.e. string header) k and JSON interface v. 652 // Since elem.k.Size() has already taken stringHeaderSize into account, we should 653 // reduce len(j) * stringHeaderSize to avoid counting the size of string headers twice 654 valSize -= uintptr(len(j)) * stringHeaderSize 655 for _, elem := range j { 656 valSize += elem.k.Size() 657 valSize += elem.v.Size() 658 } 659 return valSize 660 } 661 662 // ParseJSON takes a string of JSON and returns a JSON value. 663 func ParseJSON(s string) (JSON, error) { 664 // This goes in two phases - first it parses the string into raw interface{}s 665 // using the Go encoding/json package, then it transforms that into a JSON. 666 // This could be faster if we wrote a parser to go directly into the JSON. 667 var result interface{} 668 decoder := json.NewDecoder(strings.NewReader(s)) 669 // We want arbitrary size/precision decimals, so we call UseNumber() to tell 670 // the decoder to decode numbers into strings instead of float64s (which we 671 // later parse using apd). 672 decoder.UseNumber() 673 err := decoder.Decode(&result) 674 if err != nil { 675 err = errors.Handled(err) 676 err = errors.Wrap(err, "unable to decode JSON") 677 err = pgerror.WithCandidateCode(err, pgcode.InvalidTextRepresentation) 678 return nil, err 679 } 680 if decoder.More() { 681 return nil, errTrailingCharacters 682 } 683 return MakeJSON(result) 684 } 685 686 // EncodeInvertedIndexKeys takes in a key prefix and returns a slice of inverted index keys, 687 // one per unique path through the receiver. 688 func EncodeInvertedIndexKeys(b []byte, json JSON) ([][]byte, error) { 689 return json.encodeInvertedIndexKeys(encoding.EncodeJSONAscending(b)) 690 } 691 func (j jsonNull) encodeInvertedIndexKeys(b []byte) ([][]byte, error) { 692 b = encoding.AddJSONPathTerminator(b) 693 return [][]byte{encoding.EncodeNullAscending(b)}, nil 694 } 695 func (jsonTrue) encodeInvertedIndexKeys(b []byte) ([][]byte, error) { 696 b = encoding.AddJSONPathTerminator(b) 697 return [][]byte{encoding.EncodeTrueAscending(b)}, nil 698 } 699 func (jsonFalse) encodeInvertedIndexKeys(b []byte) ([][]byte, error) { 700 b = encoding.AddJSONPathTerminator(b) 701 return [][]byte{encoding.EncodeFalseAscending(b)}, nil 702 } 703 func (j jsonString) encodeInvertedIndexKeys(b []byte) ([][]byte, error) { 704 b = encoding.AddJSONPathTerminator(b) 705 return [][]byte{encoding.EncodeStringAscending(b, string(j))}, nil 706 } 707 func (j jsonNumber) encodeInvertedIndexKeys(b []byte) ([][]byte, error) { 708 b = encoding.AddJSONPathTerminator(b) 709 var dec = apd.Decimal(j) 710 return [][]byte{encoding.EncodeDecimalAscending(b, &dec)}, nil 711 } 712 func (j jsonArray) encodeInvertedIndexKeys(b []byte) ([][]byte, error) { 713 // Checking for an empty array. 714 if len(j) == 0 { 715 return [][]byte{encoding.EncodeJSONEmptyArray(b)}, nil 716 } 717 718 prefix := encoding.EncodeArrayAscending(b) 719 var outKeys [][]byte 720 for i := range j { 721 children, err := j[i].encodeInvertedIndexKeys(prefix[:len(prefix):len(prefix)]) 722 if err != nil { 723 return nil, err 724 } 725 outKeys = append(outKeys, children...) 726 } 727 728 // Deduplicate the entries, since arrays can have duplicates - we don't want 729 // to emit duplicate keys from this method, as it's more expensive to 730 // deduplicate keys via KV (which will actually write the keys) than via SQL 731 // (just an in-memory sort and distinct). 732 outKeys = unique.UniquifyByteSlices(outKeys) 733 return outKeys, nil 734 } 735 736 func (j jsonObject) encodeInvertedIndexKeys(b []byte) ([][]byte, error) { 737 // Checking for an empty object. 738 if len(j) == 0 { 739 return [][]byte{encoding.EncodeJSONEmptyObject(b)}, nil 740 } 741 742 var outKeys [][]byte 743 for i := range j { 744 children, err := j[i].v.encodeInvertedIndexKeys(nil) 745 if err != nil { 746 return nil, err 747 } 748 749 // We're trying to see if this is the end of the JSON path. If it is, then we don't want to 750 // add an extra separator. 751 end := true 752 switch j[i].v.(type) { 753 case jsonArray, jsonObject: 754 if j[i].v.Len() != 0 { 755 end = false 756 } 757 } 758 759 for _, childBytes := range children { 760 encodedKey := bytes.Join([][]byte{b, 761 encoding.EncodeJSONKeyStringAscending(nil, string(j[i].k), end), 762 childBytes}, nil) 763 764 outKeys = append(outKeys, encodedKey) 765 } 766 } 767 return outKeys, nil 768 } 769 770 // NumInvertedIndexEntries returns the number of inverted index entries that 771 // would be created for the given JSON value. Since identical elements of an 772 // array are encoded identically in the inverted index, the total number of 773 // distinct index entries may be less than the total number of paths. 774 func NumInvertedIndexEntries(j JSON) (int, error) { 775 return j.numInvertedIndexEntries() 776 } 777 778 func (j jsonNull) numInvertedIndexEntries() (int, error) { 779 return 1, nil 780 } 781 func (jsonTrue) numInvertedIndexEntries() (int, error) { 782 return 1, nil 783 } 784 func (jsonFalse) numInvertedIndexEntries() (int, error) { 785 return 1, nil 786 } 787 func (j jsonString) numInvertedIndexEntries() (int, error) { 788 return 1, nil 789 } 790 func (j jsonNumber) numInvertedIndexEntries() (int, error) { 791 return 1, nil 792 } 793 func (j jsonArray) numInvertedIndexEntries() (int, error) { 794 if len(j) == 0 { 795 return 1, nil 796 } 797 keys, err := j.encodeInvertedIndexKeys(nil) 798 if err != nil { 799 return 0, err 800 } 801 return len(keys), nil 802 } 803 804 func (j jsonObject) numInvertedIndexEntries() (int, error) { 805 if len(j) == 0 { 806 return 1, nil 807 } 808 count := 0 809 for _, kv := range j { 810 n, err := kv.v.numInvertedIndexEntries() 811 if err != nil { 812 return 0, err 813 } 814 count += n 815 } 816 return count, nil 817 } 818 819 // AllPaths returns a slice of new JSON documents, each a path to a leaf 820 // through the input. Note that leaves include the empty object and array 821 // in addition to scalars. 822 func AllPaths(j JSON) ([]JSON, error) { 823 return j.allPaths() 824 } 825 826 func (j jsonNull) allPaths() ([]JSON, error) { 827 return []JSON{j}, nil 828 } 829 830 func (j jsonTrue) allPaths() ([]JSON, error) { 831 return []JSON{j}, nil 832 } 833 834 func (j jsonFalse) allPaths() ([]JSON, error) { 835 return []JSON{j}, nil 836 } 837 838 func (j jsonString) allPaths() ([]JSON, error) { 839 return []JSON{j}, nil 840 } 841 842 func (j jsonNumber) allPaths() ([]JSON, error) { 843 return []JSON{j}, nil 844 } 845 846 func (j jsonArray) allPaths() ([]JSON, error) { 847 if len(j) == 0 { 848 return []JSON{j}, nil 849 } 850 ret := make([]JSON, 0, len(j)) 851 for i := range j { 852 paths, err := j[i].allPaths() 853 if err != nil { 854 return nil, err 855 } 856 for _, path := range paths { 857 ret = append(ret, jsonArray{path}) 858 } 859 } 860 return ret, nil 861 } 862 863 func (j jsonObject) allPaths() ([]JSON, error) { 864 if len(j) == 0 { 865 return []JSON{j}, nil 866 } 867 ret := make([]JSON, 0, len(j)) 868 for i := range j { 869 paths, err := j[i].v.allPaths() 870 if err != nil { 871 return nil, err 872 } 873 for _, path := range paths { 874 ret = append(ret, jsonObject{jsonKeyValuePair{k: j[i].k, v: path}}) 875 } 876 } 877 return ret, nil 878 } 879 880 // FromDecimal returns a JSON value given a apd.Decimal. 881 func FromDecimal(v apd.Decimal) JSON { 882 return jsonNumber(v) 883 } 884 885 // FromNumber returns a JSON value given a json.Number. 886 func FromNumber(v json.Number) (JSON, error) { 887 // The JSON decoder has already verified that the string `v` represents a 888 // valid JSON number, and the set of valid JSON numbers is a [proper] subset 889 // of the set of valid apd.Decimal values. 890 dec := apd.Decimal{} 891 _, _, err := dec.SetString(string(v)) 892 return jsonNumber(dec), err 893 } 894 895 // FromString returns a JSON value given a string. 896 func FromString(v string) JSON { 897 return jsonString(v) 898 } 899 900 // FromBool returns a JSON value given a bool. 901 func FromBool(v bool) JSON { 902 if v { 903 return TrueJSONValue 904 } 905 return FalseJSONValue 906 } 907 908 func fromArray(v []interface{}) (JSON, error) { 909 elems := make([]JSON, len(v)) 910 for i := range v { 911 var err error 912 elems[i], err = MakeJSON(v[i]) 913 if err != nil { 914 return nil, err 915 } 916 } 917 return jsonArray(elems), nil 918 } 919 920 func fromMap(v map[string]interface{}) (JSON, error) { 921 keys := make([]string, len(v)) 922 i := 0 923 for k := range v { 924 keys[i] = k 925 i++ 926 } 927 sort.Strings(keys) 928 result := make([]jsonKeyValuePair, len(v)) 929 for i := range keys { 930 v, err := MakeJSON(v[keys[i]]) 931 if err != nil { 932 return nil, err 933 } 934 result[i] = jsonKeyValuePair{ 935 k: jsonString(keys[i]), 936 v: v, 937 } 938 } 939 return jsonObject(result), nil 940 } 941 942 // FromInt returns a JSON value given a int. 943 func FromInt(v int) JSON { 944 dec := apd.Decimal{} 945 dec.SetFinite(int64(v), 0) 946 return jsonNumber(dec) 947 } 948 949 // FromInt64 returns a JSON value given a int64. 950 func FromInt64(v int64) JSON { 951 dec := apd.Decimal{} 952 dec.SetFinite(v, 0) 953 return jsonNumber(dec) 954 } 955 956 // FromFloat64 returns a JSON value given a float64. 957 func FromFloat64(v float64) (JSON, error) { 958 dec := apd.Decimal{} 959 _, err := dec.SetFloat64(v) 960 if err != nil { 961 return nil, err 962 } 963 return jsonNumber(dec), nil 964 } 965 966 // MakeJSON returns a JSON value given a Go-style representation of JSON. 967 // * JSON null is Go `nil`, 968 // * JSON true is Go `true`, 969 // * JSON false is Go `false`, 970 // * JSON numbers are json.Number | int | int64 | float64, 971 // * JSON string is a Go string, 972 // * JSON array is a Go []interface{}, 973 // * JSON object is a Go map[string]interface{}. 974 func MakeJSON(d interface{}) (JSON, error) { 975 switch v := d.(type) { 976 case json.Number: 977 return FromNumber(v) 978 case string: 979 return FromString(v), nil 980 case bool: 981 return FromBool(v), nil 982 case nil: 983 return NullJSONValue, nil 984 case []interface{}: 985 return fromArray(v) 986 case map[string]interface{}: 987 return fromMap(v) 988 // The below are not used by ParseJSON, but are provided for ease-of-use when 989 // constructing Datums. 990 case int: 991 return FromInt(v), nil 992 case int64: 993 return FromInt64(v), nil 994 case float64: 995 return FromFloat64(v) 996 case JSON: 997 // If we get passed a JSON, just accept it. This is useful in cases like the 998 // random JSON generator. 999 return v, nil 1000 } 1001 return nil, errors.AssertionFailedf("unknown value type passed to MakeJSON: %T", d) 1002 } 1003 1004 // This value was determined through some rough experimental results as a good 1005 // place to start doing binary search over a linear scan. 1006 const bsearchCutoff = 20 1007 1008 func findPairIndexByKey(j jsonObject, key string) (int, bool) { 1009 // For small objects, the overhead of binary search is significant and so 1010 // it's faster to just do a linear scan. 1011 var i int 1012 if len(j) < bsearchCutoff { 1013 for i = range j { 1014 if string(j[i].k) >= key { 1015 break 1016 } 1017 } 1018 } else { 1019 i = sort.Search(len(j), func(i int) bool { return string(j[i].k) >= key }) 1020 } 1021 if i < len(j) && string(j[i].k) == key { 1022 return i, true 1023 } 1024 return -1, false 1025 } 1026 1027 func (j jsonObject) FetchValKey(key string) (JSON, error) { 1028 i, ok := findPairIndexByKey(j, key) 1029 if ok { 1030 return j[i].v, nil 1031 } 1032 return nil, nil 1033 } 1034 1035 func (jsonNull) FetchValKey(string) (JSON, error) { return nil, nil } 1036 func (jsonTrue) FetchValKey(string) (JSON, error) { return nil, nil } 1037 func (jsonFalse) FetchValKey(string) (JSON, error) { return nil, nil } 1038 func (jsonString) FetchValKey(string) (JSON, error) { return nil, nil } 1039 func (jsonNumber) FetchValKey(string) (JSON, error) { return nil, nil } 1040 func (jsonArray) FetchValKey(string) (JSON, error) { return nil, nil } 1041 1042 func (j jsonArray) FetchValIdx(idx int) (JSON, error) { 1043 if idx < 0 { 1044 idx = len(j) + idx 1045 } 1046 if idx >= 0 && idx < len(j) { 1047 return j[idx], nil 1048 } 1049 return nil, nil 1050 } 1051 1052 func (jsonNull) FetchValIdx(int) (JSON, error) { return nil, nil } 1053 func (jsonTrue) FetchValIdx(int) (JSON, error) { return nil, nil } 1054 func (jsonFalse) FetchValIdx(int) (JSON, error) { return nil, nil } 1055 func (jsonString) FetchValIdx(int) (JSON, error) { return nil, nil } 1056 func (jsonNumber) FetchValIdx(int) (JSON, error) { return nil, nil } 1057 func (jsonObject) FetchValIdx(int) (JSON, error) { return nil, nil } 1058 1059 // FetchPath implements the #> operator. 1060 func FetchPath(j JSON, path []string) (JSON, error) { 1061 var next JSON 1062 var err error 1063 for _, v := range path { 1064 next, err = j.FetchValKeyOrIdx(v) 1065 if next == nil { 1066 return nil, nil 1067 } 1068 if err != nil { 1069 return nil, err 1070 } 1071 j = next 1072 } 1073 return j, nil 1074 } 1075 1076 var errCannotSetPathInScalar = pgerror.WithCandidateCode(errors.New("cannot set path in scalar"), pgcode.InvalidParameterValue) 1077 1078 // setValKeyOrIdx sets a key or index within a JSON object or array. If the 1079 // provided value is neither an object or array the value is returned 1080 // unchanged. 1081 // If the value is an object which does not have the provided key and 1082 // createMissing is true, the key is inserted into the object with the value `to`. 1083 // If the value is an array and the provided index is negative, it counts from the back of the array. 1084 // Further, if the value is an array, and createMissing is true: 1085 // * if the provided index points to before the start of the array, `to` is prepended to the array. 1086 // * if the provided index points to after the end of the array, `to` is appended to the array. 1087 func setValKeyOrIdx(j JSON, key string, to JSON, createMissing bool) (JSON, error) { 1088 switch v := j.(type) { 1089 case *jsonEncoded: 1090 n, err := v.shallowDecode() 1091 if err != nil { 1092 return nil, err 1093 } 1094 return setValKeyOrIdx(n, key, to, createMissing) 1095 case jsonObject: 1096 return v.SetKey(key, to, createMissing) 1097 case jsonArray: 1098 idx, err := strconv.Atoi(key) 1099 if err != nil { 1100 return nil, err 1101 } 1102 if idx < 0 { 1103 idx = len(v) + idx 1104 } 1105 if !createMissing && (idx < 0 || idx >= len(v)) { 1106 return v, nil 1107 } 1108 var result jsonArray 1109 if idx < 0 { 1110 result = make(jsonArray, len(v)+1) 1111 copy(result[1:], v) 1112 result[0] = to 1113 } else if idx >= len(v) { 1114 result = make(jsonArray, len(v)+1) 1115 copy(result, v) 1116 result[len(result)-1] = to 1117 } else { 1118 result = make(jsonArray, len(v)) 1119 copy(result, v) 1120 result[idx] = to 1121 } 1122 return result, nil 1123 } 1124 return j, nil 1125 } 1126 1127 // DeepSet sets a path to a value in a JSON document. 1128 // Largely follows the same semantics as setValKeyOrIdx, but with a path. 1129 // Implements the jsonb_set builtin. 1130 func DeepSet(j JSON, path []string, to JSON, createMissing bool) (JSON, error) { 1131 if j.isScalar() { 1132 return nil, errCannotSetPathInScalar 1133 } 1134 return deepSet(j, path, to, createMissing) 1135 } 1136 1137 func deepSet(j JSON, path []string, to JSON, createMissing bool) (JSON, error) { 1138 switch len(path) { 1139 case 0: 1140 return j, nil 1141 case 1: 1142 return setValKeyOrIdx(j, path[0], to, createMissing) 1143 default: 1144 switch v := j.(type) { 1145 case *jsonEncoded: 1146 n, err := v.shallowDecode() 1147 if err != nil { 1148 return nil, err 1149 } 1150 return deepSet(n, path, to, createMissing) 1151 default: 1152 fetched, err := j.FetchValKeyOrIdx(path[0]) 1153 if err != nil { 1154 return nil, err 1155 } 1156 if fetched == nil { 1157 return j, nil 1158 } 1159 sub, err := deepSet(fetched, path[1:], to, createMissing) 1160 if err != nil { 1161 return nil, err 1162 } 1163 return setValKeyOrIdx(j, path[0], sub, createMissing) 1164 } 1165 } 1166 } 1167 1168 var errCannotReplaceExistingKey = pgerror.WithCandidateCode(errors.New("cannot replace existing key"), pgcode.InvalidParameterValue) 1169 1170 func insertValKeyOrIdx(j JSON, key string, newVal JSON, insertAfter bool) (JSON, error) { 1171 switch v := j.(type) { 1172 case *jsonEncoded: 1173 n, err := v.shallowDecode() 1174 if err != nil { 1175 return nil, err 1176 } 1177 return insertValKeyOrIdx(n, key, newVal, insertAfter) 1178 case jsonObject: 1179 result, err := v.SetKey(key, newVal, true) 1180 if err != nil { 1181 return nil, err 1182 } 1183 if len(result) == len(v) { 1184 return nil, errCannotReplaceExistingKey 1185 } 1186 return result, nil 1187 case jsonArray: 1188 idx, err := strconv.Atoi(key) 1189 if err != nil { 1190 return nil, err 1191 } 1192 if idx < 0 { 1193 idx = len(v) + idx 1194 } 1195 if insertAfter { 1196 idx++ 1197 } 1198 1199 var result = make(jsonArray, len(v)+1) 1200 if idx <= 0 { 1201 copy(result[1:], v) 1202 result[0] = newVal 1203 } else if idx >= len(v) { 1204 copy(result, v) 1205 result[len(result)-1] = newVal 1206 } else { 1207 copy(result[:idx], v[:idx]) 1208 copy(result[idx+1:], v[idx:]) 1209 result[idx] = newVal 1210 } 1211 return result, nil 1212 } 1213 return j, nil 1214 } 1215 1216 // DeepInsert inserts a value at a path in a JSON document. 1217 // Implements the jsonb_insert builtin. 1218 func DeepInsert(j JSON, path []string, to JSON, insertAfter bool) (JSON, error) { 1219 if j.isScalar() { 1220 return nil, errCannotSetPathInScalar 1221 } 1222 return deepInsert(j, path, to, insertAfter) 1223 } 1224 1225 func deepInsert(j JSON, path []string, to JSON, insertAfter bool) (JSON, error) { 1226 switch len(path) { 1227 case 0: 1228 return j, nil 1229 case 1: 1230 return insertValKeyOrIdx(j, path[0], to, insertAfter) 1231 default: 1232 switch v := j.(type) { 1233 case *jsonEncoded: 1234 n, err := v.shallowDecode() 1235 if err != nil { 1236 return nil, err 1237 } 1238 return deepInsert(n, path, to, insertAfter) 1239 default: 1240 fetched, err := j.FetchValKeyOrIdx(path[0]) 1241 if err != nil { 1242 return nil, err 1243 } 1244 if fetched == nil { 1245 return j, nil 1246 } 1247 sub, err := deepInsert(fetched, path[1:], to, insertAfter) 1248 if err != nil { 1249 return nil, err 1250 } 1251 return setValKeyOrIdx(j, path[0], sub, true) 1252 } 1253 } 1254 } 1255 1256 func (j jsonObject) FetchValKeyOrIdx(key string) (JSON, error) { 1257 return j.FetchValKey(key) 1258 } 1259 1260 func (j jsonArray) FetchValKeyOrIdx(key string) (JSON, error) { 1261 idx, err := strconv.Atoi(key) 1262 if err != nil { 1263 // We shouldn't return this error because it means we couldn't parse the 1264 // number, meaning it was a string and that just means we can't find the 1265 // value in an array. 1266 return nil, nil //nolint:returnerrcheck 1267 } 1268 return j.FetchValIdx(idx) 1269 } 1270 1271 func (jsonNull) FetchValKeyOrIdx(string) (JSON, error) { return nil, nil } 1272 func (jsonTrue) FetchValKeyOrIdx(string) (JSON, error) { return nil, nil } 1273 func (jsonFalse) FetchValKeyOrIdx(string) (JSON, error) { return nil, nil } 1274 func (jsonString) FetchValKeyOrIdx(string) (JSON, error) { return nil, nil } 1275 func (jsonNumber) FetchValKeyOrIdx(string) (JSON, error) { return nil, nil } 1276 1277 var errCannotDeleteFromScalar = pgerror.WithCandidateCode(errors.New("cannot delete from scalar"), pgcode.InvalidParameterValue) 1278 var errCannotDeleteFromObject = pgerror.WithCandidateCode(errors.New("cannot delete from object using integer index"), pgcode.InvalidParameterValue) 1279 1280 func (j jsonObject) SetKey(key string, to JSON, createMissing bool) (jsonObject, error) { 1281 result := make(jsonObject, 0, len(j)+1) 1282 curIdx := 0 1283 1284 for curIdx < len(j) && string(j[curIdx].k) < key { 1285 result = append(result, j[curIdx]) 1286 curIdx++ 1287 } 1288 1289 keyAlreadyExists := curIdx < len(j) && string(j[curIdx].k) == key 1290 if createMissing || keyAlreadyExists { 1291 result = append(result, jsonKeyValuePair{ 1292 k: jsonString(key), 1293 v: to, 1294 }) 1295 } 1296 if keyAlreadyExists { 1297 curIdx++ 1298 } 1299 1300 for curIdx < len(j) { 1301 result = append(result, j[curIdx]) 1302 curIdx++ 1303 } 1304 1305 return result, nil 1306 } 1307 1308 func (j jsonArray) RemoveString(s string) (JSON, bool, error) { 1309 b := NewArrayBuilder(j.Len()) 1310 removed := false 1311 for _, el := range j { 1312 // We want to remove only elements of string type. 1313 if el.Type() == StringJSONType { 1314 t, err := el.AsText() 1315 if err != nil { 1316 return nil, false, err 1317 } 1318 if *t != s { 1319 b.Add(el) 1320 } else { 1321 removed = true 1322 } 1323 } else { 1324 b.Add(el) 1325 } 1326 } 1327 if removed { 1328 return b.Build(), removed, nil 1329 } 1330 return j, false, nil 1331 } 1332 1333 func (j jsonObject) RemoveString(s string) (JSON, bool, error) { 1334 idx, ok := findPairIndexByKey(j, s) 1335 if !ok { 1336 return j, false, nil 1337 } 1338 1339 newVal := make([]jsonKeyValuePair, len(j)-1) 1340 for i, elem := range j[:idx] { 1341 newVal[i] = elem 1342 } 1343 for i, elem := range j[idx+1:] { 1344 newVal[idx+i] = elem 1345 } 1346 return jsonObject(newVal), true, nil 1347 } 1348 1349 func (jsonNull) RemoveString(string) (JSON, bool, error) { return nil, false, errCannotDeleteFromScalar } 1350 func (jsonTrue) RemoveString(string) (JSON, bool, error) { return nil, false, errCannotDeleteFromScalar } 1351 func (jsonFalse) RemoveString(string) (JSON, bool, error) { 1352 return nil, false, errCannotDeleteFromScalar 1353 } 1354 func (jsonString) RemoveString(string) (JSON, bool, error) { 1355 return nil, false, errCannotDeleteFromScalar 1356 } 1357 func (jsonNumber) RemoveString(string) (JSON, bool, error) { 1358 return nil, false, errCannotDeleteFromScalar 1359 } 1360 1361 func (j jsonArray) RemoveIndex(idx int) (JSON, bool, error) { 1362 if idx < 0 { 1363 idx = len(j) + idx 1364 } 1365 if idx < 0 || idx >= len(j) { 1366 return j, false, nil 1367 } 1368 result := make(jsonArray, len(j)-1) 1369 for i := 0; i < idx; i++ { 1370 result[i] = j[i] 1371 } 1372 for i := idx + 1; i < len(j); i++ { 1373 result[i-1] = j[i] 1374 } 1375 return result, true, nil 1376 } 1377 1378 func (j jsonObject) RemoveIndex(int) (JSON, bool, error) { 1379 return nil, false, errCannotDeleteFromObject 1380 } 1381 1382 func (jsonNull) RemoveIndex(int) (JSON, bool, error) { return nil, false, errCannotDeleteFromScalar } 1383 func (jsonTrue) RemoveIndex(int) (JSON, bool, error) { return nil, false, errCannotDeleteFromScalar } 1384 func (jsonFalse) RemoveIndex(int) (JSON, bool, error) { return nil, false, errCannotDeleteFromScalar } 1385 func (jsonString) RemoveIndex(int) (JSON, bool, error) { return nil, false, errCannotDeleteFromScalar } 1386 func (jsonNumber) RemoveIndex(int) (JSON, bool, error) { return nil, false, errCannotDeleteFromScalar } 1387 1388 var errInvalidConcat = pgerror.WithCandidateCode(errors.New("invalid concatenation of jsonb objects"), pgcode.InvalidParameterValue) 1389 1390 func scalarConcat(left, other JSON) (JSON, error) { 1391 switch other.Type() { 1392 case ArrayJSONType: 1393 decoded, err := other.tryDecode() 1394 if err != nil { 1395 return nil, err 1396 } 1397 right := decoded.(jsonArray) 1398 result := make(jsonArray, len(right)+1) 1399 result[0] = left 1400 for i := range right { 1401 result[i+1] = right[i] 1402 } 1403 return result, nil 1404 case ObjectJSONType: 1405 return nil, errInvalidConcat 1406 default: 1407 return jsonArray{left, other}, nil 1408 } 1409 } 1410 1411 func (jsonNull) Concat(other JSON) (JSON, error) { return scalarConcat(NullJSONValue, other) } 1412 func (jsonTrue) Concat(other JSON) (JSON, error) { return scalarConcat(TrueJSONValue, other) } 1413 func (jsonFalse) Concat(other JSON) (JSON, error) { return scalarConcat(FalseJSONValue, other) } 1414 func (j jsonString) Concat(other JSON) (JSON, error) { return scalarConcat(j, other) } 1415 func (j jsonNumber) Concat(other JSON) (JSON, error) { return scalarConcat(j, other) } 1416 1417 func (j jsonArray) Concat(other JSON) (JSON, error) { 1418 left := j 1419 switch other.Type() { 1420 case ArrayJSONType: 1421 decoded, err := other.tryDecode() 1422 if err != nil { 1423 return nil, err 1424 } 1425 right := decoded.(jsonArray) 1426 result := make(jsonArray, len(left)+len(right)) 1427 for i := range left { 1428 result[i] = left[i] 1429 } 1430 for i := range right { 1431 result[len(left)+i] = right[i] 1432 } 1433 return result, nil 1434 default: 1435 result := make(jsonArray, len(left)+1) 1436 for i := range left { 1437 result[i] = left[i] 1438 } 1439 result[len(left)] = other 1440 return result, nil 1441 } 1442 } 1443 1444 func (j jsonObject) Concat(other JSON) (JSON, error) { 1445 switch other.Type() { 1446 case ArrayJSONType: 1447 return scalarConcat(j, other) 1448 case ObjectJSONType: 1449 right := other.MaybeDecode().(jsonObject) 1450 // Since both objects are sorted, we can do the merge sort thing to 1451 // "concatenate" them. 1452 // The capacity here is an overestimate if the two objects share keys. 1453 result := make(jsonObject, 0, len(j)+len(right)) 1454 rightIdx := 0 1455 for _, kv := range j { 1456 for rightIdx < len(right) && right[rightIdx].k < kv.k { 1457 result = append(result, right[rightIdx]) 1458 rightIdx++ 1459 } 1460 // If we have any matching keys, the value in the right object takes 1461 // precedence (this allows || to work as a setter). 1462 if rightIdx < len(right) && right[rightIdx].k == kv.k { 1463 result = append(result, right[rightIdx]) 1464 rightIdx++ 1465 } else { 1466 result = append(result, kv) 1467 } 1468 } 1469 // We've exhausted all of the key-value pairs on the left, so just dump in 1470 // the remaining ones from the right. 1471 for i := rightIdx; i < len(right); i++ { 1472 result = append(result, right[i]) 1473 } 1474 return result, nil 1475 default: 1476 return nil, errInvalidConcat 1477 } 1478 } 1479 1480 func (j jsonString) AsText() (*string, error) { 1481 s := string(j) 1482 return &s, nil 1483 } 1484 func (j jsonNull) AsText() (*string, error) { return nil, nil } 1485 func (j jsonTrue) AsText() (*string, error) { 1486 s := j.String() 1487 return &s, nil 1488 } 1489 func (j jsonFalse) AsText() (*string, error) { 1490 s := j.String() 1491 return &s, nil 1492 } 1493 func (j jsonNumber) AsText() (*string, error) { 1494 s := j.String() 1495 return &s, nil 1496 } 1497 func (j jsonArray) AsText() (*string, error) { 1498 s := j.String() 1499 return &s, nil 1500 } 1501 func (j jsonObject) AsText() (*string, error) { 1502 s := j.String() 1503 return &s, nil 1504 } 1505 1506 func (jsonNull) Exists(string) (bool, error) { return false, nil } 1507 func (jsonTrue) Exists(string) (bool, error) { return false, nil } 1508 func (jsonFalse) Exists(string) (bool, error) { return false, nil } 1509 func (jsonNumber) Exists(string) (bool, error) { return false, nil } 1510 1511 func (j jsonString) Exists(s string) (bool, error) { 1512 return string(j) == s, nil 1513 } 1514 1515 func (j jsonArray) Exists(s string) (bool, error) { 1516 for i := 0; i < len(j); i++ { 1517 if elem, ok := j[i].(jsonString); ok && string(elem) == s { 1518 return true, nil 1519 } 1520 } 1521 return false, nil 1522 } 1523 func (j jsonObject) Exists(s string) (bool, error) { 1524 v, err := j.FetchValKey(s) 1525 if err != nil { 1526 return false, err 1527 } 1528 return v != nil, nil 1529 } 1530 1531 func (j jsonNull) StripNulls() (JSON, bool, error) { 1532 return j, false, nil 1533 } 1534 func (j jsonTrue) StripNulls() (JSON, bool, error) { 1535 return j, false, nil 1536 } 1537 func (j jsonFalse) StripNulls() (JSON, bool, error) { 1538 return j, false, nil 1539 } 1540 func (j jsonNumber) StripNulls() (JSON, bool, error) { 1541 return j, false, nil 1542 } 1543 func (j jsonString) StripNulls() (JSON, bool, error) { 1544 return j, false, nil 1545 } 1546 func (j jsonArray) StripNulls() (JSON, bool, error) { 1547 for i, e := range j { 1548 json, needToStrip, err := e.StripNulls() 1549 if err != nil { 1550 return nil, false, err 1551 } 1552 if needToStrip { 1553 // Cannot return the original content, need to return the result 1554 // with new JSON array. 1555 newArr := make(jsonArray, 0, len(j)) 1556 newArr = append(append(newArr, j[:i]...), json) 1557 for _, elem := range j[i+1:] { 1558 if json, _, err = elem.StripNulls(); err != nil { 1559 return nil, false, err 1560 } 1561 newArr = append(newArr, json) 1562 } 1563 return newArr, true, nil 1564 } 1565 } 1566 return j, false, nil 1567 } 1568 func (j jsonObject) StripNulls() (JSON, bool, error) { 1569 for i, e := range j { 1570 var json JSON 1571 var err error 1572 needToStrip := false 1573 hasNullValue := e.v.Type() == NullJSONType 1574 if !hasNullValue { 1575 json, needToStrip, err = e.v.StripNulls() 1576 if err != nil { 1577 return nil, false, err 1578 } 1579 } 1580 if hasNullValue || needToStrip { 1581 // Cannot return the original content, need to return the result 1582 // with new JSON object. 1583 numNotNulls := i 1584 for _, elem := range j[i:] { 1585 if elem.v.Type() != NullJSONType { 1586 numNotNulls++ 1587 } 1588 } 1589 // Use number of fields not having null value to construct newObj 1590 // so that no need to grow the capacity of newObj. 1591 newObj := make(jsonObject, 0, numNotNulls) 1592 newObj = append(newObj, j[:i]...) 1593 if !hasNullValue { 1594 newObj = append(newObj, jsonKeyValuePair{ 1595 k: e.k, 1596 v: json, 1597 }) 1598 } 1599 for _, elem := range j[i+1:] { 1600 if elem.v.Type() != NullJSONType { 1601 if json, _, err = elem.v.StripNulls(); err != nil { 1602 return nil, false, err 1603 } 1604 newObj = append(newObj, jsonKeyValuePair{ 1605 k: elem.k, 1606 v: json, 1607 }) 1608 } 1609 } 1610 return newObj, true, nil 1611 } 1612 } 1613 return j, false, nil 1614 } 1615 1616 func (jsonNull) ObjectIter() (*ObjectIterator, error) { 1617 return nil, nil 1618 } 1619 func (jsonTrue) ObjectIter() (*ObjectIterator, error) { 1620 return nil, nil 1621 } 1622 func (jsonFalse) ObjectIter() (*ObjectIterator, error) { 1623 return nil, nil 1624 } 1625 func (jsonNumber) ObjectIter() (*ObjectIterator, error) { 1626 return nil, nil 1627 } 1628 func (jsonString) ObjectIter() (*ObjectIterator, error) { 1629 return nil, nil 1630 } 1631 func (jsonArray) ObjectIter() (*ObjectIterator, error) { 1632 return nil, nil 1633 } 1634 func (j jsonObject) ObjectIter() (*ObjectIterator, error) { 1635 return newObjectIterator(j), nil 1636 } 1637 1638 func (jsonNull) isScalar() bool { return true } 1639 func (jsonFalse) isScalar() bool { return true } 1640 func (jsonTrue) isScalar() bool { return true } 1641 func (jsonNumber) isScalar() bool { return true } 1642 func (jsonString) isScalar() bool { return true } 1643 func (jsonArray) isScalar() bool { return false } 1644 func (jsonObject) isScalar() bool { return false } 1645 1646 func (jsonNull) Len() int { return 0 } 1647 func (jsonTrue) Len() int { return 0 } 1648 func (jsonFalse) Len() int { return 0 } 1649 func (jsonNumber) Len() int { return 0 } 1650 func (jsonString) Len() int { return 0 } 1651 func (j jsonArray) Len() int { return len(j) } 1652 func (j jsonObject) Len() int { return len(j) } 1653 1654 func (jsonNull) toGoRepr() (interface{}, error) { return nil, nil } 1655 func (jsonTrue) toGoRepr() (interface{}, error) { return true, nil } 1656 func (jsonFalse) toGoRepr() (interface{}, error) { return false, nil } 1657 func (j jsonString) toGoRepr() (interface{}, error) { return string(j), nil } 1658 func (j jsonNumber) toGoRepr() (interface{}, error) { return json.Number(j.String()), nil } 1659 func (j jsonArray) toGoRepr() (interface{}, error) { 1660 result := make([]interface{}, len(j)) 1661 for i, e := range j { 1662 next, err := e.toGoRepr() 1663 if err != nil { 1664 return nil, err 1665 } 1666 result[i] = next 1667 } 1668 return result, nil 1669 } 1670 func (j jsonObject) toGoRepr() (interface{}, error) { 1671 result := make(map[string]interface{}) 1672 for _, e := range j { 1673 next, err := e.v.toGoRepr() 1674 if err != nil { 1675 return nil, err 1676 } 1677 result[string(e.k)] = next 1678 } 1679 return result, nil 1680 } 1681 1682 // Pretty pretty-prints the given JSON document as required by jsonb_pretty. 1683 func Pretty(j JSON) (string, error) { 1684 asGo, err := j.toGoRepr() 1685 if err != nil { 1686 return "", err 1687 } 1688 // Luckily for us, despite Go's random map ordering, MarshalIndent sorts the 1689 // keys of objects. 1690 res, err := json.MarshalIndent(asGo, "", " ") 1691 return string(res), errors.Handled(err) 1692 } 1693 1694 var errCannotDeletePathInScalar = pgerror.WithCandidateCode(errors.New("cannot delete path in scalar"), pgcode.InvalidParameterValue) 1695 1696 func (j jsonArray) RemovePath(path []string) (JSON, bool, error) { return j.doRemovePath(path) } 1697 func (j jsonObject) RemovePath(path []string) (JSON, bool, error) { return j.doRemovePath(path) } 1698 func (jsonNull) RemovePath([]string) (JSON, bool, error) { 1699 return nil, false, errCannotDeletePathInScalar 1700 } 1701 func (jsonTrue) RemovePath([]string) (JSON, bool, error) { 1702 return nil, false, errCannotDeletePathInScalar 1703 } 1704 func (jsonFalse) RemovePath([]string) (JSON, bool, error) { 1705 return nil, false, errCannotDeletePathInScalar 1706 } 1707 func (jsonString) RemovePath([]string) (JSON, bool, error) { 1708 return nil, false, errCannotDeletePathInScalar 1709 } 1710 func (jsonNumber) RemovePath([]string) (JSON, bool, error) { 1711 return nil, false, errCannotDeletePathInScalar 1712 } 1713 1714 func (j jsonArray) doRemovePath(path []string) (JSON, bool, error) { 1715 if len(path) == 0 { 1716 return j, false, nil 1717 } 1718 // In path-deletion we have to attempt to parse numbers (this is different 1719 // from the `-` operator, where strings just never match on arrays). 1720 idx, err := strconv.Atoi(path[0]) 1721 if err != nil { 1722 // TODO(yuzefovich): give the position of the path element to match psql. 1723 err := errors.Newf("a path element is not an integer: %s", path[0]) 1724 err = pgerror.WithCandidateCode(err, pgcode.InvalidTextRepresentation) 1725 return j, false, err 1726 } 1727 if len(path) == 1 { 1728 return j.RemoveIndex(idx) 1729 } 1730 1731 if idx < -len(j) || idx >= len(j) { 1732 return j, false, nil 1733 } 1734 if idx < 0 { 1735 idx += len(j) 1736 } 1737 newVal, ok, err := j[idx].doRemovePath(path[1:]) 1738 if err != nil { 1739 return nil, false, err 1740 } 1741 if !ok { 1742 return j, false, nil 1743 } 1744 1745 result := make(jsonArray, len(j)) 1746 for i := range j { 1747 result[i] = j[i] 1748 } 1749 result[idx] = newVal 1750 1751 return result, true, nil 1752 } 1753 1754 func (j jsonObject) doRemovePath(path []string) (JSON, bool, error) { 1755 if len(path) == 0 { 1756 return j, false, nil 1757 } 1758 if len(path) == 1 { 1759 return j.RemoveString(path[0]) 1760 } 1761 idx, ok := findPairIndexByKey(j, path[0]) 1762 if !ok { 1763 return j, false, nil 1764 } 1765 1766 newVal, ok, err := j[idx].v.doRemovePath(path[1:]) 1767 if err != nil { 1768 return nil, false, err 1769 } 1770 if !ok { 1771 return j, false, nil 1772 } 1773 1774 result := make(jsonObject, len(j)) 1775 for i := range j { 1776 result[i] = j[i] 1777 } 1778 result[idx].v = newVal 1779 1780 return result, true, nil 1781 } 1782 1783 // When we hit a scalar, we stop. #- only errors if there's a scalar at the 1784 // very top level. 1785 func (j jsonNull) doRemovePath([]string) (JSON, bool, error) { return j, false, nil } 1786 func (j jsonTrue) doRemovePath([]string) (JSON, bool, error) { return j, false, nil } 1787 func (j jsonFalse) doRemovePath([]string) (JSON, bool, error) { return j, false, nil } 1788 func (j jsonString) doRemovePath([]string) (JSON, bool, error) { return j, false, nil } 1789 func (j jsonNumber) doRemovePath([]string) (JSON, bool, error) { return j, false, nil } 1790 1791 func (j jsonObject) HasContainerLeaf() (bool, error) { 1792 if j.Len() == 0 { 1793 return true, nil 1794 } 1795 for _, c := range j { 1796 child, err := c.v.HasContainerLeaf() 1797 if err != nil { 1798 return false, err 1799 } 1800 if child { 1801 return true, nil 1802 } 1803 } 1804 return false, nil 1805 } 1806 1807 func (j jsonArray) HasContainerLeaf() (bool, error) { 1808 if j.Len() == 0 { 1809 return true, nil 1810 } 1811 for _, c := range j { 1812 child, err := c.HasContainerLeaf() 1813 if err != nil { 1814 return false, err 1815 } 1816 if child { 1817 return true, nil 1818 } 1819 } 1820 return false, nil 1821 } 1822 1823 func (j jsonNull) HasContainerLeaf() (bool, error) { return false, nil } 1824 func (j jsonTrue) HasContainerLeaf() (bool, error) { return false, nil } 1825 func (j jsonFalse) HasContainerLeaf() (bool, error) { return false, nil } 1826 func (j jsonString) HasContainerLeaf() (bool, error) { return false, nil } 1827 func (j jsonNumber) HasContainerLeaf() (bool, error) { return false, nil }