1 /*-------------------------------------------------------------------------
4 * converting between Jsonb and JsonbValues, and iterating.
6 * Copyright (c) 2014-2019, PostgreSQL Global Development Group
10 * src/backend/utils/adt/jsonb_util.c
12 *-------------------------------------------------------------------------
16 #include "catalog/pg_collation.h"
17 #include "catalog/pg_type.h"
18 #include "miscadmin.h"
19 #include "utils/builtins.h"
20 #include "utils/datetime.h"
21 #include "utils/hashutils.h"
22 #include "utils/jsonapi.h"
23 #include "utils/jsonb.h"
24 #include "utils/memutils.h"
25 #include "utils/varlena.h"
28 * Maximum number of elements in an array (or key/value pairs in an object).
29 * This is limited by two things: the size of the JEntry array must fit
30 * in MaxAllocSize, and the number of elements (or pairs) must fit in the bits
31 * reserved for that in the JsonbContainer.header field.
33 * (The total size of an array's or object's elements is also limited by
34 * JENTRY_OFFLENMASK, but we're not concerned about that here.)
36 #define JSONB_MAX_ELEMS (Min(MaxAllocSize / sizeof(JsonbValue), JB_CMASK))
37 #define JSONB_MAX_PAIRS (Min(MaxAllocSize / sizeof(JsonbPair), JB_CMASK))
39 static void fillJsonbValue(JsonbContainer *container, int index,
40 char *base_addr, uint32 offset,
42 static bool equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b);
43 static int compareJsonbScalarValue(JsonbValue *a, JsonbValue *b);
44 static Jsonb *convertToJsonb(JsonbValue *val);
45 static void convertJsonbValue(StringInfo buffer, JEntry *header, JsonbValue *val, int level);
46 static void convertJsonbArray(StringInfo buffer, JEntry *header, JsonbValue *val, int level);
47 static void convertJsonbObject(StringInfo buffer, JEntry *header, JsonbValue *val, int level);
48 static void convertJsonbScalar(StringInfo buffer, JEntry *header, JsonbValue *scalarVal);
50 static int reserveFromBuffer(StringInfo buffer, int len);
51 static void appendToBuffer(StringInfo buffer, const char *data, int len);
52 static void copyToBuffer(StringInfo buffer, int offset, const char *data, int len);
53 static short padBufferToInt(StringInfo buffer);
55 static JsonbIterator *iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent);
56 static JsonbIterator *freeAndGetParent(JsonbIterator *it);
57 static JsonbParseState *pushState(JsonbParseState **pstate);
58 static void appendKey(JsonbParseState *pstate, JsonbValue *scalarVal);
59 static void appendValue(JsonbParseState *pstate, JsonbValue *scalarVal);
60 static void appendElement(JsonbParseState *pstate, JsonbValue *scalarVal);
61 static int lengthCompareJsonbStringValue(const void *a, const void *b);
62 static int lengthCompareJsonbString(const char *val1, int len1,
63 const char *val2, int len2);
64 static int lengthCompareJsonbPair(const void *a, const void *b, void *arg);
65 static void uniqueifyJsonbObject(JsonbValue *object);
66 static JsonbValue *pushJsonbValueScalar(JsonbParseState **pstate,
67 JsonbIteratorToken seq,
68 JsonbValue *scalarVal);
71 * Turn an in-memory JsonbValue into a Jsonb for on-disk storage.
73 * There isn't a JsonbToJsonbValue(), because generally we find it more
74 * convenient to directly iterate through the Jsonb representation and only
75 * really convert nested scalar values. JsonbIteratorNext() does this, so that
76 * clients of the iteration code don't have to directly deal with the binary
77 * representation (JsonbDeepContains() is a notable exception, although all
78 * exceptions are internal to this module). In general, functions that accept
79 * a JsonbValue argument are concerned with the manipulation of scalar values,
80 * or simple containers of scalar values, where it would be inconvenient to
81 * deal with a great amount of other state.
84 JsonbValueToJsonb(JsonbValue *val)
88 if (IsAJsonbScalar(val))
91 JsonbParseState *pstate = NULL;
93 JsonbValue scalarArray;
95 scalarArray.type = jbvArray;
96 scalarArray.val.array.rawScalar = true;
97 scalarArray.val.array.nElems = 1;
99 pushJsonbValue(&pstate, WJB_BEGIN_ARRAY, &scalarArray);
100 pushJsonbValue(&pstate, WJB_ELEM, val);
101 res = pushJsonbValue(&pstate, WJB_END_ARRAY, NULL);
103 out = convertToJsonb(res);
105 else if (val->type == jbvObject || val->type == jbvArray)
107 out = convertToJsonb(val);
111 Assert(val->type == jbvBinary);
112 out = palloc(VARHDRSZ + val->val.binary.len);
113 SET_VARSIZE(out, VARHDRSZ + val->val.binary.len);
114 memcpy(VARDATA(out), val->val.binary.data, val->val.binary.len);
121 * Get the offset of the variable-length portion of a Jsonb node within
122 * the variable-length-data part of its container. The node is identified
123 * by index within the container's JEntry array.
126 getJsonbOffset(const JsonbContainer *jc, int index)
132 * Start offset of this entry is equal to the end offset of the previous
133 * entry. Walk backwards to the most recent entry stored as an end
134 * offset, returning that offset plus any lengths in between.
136 for (i = index - 1; i >= 0; i--)
138 offset += JBE_OFFLENFLD(jc->children[i]);
139 if (JBE_HAS_OFF(jc->children[i]))
147 * Get the length of the variable-length portion of a Jsonb node.
148 * The node is identified by index within the container's JEntry array.
151 getJsonbLength(const JsonbContainer *jc, int index)
157 * If the length is stored directly in the JEntry, just return it.
158 * Otherwise, get the begin offset of the entry, and subtract that from
159 * the stored end+1 offset.
161 if (JBE_HAS_OFF(jc->children[index]))
163 off = getJsonbOffset(jc, index);
164 len = JBE_OFFLENFLD(jc->children[index]) - off;
167 len = JBE_OFFLENFLD(jc->children[index]);
173 * BT comparator worker function. Returns an integer less than, equal to, or
174 * greater than zero, indicating whether a is less than, equal to, or greater
175 * than b. Consistent with the requirements for a B-Tree operator class
177 * Strings are compared lexically, in contrast with other places where we use a
178 * much simpler comparator logic for searching through Strings. Since this is
179 * called from B-Tree support function 1, we're careful about not leaking
183 compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
189 ita = JsonbIteratorInit(a);
190 itb = JsonbIteratorInit(b);
196 JsonbIteratorToken ra,
199 ra = JsonbIteratorNext(&ita, &va, false);
200 rb = JsonbIteratorNext(&itb, &vb, false);
206 /* Decisively equal */
210 if (ra == WJB_END_ARRAY || ra == WJB_END_OBJECT)
213 * There is no array or object to compare at this stage of
214 * processing. jbvArray/jbvObject values are compared
215 * initially, at the WJB_BEGIN_ARRAY and WJB_BEGIN_OBJECT
221 if (va.type == vb.type)
229 res = compareJsonbScalarValue(&va, &vb);
234 * This could be a "raw scalar" pseudo array. That's
235 * a special case here though, since we still want the
236 * general type-based comparisons to apply, and as far
237 * as we're concerned a pseudo array is just a scalar.
239 if (va.val.array.rawScalar != vb.val.array.rawScalar)
240 res = (va.val.array.rawScalar) ? -1 : 1;
241 if (va.val.array.nElems != vb.val.array.nElems)
242 res = (va.val.array.nElems > vb.val.array.nElems) ? 1 : -1;
245 if (va.val.object.nPairs != vb.val.object.nPairs)
246 res = (va.val.object.nPairs > vb.val.object.nPairs) ? 1 : -1;
249 elog(ERROR, "unexpected jbvBinary value");
251 elog(ERROR, "unexpected jbvDatetime value");
256 /* Type-defined order */
257 res = (va.type > vb.type) ? 1 : -1;
263 * It's safe to assume that the types differed, and that the va
264 * and vb values passed were set.
266 * If the two values were of the same container type, then there'd
267 * have been a chance to observe the variation in the number of
268 * elements/pairs (when processing WJB_BEGIN_OBJECT, say). They're
269 * either two heterogeneously-typed containers, or a container and
272 * We don't have to consider the WJB_END_ARRAY and WJB_END_OBJECT
273 * cases here, because we would have seen the corresponding
274 * WJB_BEGIN_ARRAY and WJB_BEGIN_OBJECT tokens first, and
275 * concluded that they don't match.
277 Assert(ra != WJB_END_ARRAY && ra != WJB_END_OBJECT);
278 Assert(rb != WJB_END_ARRAY && rb != WJB_END_OBJECT);
280 Assert(va.type != vb.type);
281 Assert(va.type != jbvBinary);
282 Assert(vb.type != jbvBinary);
283 /* Type-defined order */
284 res = (va.type > vb.type) ? 1 : -1;
291 JsonbIterator *i = ita->parent;
298 JsonbIterator *i = itb->parent;
308 * Find value in object (i.e. the "value" part of some key/value pair in an
309 * object), or find a matching element if we're looking through an array. Do
310 * so on the basis of equality of the object keys only, or alternatively
311 * element values only, with a caller-supplied value "key". The "flags"
312 * argument allows the caller to specify which container types are of interest.
314 * This exported utility function exists to facilitate various cases concerned
315 * with "containment". If asked to look through an object, the caller had
316 * better pass a Jsonb String, because their keys can only be strings.
317 * Otherwise, for an array, any type of JsonbValue will do.
319 * In order to proceed with the search, it is necessary for callers to have
320 * both specified an interest in exactly one particular container type with an
321 * appropriate flag, as well as having the pointed-to Jsonb container be of
322 * one of those same container types at the top level. (Actually, we just do
323 * whichever makes sense to save callers the trouble of figuring it out - at
324 * most one can make sense, because the container either points to an array
325 * (possibly a "raw scalar" pseudo array) or an object.)
327 * Note that we can return a jbvBinary JsonbValue if this is called on an
328 * object, but we never do so on an array. If the caller asks to look through
329 * a container type that is not of the type pointed to by the container,
330 * immediately fall through and return NULL. If we cannot find the value,
331 * return NULL. Otherwise, return palloc()'d copy of value.
334 findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
337 JEntry *children = container->children;
338 int count = JsonContainerSize(container);
340 Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
342 /* Quick out without a palloc cycle if object/array is empty */
346 if ((flags & JB_FARRAY) && JsonContainerIsArray(container))
348 JsonbValue *result = palloc(sizeof(JsonbValue));
349 char *base_addr = (char *) (children + count);
353 for (i = 0; i < count; i++)
355 fillJsonbValue(container, i, base_addr, offset, result);
357 if (key->type == result->type)
359 if (equalsJsonbScalarValue(key, result))
363 JBE_ADVANCE_OFFSET(offset, children[i]);
368 else if ((flags & JB_FOBJECT) && JsonContainerIsObject(container))
370 /* Object key passed by caller must be a string */
371 Assert(key->type == jbvString);
373 return getKeyJsonValueFromContainer(container, key->val.string.val,
374 key->val.string.len, NULL);
382 * Find value by key in Jsonb object and fetch it into 'res', which is also
385 * 'res' can be passed in as NULL, in which case it's newly palloc'ed here.
388 getKeyJsonValueFromContainer(JsonbContainer *container,
389 const char *keyVal, int keyLen, JsonbValue *res)
391 JEntry *children = container->children;
392 int count = JsonContainerSize(container);
397 Assert(JsonContainerIsObject(container));
399 /* Quick out without a palloc cycle if object is empty */
404 * Binary search the container. Since we know this is an object, account
405 * for *Pairs* of Jentrys
407 baseAddr = (char *) (children + count * 2);
410 while (stopLow < stopHigh)
414 const char *candidateVal;
417 stopMiddle = stopLow + (stopHigh - stopLow) / 2;
419 candidateVal = baseAddr + getJsonbOffset(container, stopMiddle);
420 candidateLen = getJsonbLength(container, stopMiddle);
422 difference = lengthCompareJsonbString(candidateVal, candidateLen,
427 /* Found our key, return corresponding value */
428 int index = stopMiddle + count;
431 res = palloc(sizeof(JsonbValue));
433 fillJsonbValue(container, index, baseAddr,
434 getJsonbOffset(container, index),
442 stopLow = stopMiddle + 1;
444 stopHigh = stopMiddle;
453 * Get i-th value of a Jsonb array.
455 * Returns palloc()'d copy of the value, or NULL if it does not exist.
458 getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)
464 if (!JsonContainerIsArray(container))
465 elog(ERROR, "not a jsonb array");
467 nelements = JsonContainerSize(container);
468 base_addr = (char *) &container->children[nelements];
473 result = palloc(sizeof(JsonbValue));
475 fillJsonbValue(container, i, base_addr,
476 getJsonbOffset(container, i),
483 * A helper function to fill in a JsonbValue to represent an element of an
484 * array, or a key or value of an object.
486 * The node's JEntry is at container->children[index], and its variable-length
487 * data is at base_addr + offset. We make the caller determine the offset
488 * since in many cases the caller can amortize that work across multiple
489 * children. When it can't, it can just call getJsonbOffset().
491 * A nested array or object will be returned as jbvBinary, ie. it won't be
495 fillJsonbValue(JsonbContainer *container, int index,
496 char *base_addr, uint32 offset,
499 JEntry entry = container->children[index];
501 if (JBE_ISNULL(entry))
503 result->type = jbvNull;
505 else if (JBE_ISSTRING(entry))
507 result->type = jbvString;
508 result->val.string.val = base_addr + offset;
509 result->val.string.len = getJsonbLength(container, index);
510 Assert(result->val.string.len >= 0);
512 else if (JBE_ISNUMERIC(entry))
514 result->type = jbvNumeric;
515 result->val.numeric = (Numeric) (base_addr + INTALIGN(offset));
517 else if (JBE_ISBOOL_TRUE(entry))
519 result->type = jbvBool;
520 result->val.boolean = true;
522 else if (JBE_ISBOOL_FALSE(entry))
524 result->type = jbvBool;
525 result->val.boolean = false;
529 Assert(JBE_ISCONTAINER(entry));
530 result->type = jbvBinary;
531 /* Remove alignment padding from data pointer and length */
532 result->val.binary.data = (JsonbContainer *) (base_addr + INTALIGN(offset));
533 result->val.binary.len = getJsonbLength(container, index) -
534 (INTALIGN(offset) - offset);
539 * Push JsonbValue into JsonbParseState.
541 * Used when parsing JSON tokens to form Jsonb, or when converting an in-memory
542 * JsonbValue to a Jsonb.
544 * Initial state of *JsonbParseState is NULL, since it'll be allocated here
545 * originally (caller will get JsonbParseState back by reference).
547 * Only sequential tokens pertaining to non-container types should pass a
548 * JsonbValue. There is one exception -- WJB_BEGIN_ARRAY callers may pass a
549 * "raw scalar" pseudo array to append it - the actual scalar should be passed
550 * next and it will be added as the only member of the array.
552 * Values of type jbvBinary, which are rolled up arrays and objects,
553 * are unpacked before being added to the result.
556 pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq,
560 JsonbValue *res = NULL;
562 JsonbIteratorToken tok;
564 if (!jbval || (seq != WJB_ELEM && seq != WJB_VALUE) ||
565 jbval->type != jbvBinary)
568 return pushJsonbValueScalar(pstate, seq, jbval);
571 /* unpack the binary and add each piece to the pstate */
572 it = JsonbIteratorInit(jbval->val.binary.data);
573 while ((tok = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
574 res = pushJsonbValueScalar(pstate, tok,
575 tok < WJB_BEGIN_ARRAY ? &v : NULL);
581 * Do the actual pushing, with only scalar or pseudo-scalar-array values
585 pushJsonbValueScalar(JsonbParseState **pstate, JsonbIteratorToken seq,
586 JsonbValue *scalarVal)
588 JsonbValue *result = NULL;
592 case WJB_BEGIN_ARRAY:
593 Assert(!scalarVal || scalarVal->val.array.rawScalar);
594 *pstate = pushState(pstate);
595 result = &(*pstate)->contVal;
596 (*pstate)->contVal.type = jbvArray;
597 (*pstate)->contVal.val.array.nElems = 0;
598 (*pstate)->contVal.val.array.rawScalar = (scalarVal &&
599 scalarVal->val.array.rawScalar);
600 if (scalarVal && scalarVal->val.array.nElems > 0)
602 /* Assume that this array is still really a scalar */
603 Assert(scalarVal->type == jbvArray);
604 (*pstate)->size = scalarVal->val.array.nElems;
610 (*pstate)->contVal.val.array.elems = palloc(sizeof(JsonbValue) *
613 case WJB_BEGIN_OBJECT:
615 *pstate = pushState(pstate);
616 result = &(*pstate)->contVal;
617 (*pstate)->contVal.type = jbvObject;
618 (*pstate)->contVal.val.object.nPairs = 0;
620 (*pstate)->contVal.val.object.pairs = palloc(sizeof(JsonbPair) *
624 Assert(scalarVal->type == jbvString);
625 appendKey(*pstate, scalarVal);
628 Assert(IsAJsonbScalar(scalarVal));
629 appendValue(*pstate, scalarVal);
632 Assert(IsAJsonbScalar(scalarVal));
633 appendElement(*pstate, scalarVal);
636 uniqueifyJsonbObject(&(*pstate)->contVal);
639 /* Steps here common to WJB_END_OBJECT case */
641 result = &(*pstate)->contVal;
644 * Pop stack and push current array/object as value in parent
647 *pstate = (*pstate)->next;
650 switch ((*pstate)->contVal.type)
653 appendElement(*pstate, result);
656 appendValue(*pstate, result);
659 elog(ERROR, "invalid jsonb container type");
664 elog(ERROR, "unrecognized jsonb sequential processing token");
671 * pushJsonbValue() worker: Iteration-like forming of Jsonb
673 static JsonbParseState *
674 pushState(JsonbParseState **pstate)
676 JsonbParseState *ns = palloc(sizeof(JsonbParseState));
683 * pushJsonbValue() worker: Append a pair key to state when generating a Jsonb
686 appendKey(JsonbParseState *pstate, JsonbValue *string)
688 JsonbValue *object = &pstate->contVal;
690 Assert(object->type == jbvObject);
691 Assert(string->type == jbvString);
693 if (object->val.object.nPairs >= JSONB_MAX_PAIRS)
695 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
696 errmsg("number of jsonb object pairs exceeds the maximum allowed (%zu)",
699 if (object->val.object.nPairs >= pstate->size)
702 object->val.object.pairs = repalloc(object->val.object.pairs,
703 sizeof(JsonbPair) * pstate->size);
706 object->val.object.pairs[object->val.object.nPairs].key = *string;
707 object->val.object.pairs[object->val.object.nPairs].order = object->val.object.nPairs;
711 * pushJsonbValue() worker: Append a pair value to state when generating a
715 appendValue(JsonbParseState *pstate, JsonbValue *scalarVal)
717 JsonbValue *object = &pstate->contVal;
719 Assert(object->type == jbvObject);
721 object->val.object.pairs[object->val.object.nPairs++].value = *scalarVal;
725 * pushJsonbValue() worker: Append an element to state when generating a Jsonb
728 appendElement(JsonbParseState *pstate, JsonbValue *scalarVal)
730 JsonbValue *array = &pstate->contVal;
732 Assert(array->type == jbvArray);
734 if (array->val.array.nElems >= JSONB_MAX_ELEMS)
736 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
737 errmsg("number of jsonb array elements exceeds the maximum allowed (%zu)",
740 if (array->val.array.nElems >= pstate->size)
743 array->val.array.elems = repalloc(array->val.array.elems,
744 sizeof(JsonbValue) * pstate->size);
747 array->val.array.elems[array->val.array.nElems++] = *scalarVal;
751 * Given a JsonbContainer, expand to JsonbIterator to iterate over items
752 * fully expanded to in-memory representation for manipulation.
754 * See JsonbIteratorNext() for notes on memory management.
757 JsonbIteratorInit(JsonbContainer *container)
759 return iteratorFromContainer(container, NULL);
763 * Get next JsonbValue while iterating
765 * Caller should initially pass their own, original iterator. They may get
766 * back a child iterator palloc()'d here instead. The function can be relied
767 * on to free those child iterators, lest the memory allocated for highly
768 * nested objects become unreasonable, but only if callers don't end iteration
769 * early (by breaking upon having found something in a search, for example).
771 * Callers in such a scenario, that are particularly sensitive to leaking
772 * memory in a long-lived context may walk the ancestral tree from the final
773 * iterator we left them with to its oldest ancestor, pfree()ing as they go.
774 * They do not have to free any other memory previously allocated for iterators
775 * but not accessible as direct ancestors of the iterator they're last passed
778 * Returns "Jsonb sequential processing" token value. Iterator "state"
779 * reflects the current stage of the process in a less granular fashion, and is
780 * mostly used here to track things internally with respect to particular
783 * Clients of this function should not have to handle any jbvBinary values
784 * (since recursive calls will deal with this), provided skipNested is false.
785 * It is our job to expand the jbvBinary representation without bothering them
786 * with it. However, clients should not take it upon themselves to touch array
787 * or Object element/pair buffers, since their element/pair pointers are
788 * garbage. Also, *val will not be set when returning WJB_END_ARRAY or
789 * WJB_END_OBJECT, on the assumption that it's only useful to access values
793 JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
799 * When stepping into a nested container, we jump back here to start
800 * processing the child. We will not recurse further in one call, because
801 * processing the child will always begin in JBI_ARRAY_START or
802 * JBI_OBJECT_START state.
805 switch ((*it)->state)
807 case JBI_ARRAY_START:
808 /* Set v to array on first array call */
809 val->type = jbvArray;
810 val->val.array.nElems = (*it)->nElems;
813 * v->val.array.elems is not actually set, because we aren't doing
816 val->val.array.rawScalar = (*it)->isScalar;
818 (*it)->curDataOffset = 0;
819 (*it)->curValueOffset = 0; /* not actually used */
820 /* Set state for next call */
821 (*it)->state = JBI_ARRAY_ELEM;
822 return WJB_BEGIN_ARRAY;
825 if ((*it)->curIndex >= (*it)->nElems)
828 * All elements within array already processed. Report this
829 * to caller, and give it back original parent iterator (which
830 * independently tracks iteration progress at its level of
833 *it = freeAndGetParent(*it);
834 return WJB_END_ARRAY;
837 fillJsonbValue((*it)->container, (*it)->curIndex,
838 (*it)->dataProper, (*it)->curDataOffset,
841 JBE_ADVANCE_OFFSET((*it)->curDataOffset,
842 (*it)->children[(*it)->curIndex]);
845 if (!IsAJsonbScalar(val) && !skipNested)
847 /* Recurse into container. */
848 *it = iteratorFromContainer(val->val.binary.data, *it);
854 * Scalar item in array, or a container and caller didn't want
855 * us to recurse into it.
860 case JBI_OBJECT_START:
861 /* Set v to object on first object call */
862 val->type = jbvObject;
863 val->val.object.nPairs = (*it)->nElems;
866 * v->val.object.pairs is not actually set, because we aren't
867 * doing a full conversion
870 (*it)->curDataOffset = 0;
871 (*it)->curValueOffset = getJsonbOffset((*it)->container,
873 /* Set state for next call */
874 (*it)->state = JBI_OBJECT_KEY;
875 return WJB_BEGIN_OBJECT;
878 if ((*it)->curIndex >= (*it)->nElems)
881 * All pairs within object already processed. Report this to
882 * caller, and give it back original containing iterator
883 * (which independently tracks iteration progress at its level
886 *it = freeAndGetParent(*it);
887 return WJB_END_OBJECT;
891 /* Return key of a key/value pair. */
892 fillJsonbValue((*it)->container, (*it)->curIndex,
893 (*it)->dataProper, (*it)->curDataOffset,
895 if (val->type != jbvString)
896 elog(ERROR, "unexpected jsonb type as object key");
898 /* Set state for next call */
899 (*it)->state = JBI_OBJECT_VALUE;
903 case JBI_OBJECT_VALUE:
904 /* Set state for next call */
905 (*it)->state = JBI_OBJECT_KEY;
907 fillJsonbValue((*it)->container, (*it)->curIndex + (*it)->nElems,
908 (*it)->dataProper, (*it)->curValueOffset,
911 JBE_ADVANCE_OFFSET((*it)->curDataOffset,
912 (*it)->children[(*it)->curIndex]);
913 JBE_ADVANCE_OFFSET((*it)->curValueOffset,
914 (*it)->children[(*it)->curIndex + (*it)->nElems]);
918 * Value may be a container, in which case we recurse with new,
919 * child iterator (unless the caller asked not to, by passing
922 if (!IsAJsonbScalar(val) && !skipNested)
924 *it = iteratorFromContainer(val->val.binary.data, *it);
931 elog(ERROR, "invalid iterator state");
936 * Initialize an iterator for iterating all elements in a container.
938 static JsonbIterator *
939 iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent)
943 it = palloc0(sizeof(JsonbIterator));
944 it->container = container;
946 it->nElems = JsonContainerSize(container);
948 /* Array starts just after header */
949 it->children = container->children;
951 switch (container->header & (JB_FARRAY | JB_FOBJECT))
955 (char *) it->children + it->nElems * sizeof(JEntry);
956 it->isScalar = JsonContainerIsScalar(container);
957 /* This is either a "raw scalar", or an array */
958 Assert(!it->isScalar || it->nElems == 1);
960 it->state = JBI_ARRAY_START;
965 (char *) it->children + it->nElems * sizeof(JEntry) * 2;
966 it->state = JBI_OBJECT_START;
970 elog(ERROR, "unknown type of jsonb container");
977 * JsonbIteratorNext() worker: Return parent, while freeing memory for current
980 static JsonbIterator *
981 freeAndGetParent(JsonbIterator *it)
983 JsonbIterator *v = it->parent;
990 * Worker for "contains" operator's function
992 * Formally speaking, containment is top-down, unordered subtree isomorphism.
994 * Takes iterators that belong to some container type. These iterators
995 * "belong" to those values in the sense that they've just been initialized in
996 * respect of them by the caller (perhaps in a nested fashion).
998 * "val" is lhs Jsonb, and mContained is rhs Jsonb when called from top level.
999 * We determine if mContained is contained within val.
1002 JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
1006 JsonbIteratorToken rval,
1010 * Guard against stack overflow due to overly complex Jsonb.
1012 * Functions called here independently take this precaution, but that
1013 * might not be sufficient since this is also a recursive function.
1015 check_stack_depth();
1017 rval = JsonbIteratorNext(val, &vval, false);
1018 rcont = JsonbIteratorNext(mContained, &vcontained, false);
1023 * The differing return values can immediately be taken as indicating
1024 * two differing container types at this nesting level, which is
1025 * sufficient reason to give up entirely (but it should be the case
1026 * that they're both some container type).
1028 Assert(rval == WJB_BEGIN_OBJECT || rval == WJB_BEGIN_ARRAY);
1029 Assert(rcont == WJB_BEGIN_OBJECT || rcont == WJB_BEGIN_ARRAY);
1032 else if (rcont == WJB_BEGIN_OBJECT)
1034 Assert(vval.type == jbvObject);
1035 Assert(vcontained.type == jbvObject);
1038 * If the lhs has fewer pairs than the rhs, it can't possibly contain
1039 * the rhs. (This conclusion is safe only because we de-duplicate
1040 * keys in all Jsonb objects; thus there can be no corresponding
1041 * optimization in the array case.) The case probably won't arise
1042 * often, but since it's such a cheap check we may as well make it.
1044 if (vval.val.object.nPairs < vcontained.val.object.nPairs)
1047 /* Work through rhs "is it contained within?" object */
1050 JsonbValue *lhsVal; /* lhsVal is from pair in lhs object */
1051 JsonbValue lhsValBuf;
1053 rcont = JsonbIteratorNext(mContained, &vcontained, false);
1056 * When we get through caller's rhs "is it contained within?"
1057 * object without failing to find one of its values, it's
1060 if (rcont == WJB_END_OBJECT)
1063 Assert(rcont == WJB_KEY);
1064 Assert(vcontained.type == jbvString);
1066 /* First, find value by key... */
1068 getKeyJsonValueFromContainer((*val)->container,
1069 vcontained.val.string.val,
1070 vcontained.val.string.len,
1076 * ...at this stage it is apparent that there is at least a key
1077 * match for this rhs pair.
1079 rcont = JsonbIteratorNext(mContained, &vcontained, true);
1081 Assert(rcont == WJB_VALUE);
1084 * Compare rhs pair's value with lhs pair's value just found using
1087 if (lhsVal->type != vcontained.type)
1091 else if (IsAJsonbScalar(lhsVal))
1093 if (!equalsJsonbScalarValue(lhsVal, &vcontained))
1098 /* Nested container value (object or array) */
1099 JsonbIterator *nestval,
1102 Assert(lhsVal->type == jbvBinary);
1103 Assert(vcontained.type == jbvBinary);
1105 nestval = JsonbIteratorInit(lhsVal->val.binary.data);
1106 nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1109 * Match "value" side of rhs datum object's pair recursively.
1110 * It's a nested structure.
1112 * Note that nesting still has to "match up" at the right
1113 * nesting sub-levels. However, there need only be zero or
1114 * more matching pairs (or elements) at each nesting level
1115 * (provided the *rhs* pairs/elements *all* match on each
1116 * level), which enables searching nested structures for a
1117 * single String or other primitive type sub-datum quite
1118 * effectively (provided the user constructed the rhs nested
1119 * structure such that we "know where to look").
1121 * In other words, the mapping of container nodes in the rhs
1122 * "vcontained" Jsonb to internal nodes on the lhs is
1123 * injective, and parent-child edges on the rhs must be mapped
1124 * to parent-child edges on the lhs to satisfy the condition
1125 * of containment (plus of course the mapped nodes must be
1128 if (!JsonbDeepContains(&nestval, &nestContained))
1133 else if (rcont == WJB_BEGIN_ARRAY)
1135 JsonbValue *lhsConts = NULL;
1136 uint32 nLhsElems = vval.val.array.nElems;
1138 Assert(vval.type == jbvArray);
1139 Assert(vcontained.type == jbvArray);
1142 * Handle distinction between "raw scalar" pseudo arrays, and real
1145 * A raw scalar may contain another raw scalar, and an array may
1146 * contain a raw scalar, but a raw scalar may not contain an array. We
1147 * don't do something like this for the object case, since objects can
1148 * only contain pairs, never raw scalars (a pair is represented by an
1149 * rhs object argument with a single contained pair).
1151 if (vval.val.array.rawScalar && !vcontained.val.array.rawScalar)
1154 /* Work through rhs "is it contained within?" array */
1157 rcont = JsonbIteratorNext(mContained, &vcontained, true);
1160 * When we get through caller's rhs "is it contained within?"
1161 * array without failing to find one of its values, it's
1164 if (rcont == WJB_END_ARRAY)
1167 Assert(rcont == WJB_ELEM);
1169 if (IsAJsonbScalar(&vcontained))
1171 if (!findJsonbValueFromContainer((*val)->container,
1181 * If this is first container found in rhs array (at this
1182 * depth), initialize temp lhs array of containers
1184 if (lhsConts == NULL)
1188 /* Make room for all possible values */
1189 lhsConts = palloc(sizeof(JsonbValue) * nLhsElems);
1191 for (i = 0; i < nLhsElems; i++)
1193 /* Store all lhs elements in temp array */
1194 rcont = JsonbIteratorNext(val, &vval, true);
1195 Assert(rcont == WJB_ELEM);
1197 if (vval.type == jbvBinary)
1198 lhsConts[j++] = vval;
1201 /* No container elements in temp array, so give up now */
1205 /* We may have only partially filled array */
1209 /* XXX: Nested array containment is O(N^2) */
1210 for (i = 0; i < nLhsElems; i++)
1212 /* Nested container value (object or array) */
1213 JsonbIterator *nestval,
1217 nestval = JsonbIteratorInit(lhsConts[i].val.binary.data);
1218 nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1220 contains = JsonbDeepContains(&nestval, &nestContained);
1225 pfree(nestContained);
1231 * Report rhs container value is not contained if couldn't
1232 * match rhs container to *some* lhs cont
1241 elog(ERROR, "invalid jsonb container type");
1244 elog(ERROR, "unexpectedly fell off end of jsonb container");
1249 * Hash a JsonbValue scalar value, mixing the hash value into an existing
1250 * hash provided by the caller.
1252 * Some callers may wish to independently XOR in JB_FOBJECT and JB_FARRAY
1256 JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash)
1260 /* Compute hash value for scalarVal */
1261 switch (scalarVal->type)
1267 tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->val.string.val,
1268 scalarVal->val.string.len));
1271 /* Must hash equal numerics to equal hash codes */
1272 tmp = DatumGetUInt32(DirectFunctionCall1(hash_numeric,
1273 NumericGetDatum(scalarVal->val.numeric)));
1276 tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1280 elog(ERROR, "invalid jsonb scalar type");
1281 tmp = 0; /* keep compiler quiet */
1286 * Combine hash values of successive keys, values and elements by rotating
1287 * the previous value left 1 bit, then XOR'ing in the new
1288 * key/value/element's hash value.
1290 *hash = (*hash << 1) | (*hash >> 31);
1295 * Hash a value to a 64-bit value, with a seed. Otherwise, similar to
1296 * JsonbHashScalarValue.
1299 JsonbHashScalarValueExtended(const JsonbValue *scalarVal, uint64 *hash,
1304 switch (scalarVal->type)
1310 tmp = DatumGetUInt64(hash_any_extended((const unsigned char *) scalarVal->val.string.val,
1311 scalarVal->val.string.len,
1315 tmp = DatumGetUInt64(DirectFunctionCall2(hash_numeric_extended,
1316 NumericGetDatum(scalarVal->val.numeric),
1317 UInt64GetDatum(seed)));
1321 tmp = DatumGetUInt64(DirectFunctionCall2(hashcharextended,
1322 BoolGetDatum(scalarVal->val.boolean),
1323 UInt64GetDatum(seed)));
1325 tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1329 elog(ERROR, "invalid jsonb scalar type");
1333 *hash = ROTATE_HIGH_AND_LOW_32BITS(*hash);
1338 * Are two scalar JsonbValues of the same type a and b equal?
1341 equalsJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar)
1343 if (aScalar->type == bScalar->type)
1345 switch (aScalar->type)
1350 return lengthCompareJsonbStringValue(aScalar, bScalar) == 0;
1352 return DatumGetBool(DirectFunctionCall2(numeric_eq,
1353 PointerGetDatum(aScalar->val.numeric),
1354 PointerGetDatum(bScalar->val.numeric)));
1356 return aScalar->val.boolean == bScalar->val.boolean;
1359 elog(ERROR, "invalid jsonb scalar type");
1362 elog(ERROR, "jsonb scalar type mismatch");
1367 * Compare two scalar JsonbValues, returning -1, 0, or 1.
1369 * Strings are compared using the default collation. Used by B-tree
1370 * operators, where a lexical sort order is generally expected.
1373 compareJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar)
1375 if (aScalar->type == bScalar->type)
1377 switch (aScalar->type)
1382 return varstr_cmp(aScalar->val.string.val,
1383 aScalar->val.string.len,
1384 bScalar->val.string.val,
1385 bScalar->val.string.len,
1386 DEFAULT_COLLATION_OID);
1388 return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
1389 PointerGetDatum(aScalar->val.numeric),
1390 PointerGetDatum(bScalar->val.numeric)));
1392 if (aScalar->val.boolean == bScalar->val.boolean)
1394 else if (aScalar->val.boolean > bScalar->val.boolean)
1399 elog(ERROR, "invalid jsonb scalar type");
1402 elog(ERROR, "jsonb scalar type mismatch");
1408 * Functions for manipulating the resizable buffer used by convertJsonb and
1413 * Reserve 'len' bytes, at the end of the buffer, enlarging it if necessary.
1414 * Returns the offset to the reserved area. The caller is expected to fill
1415 * the reserved area later with copyToBuffer().
1418 reserveFromBuffer(StringInfo buffer, int len)
1422 /* Make more room if needed */
1423 enlargeStringInfo(buffer, len);
1425 /* remember current offset */
1426 offset = buffer->len;
1428 /* reserve the space */
1432 * Keep a trailing null in place, even though it's not useful for us; it
1433 * seems best to preserve the invariants of StringInfos.
1435 buffer->data[buffer->len] = '\0';
1441 * Copy 'len' bytes to a previously reserved area in buffer.
1444 copyToBuffer(StringInfo buffer, int offset, const char *data, int len)
1446 memcpy(buffer->data + offset, data, len);
1450 * A shorthand for reserveFromBuffer + copyToBuffer.
1453 appendToBuffer(StringInfo buffer, const char *data, int len)
1457 offset = reserveFromBuffer(buffer, len);
1458 copyToBuffer(buffer, offset, data, len);
1463 * Append padding, so that the length of the StringInfo is int-aligned.
1464 * Returns the number of padding bytes appended.
1467 padBufferToInt(StringInfo buffer)
1473 padlen = INTALIGN(buffer->len) - buffer->len;
1475 offset = reserveFromBuffer(buffer, padlen);
1477 /* padlen must be small, so this is probably faster than a memset */
1478 for (p = 0; p < padlen; p++)
1479 buffer->data[offset + p] = '\0';
1485 * Given a JsonbValue, convert to Jsonb. The result is palloc'd.
1488 convertToJsonb(JsonbValue *val)
1490 StringInfoData buffer;
1494 /* Should not already have binary representation */
1495 Assert(val->type != jbvBinary);
1497 /* Allocate an output buffer. It will be enlarged as needed */
1498 initStringInfo(&buffer);
1500 /* Make room for the varlena header */
1501 reserveFromBuffer(&buffer, VARHDRSZ);
1503 convertJsonbValue(&buffer, &jentry, val, 0);
1506 * Note: the JEntry of the root is discarded. Therefore the root
1507 * JsonbContainer struct must contain enough information to tell what kind
1511 res = (Jsonb *) buffer.data;
1513 SET_VARSIZE(res, buffer.len);
1519 * Subroutine of convertJsonb: serialize a single JsonbValue into buffer.
1521 * The JEntry header for this node is returned in *header. It is filled in
1522 * with the length of this value and appropriate type bits. If we wish to
1523 * store an end offset rather than a length, it is the caller's responsibility
1524 * to adjust for that.
1526 * If the value is an array or an object, this recurses. 'level' is only used
1527 * for debugging purposes.
1530 convertJsonbValue(StringInfo buffer, JEntry *header, JsonbValue *val, int level)
1532 check_stack_depth();
1538 * A JsonbValue passed as val should never have a type of jbvBinary, and
1539 * neither should any of its sub-components. Those values will be produced
1540 * by convertJsonbArray and convertJsonbObject, the results of which will
1541 * not be passed back to this function as an argument.
1544 if (IsAJsonbScalar(val))
1545 convertJsonbScalar(buffer, header, val);
1546 else if (val->type == jbvArray)
1547 convertJsonbArray(buffer, header, val, level);
1548 else if (val->type == jbvObject)
1549 convertJsonbObject(buffer, header, val, level);
1551 elog(ERROR, "unknown type of jsonb container to convert");
1555 convertJsonbArray(StringInfo buffer, JEntry *pheader, JsonbValue *val, int level)
1562 int nElems = val->val.array.nElems;
1564 /* Remember where in the buffer this array starts. */
1565 base_offset = buffer->len;
1567 /* Align to 4-byte boundary (any padding counts as part of my data) */
1568 padBufferToInt(buffer);
1571 * Construct the header Jentry and store it in the beginning of the
1572 * variable-length payload.
1574 header = nElems | JB_FARRAY;
1575 if (val->val.array.rawScalar)
1577 Assert(nElems == 1);
1579 header |= JB_FSCALAR;
1582 appendToBuffer(buffer, (char *) &header, sizeof(uint32));
1584 /* Reserve space for the JEntries of the elements. */
1585 jentry_offset = reserveFromBuffer(buffer, sizeof(JEntry) * nElems);
1588 for (i = 0; i < nElems; i++)
1590 JsonbValue *elem = &val->val.array.elems[i];
1595 * Convert element, producing a JEntry and appending its
1596 * variable-length data to buffer
1598 convertJsonbValue(buffer, &meta, elem, level + 1);
1600 len = JBE_OFFLENFLD(meta);
1604 * Bail out if total variable-length data exceeds what will fit in a
1605 * JEntry length field. We check this in each iteration, not just
1606 * once at the end, to forestall possible integer overflow.
1608 if (totallen > JENTRY_OFFLENMASK)
1610 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1611 errmsg("total size of jsonb array elements exceeds the maximum of %u bytes",
1612 JENTRY_OFFLENMASK)));
1615 * Convert each JB_OFFSET_STRIDE'th length to an offset.
1617 if ((i % JB_OFFSET_STRIDE) == 0)
1618 meta = (meta & JENTRY_TYPEMASK) | totallen | JENTRY_HAS_OFF;
1620 copyToBuffer(buffer, jentry_offset, (char *) &meta, sizeof(JEntry));
1621 jentry_offset += sizeof(JEntry);
1624 /* Total data size is everything we've appended to buffer */
1625 totallen = buffer->len - base_offset;
1627 /* Check length again, since we didn't include the metadata above */
1628 if (totallen > JENTRY_OFFLENMASK)
1630 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1631 errmsg("total size of jsonb array elements exceeds the maximum of %u bytes",
1632 JENTRY_OFFLENMASK)));
1634 /* Initialize the header of this node in the container's JEntry array */
1635 *pheader = JENTRY_ISCONTAINER | totallen;
1639 convertJsonbObject(StringInfo buffer, JEntry *pheader, JsonbValue *val, int level)
1646 int nPairs = val->val.object.nPairs;
1648 /* Remember where in the buffer this object starts. */
1649 base_offset = buffer->len;
1651 /* Align to 4-byte boundary (any padding counts as part of my data) */
1652 padBufferToInt(buffer);
1655 * Construct the header Jentry and store it in the beginning of the
1656 * variable-length payload.
1658 header = nPairs | JB_FOBJECT;
1659 appendToBuffer(buffer, (char *) &header, sizeof(uint32));
1661 /* Reserve space for the JEntries of the keys and values. */
1662 jentry_offset = reserveFromBuffer(buffer, sizeof(JEntry) * nPairs * 2);
1665 * Iterate over the keys, then over the values, since that is the ordering
1666 * we want in the on-disk representation.
1669 for (i = 0; i < nPairs; i++)
1671 JsonbPair *pair = &val->val.object.pairs[i];
1676 * Convert key, producing a JEntry and appending its variable-length
1679 convertJsonbScalar(buffer, &meta, &pair->key);
1681 len = JBE_OFFLENFLD(meta);
1685 * Bail out if total variable-length data exceeds what will fit in a
1686 * JEntry length field. We check this in each iteration, not just
1687 * once at the end, to forestall possible integer overflow.
1689 if (totallen > JENTRY_OFFLENMASK)
1691 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1692 errmsg("total size of jsonb object elements exceeds the maximum of %u bytes",
1693 JENTRY_OFFLENMASK)));
1696 * Convert each JB_OFFSET_STRIDE'th length to an offset.
1698 if ((i % JB_OFFSET_STRIDE) == 0)
1699 meta = (meta & JENTRY_TYPEMASK) | totallen | JENTRY_HAS_OFF;
1701 copyToBuffer(buffer, jentry_offset, (char *) &meta, sizeof(JEntry));
1702 jentry_offset += sizeof(JEntry);
1704 for (i = 0; i < nPairs; i++)
1706 JsonbPair *pair = &val->val.object.pairs[i];
1711 * Convert value, producing a JEntry and appending its variable-length
1714 convertJsonbValue(buffer, &meta, &pair->value, level + 1);
1716 len = JBE_OFFLENFLD(meta);
1720 * Bail out if total variable-length data exceeds what will fit in a
1721 * JEntry length field. We check this in each iteration, not just
1722 * once at the end, to forestall possible integer overflow.
1724 if (totallen > JENTRY_OFFLENMASK)
1726 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1727 errmsg("total size of jsonb object elements exceeds the maximum of %u bytes",
1728 JENTRY_OFFLENMASK)));
1731 * Convert each JB_OFFSET_STRIDE'th length to an offset.
1733 if (((i + nPairs) % JB_OFFSET_STRIDE) == 0)
1734 meta = (meta & JENTRY_TYPEMASK) | totallen | JENTRY_HAS_OFF;
1736 copyToBuffer(buffer, jentry_offset, (char *) &meta, sizeof(JEntry));
1737 jentry_offset += sizeof(JEntry);
1740 /* Total data size is everything we've appended to buffer */
1741 totallen = buffer->len - base_offset;
1743 /* Check length again, since we didn't include the metadata above */
1744 if (totallen > JENTRY_OFFLENMASK)
1746 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1747 errmsg("total size of jsonb object elements exceeds the maximum of %u bytes",
1748 JENTRY_OFFLENMASK)));
1750 /* Initialize the header of this node in the container's JEntry array */
1751 *pheader = JENTRY_ISCONTAINER | totallen;
1755 convertJsonbScalar(StringInfo buffer, JEntry *jentry, JsonbValue *scalarVal)
1760 switch (scalarVal->type)
1763 *jentry = JENTRY_ISNULL;
1767 appendToBuffer(buffer, scalarVal->val.string.val, scalarVal->val.string.len);
1769 *jentry = scalarVal->val.string.len;
1773 /* replace numeric NaN with string "NaN" */
1774 if (numeric_is_nan(scalarVal->val.numeric))
1776 appendToBuffer(buffer, "NaN", 3);
1781 numlen = VARSIZE_ANY(scalarVal->val.numeric);
1782 padlen = padBufferToInt(buffer);
1784 appendToBuffer(buffer, (char *) scalarVal->val.numeric, numlen);
1786 *jentry = JENTRY_ISNUMERIC | (padlen + numlen);
1790 *jentry = (scalarVal->val.boolean) ?
1791 JENTRY_ISBOOL_TRUE : JENTRY_ISBOOL_FALSE;
1796 char buf[MAXDATELEN + 1];
1799 JsonEncodeDateTime(buf,
1800 scalarVal->val.datetime.value,
1801 scalarVal->val.datetime.typid,
1802 &scalarVal->val.datetime.tz);
1804 appendToBuffer(buffer, buf, len);
1811 elog(ERROR, "invalid jsonb scalar type");
1816 * Compare two jbvString JsonbValue values, a and b.
1818 * This is a special qsort() comparator used to sort strings in certain
1819 * internal contexts where it is sufficient to have a well-defined sort order.
1820 * In particular, object pair keys are sorted according to this criteria to
1821 * facilitate cheap binary searches where we don't care about lexical sort
1824 * a and b are first sorted based on their length. If a tie-breaker is
1825 * required, only then do we consider string binary equality.
1828 lengthCompareJsonbStringValue(const void *a, const void *b)
1830 const JsonbValue *va = (const JsonbValue *) a;
1831 const JsonbValue *vb = (const JsonbValue *) b;
1833 Assert(va->type == jbvString);
1834 Assert(vb->type == jbvString);
1836 return lengthCompareJsonbString(va->val.string.val, va->val.string.len,
1837 vb->val.string.val, vb->val.string.len);
1841 * Subroutine for lengthCompareJsonbStringValue
1843 * This is also useful separately to implement binary search on
1847 lengthCompareJsonbString(const char *val1, int len1, const char *val2, int len2)
1850 return memcmp(val1, val2, len1);
1852 return len1 > len2 ? 1 : -1;
1856 * qsort_arg() comparator to compare JsonbPair values.
1858 * Third argument 'binequal' may point to a bool. If it's set, *binequal is set
1859 * to true iff a and b have full binary equality, since some callers have an
1860 * interest in whether the two values are equal or merely equivalent.
1862 * N.B: String comparisons here are "length-wise"
1864 * Pairs with equals keys are ordered such that the order field is respected.
1867 lengthCompareJsonbPair(const void *a, const void *b, void *binequal)
1869 const JsonbPair *pa = (const JsonbPair *) a;
1870 const JsonbPair *pb = (const JsonbPair *) b;
1873 res = lengthCompareJsonbStringValue(&pa->key, &pb->key);
1874 if (res == 0 && binequal)
1875 *((bool *) binequal) = true;
1878 * Guarantee keeping order of equal pair. Unique algorithm will prefer
1879 * first element as value.
1882 res = (pa->order > pb->order) ? -1 : 1;
1888 * Sort and unique-ify pairs in JsonbValue object
1891 uniqueifyJsonbObject(JsonbValue *object)
1893 bool hasNonUniq = false;
1895 Assert(object->type == jbvObject);
1897 if (object->val.object.nPairs > 1)
1898 qsort_arg(object->val.object.pairs, object->val.object.nPairs, sizeof(JsonbPair),
1899 lengthCompareJsonbPair, &hasNonUniq);
1903 JsonbPair *ptr = object->val.object.pairs + 1,
1904 *res = object->val.object.pairs;
1906 while (ptr - object->val.object.pairs < object->val.object.nPairs)
1908 /* Avoid copying over duplicate */
1909 if (lengthCompareJsonbStringValue(ptr, res) != 0)
1913 memcpy(res, ptr, sizeof(JsonbPair));
1918 object->val.object.nPairs = res + 1 - object->val.object.pairs;