1 /*-------------------------------------------------------------------------
4 * Utilities for jsonb datatype
6 * Copyright (c) 2014, PostgreSQL Global Development Group
10 * src/backend/utils/adt/jsonb_util.c
12 *-------------------------------------------------------------------------
16 #include "access/hash.h"
17 #include "catalog/pg_collation.h"
18 #include "catalog/pg_type.h"
19 #include "miscadmin.h"
20 #include "utils/builtins.h"
21 #include "utils/jsonb.h"
22 #include "utils/memutils.h"
25 * Twice as many values may be stored within pairs (for an Object) than within
26 * elements (for an Array), modulo the current MaxAllocSize limitation. Note
27 * that JSONB_MAX_PAIRS is derived from the number of possible pairs, not
28 * values (as is the case for arrays and their elements), because we're
29 * concerned about limitations on the representation of the number of pairs.
30 * Over twice the memory is required to store n JsonbPairs as n JsonbValues.
31 * It only takes exactly twice as much disk space for storage, though. The
32 * JsonbPair (not an actual pair of values) representation is used here because
33 * that is what is subject to the MaxAllocSize restriction when building an
36 #define JSONB_MAX_ELEMS (Min(MaxAllocSize / sizeof(JsonbValue), JENTRY_POSMASK))
37 #define JSONB_MAX_PAIRS (Min(MaxAllocSize / sizeof(JsonbPair), \
41 * State used while converting an arbitrary JsonbValue into a Jsonb value
42 * (4-byte varlena uncompressed representation of a Jsonb)
44 * ConvertLevel: Bookkeeping around particular level when converting.
46 typedef struct convertLevel
48 uint32 i; /* Iterates once per element, or once per pair */
49 uint32 *header; /* Pointer to current container header */
50 JEntry *meta; /* This level's metadata */
51 char *begin; /* Pointer into convertState.buffer */
55 * convertState: Overall bookkeeping state for conversion
57 typedef struct convertState
59 /* Preallocated buffer in which to form varlena/Jsonb value */
61 /* Pointer into buffer */
65 convertLevel *allState, /* Overall state array */
66 *contPtr; /* Cur container pointer (in allState) */
68 /* Current size of buffer containing allState array */
73 static int compareJsonbScalarValue(JsonbValue * a, JsonbValue * b);
74 static int lexicalCompareJsonbStringValue(const void *a, const void *b);
75 static Size convertJsonb(JsonbValue * val, Jsonb* buffer);
76 static inline short addPaddingInt(convertState * cstate);
77 static void walkJsonbValueConversion(JsonbValue * val, convertState * cstate,
79 static void putJsonbValueConversion(convertState * cstate, JsonbValue * val,
80 uint32 flags, uint32 level);
81 static void putScalarConversion(convertState * cstate, JsonbValue * scalarVal,
82 uint32 level, uint32 i);
83 static void iteratorFromContainerBuf(JsonbIterator * it, char *buffer);
84 static bool formIterIsContainer(JsonbIterator ** it, JsonbValue * val,
85 JEntry * ent, bool skipNested);
86 static JsonbIterator *freeAndGetParent(JsonbIterator * it);
87 static JsonbParseState *pushState(JsonbParseState ** pstate);
88 static void appendKey(JsonbParseState * pstate, JsonbValue * scalarVal);
89 static void appendValue(JsonbParseState * pstate, JsonbValue * scalarVal);
90 static void appendElement(JsonbParseState * pstate, JsonbValue * scalarVal);
91 static int lengthCompareJsonbStringValue(const void *a, const void *b, void *arg);
92 static int lengthCompareJsonbPair(const void *a, const void *b, void *arg);
93 static void uniqueifyJsonbObject(JsonbValue * object);
94 static void uniqueifyJsonbArray(JsonbValue * array);
97 * Turn an in-memory JsonbValue into a Jsonb for on-disk storage.
99 * There isn't a JsonbToJsonbValue(), because generally we find it more
100 * convenient to directly iterate through the Jsonb representation and only
101 * really convert nested scalar values. formIterIsContainer() does this, so
102 * that clients of the iteration code don't have to directly deal with the
103 * binary representation (JsonbDeepContains() is a notable exception, although
104 * all exceptions are internal to this module). In general, functions that
105 * accept a JsonbValue argument are concerned with the manipulation of scalar
106 * values, or simple containers of scalar values, where it would be
107 * inconvenient to deal with a great amount of other state.
110 JsonbValueToJsonb(JsonbValue * val)
115 if (IsAJsonbScalar(val))
118 JsonbParseState *pstate = NULL;
120 JsonbValue scalarArray;
122 scalarArray.type = jbvArray;
123 scalarArray.array.rawScalar = true;
124 scalarArray.array.nElems = 1;
126 pushJsonbValue(&pstate, WJB_BEGIN_ARRAY, &scalarArray);
127 pushJsonbValue(&pstate, WJB_ELEM, val);
128 res = pushJsonbValue(&pstate, WJB_END_ARRAY, NULL);
130 out = palloc(VARHDRSZ + res->estSize);
131 sz = convertJsonb(res, out);
132 Assert(sz <= res->estSize);
133 SET_VARSIZE(out, sz + VARHDRSZ);
135 else if (val->type == jbvObject || val->type == jbvArray)
137 out = palloc(VARHDRSZ + val->estSize);
138 sz = convertJsonb(val, out);
139 Assert(sz <= val->estSize);
140 SET_VARSIZE(out, VARHDRSZ + sz);
144 Assert(val->type == jbvBinary);
145 out = palloc(VARHDRSZ + val->binary.len);
146 SET_VARSIZE(out, VARHDRSZ + val->binary.len);
147 memcpy(VARDATA(out), val->binary.data, val->binary.len);
154 * BT comparator worker function. Returns an integer less than, equal to, or
155 * greater than zero, indicating whether a is less than, equal to, or greater
156 * than b. Consistent with the requirements for a B-Tree operator class
158 * Strings are compared lexically, in contrast with other places where we use a
159 * much simpler comparator logic for searching through Strings. Since this is
160 * called from B-Tree support function 1, we're careful about not leaking
164 compareJsonbSuperHeaderValue(JsonbSuperHeader a, JsonbSuperHeader b)
170 ita = JsonbIteratorInit(a);
171 itb = JsonbIteratorInit(b);
180 ra = JsonbIteratorNext(&ita, &va, false);
181 rb = JsonbIteratorNext(&itb, &vb, false);
184 * To a limited extent we'll redundantly iterate over an array/object
185 * while re-performing the same test without any reasonable expectation
186 * of the same container types having differing lengths (as when we
187 * process a WJB_BEGIN_OBJECT, and later the corresponding
188 * WJB_END_OBJECT), but no matter.
194 /* Decisively equal */
198 if (va.type == vb.type)
203 res = lexicalCompareJsonbStringValue(&va, &vb);
208 res = compareJsonbScalarValue(&va, &vb);
212 * This could be a "raw scalar" pseudo array. That's a
213 * special case here though, since we still want the
214 * general type-based comparisons to apply, and as far
215 * as we're concerned a pseudo array is just a scalar.
217 if (va.array.rawScalar != vb.array.rawScalar)
218 res = (va.array.rawScalar) ? -1 : 1;
219 if (va.array.nElems != vb.array.nElems)
220 res = (va.array.nElems > vb.array.nElems) ? 1 : -1;
223 if (va.object.nPairs != vb.object.nPairs)
224 res = (va.object.nPairs > vb.object.nPairs) ? 1 : -1;
227 elog(ERROR, "unexpected jbvBinary value");
232 /* Type-defined order */
233 res = (va.type > vb.type) ? 1 : -1;
239 * It's safe to assume that the types differed.
241 * If the two values were the same container type, then there'd
242 * have been a chance to observe the variation in the number of
243 * elements/pairs (when processing WJB_BEGIN_OBJECT, say). They
244 * can't be scalar types either, because then they'd have to be
245 * contained in containers already ruled unequal due to differing
246 * numbers of pairs/elements, or already directly ruled unequal
247 * with a call to the underlying type's comparator.
249 Assert(va.type != vb.type);
250 Assert(va.type == jbvArray || va.type == jbvObject);
251 Assert(vb.type == jbvArray || vb.type == jbvObject);
252 /* Type-defined order */
253 res = (va.type > vb.type) ? 1 : -1;
260 JsonbIterator *i = ita->parent;
266 JsonbIterator *i = itb->parent;
275 * Find value in object (i.e. the "value" part of some key/value pair in an
276 * object), or find a matching element if we're looking through an array. Do
277 * so on the basis of equality of the object keys only, or alternatively
278 * element values only, with a caller-supplied value "key". The "flags"
279 * argument allows the caller to specify which container types are of interest.
281 * This exported utility function exists to facilitate various cases concerned
282 * with "containment". If asked to look through an object, the caller had
283 * better pass a Jsonb String, because their keys can only be strings.
284 * Otherwise, for an array, any type of JsonbValue will do.
286 * In order to proceed with the search, it is necessary for callers to have
287 * both specified an interest in exactly one particular container type with an
288 * appropriate flag, as well as having the pointed-to Jsonb superheader be of
289 * one of those same container types at the top level. (Actually, we just do
290 * whichever makes sense to save callers the trouble of figuring it out - at
291 * most one can make sense, because the super header either points to an array
292 * (possible a "raw scalar" pseudo array) or an object.)
294 * Note that we can return a jbvBinary JsonbValue if this is called on an
295 * object, but we never do so on an array. If the caller asks to look through
296 * a container type that is not of the type pointed to by the superheader,
297 * immediately fall through and return NULL. If we cannot find the value,
298 * return NULL. Otherwise, return palloc()'d copy of value.
300 * lowbound can be NULL, but if not it's used to establish a point at which to
301 * start searching. If the value searched for is found, then lowbound is then
302 * set to an offset into the array or object. Typically, this is used to
303 * exploit the ordering of objects to avoid redundant work, by also sorting a
304 * list of items to be checked using the internal sort criteria for objects
305 * (object pair keys), and then, when searching for the second or subsequent
306 * item, picking it up where we left off knowing that the second or subsequent
307 * item can not be at a point below the low bound set when the first was found.
308 * This is only useful for objects, not arrays (which have a user-defined
309 * order), so array superheader Jsonbs should just pass NULL. Moreover, it's
310 * only useful because we only match object pairs on the basis of their key, so
311 * presumably anyone exploiting this is only interested in matching Object keys
312 * with a String. lowbound is given in units of pairs, not underlying values.
315 findJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 flags,
316 uint32 *lowbound, JsonbValue * key)
318 uint32 superheader = *(uint32 *) sheader;
319 JEntry *array = (JEntry *) (sheader + sizeof(uint32));
320 int count = (superheader & JB_CMASK);
321 JsonbValue *result = palloc(sizeof(JsonbValue));
323 Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
325 if (flags & JB_FARRAY & superheader)
327 char *data = (char *) (array + (superheader & JB_CMASK));
330 for (i = 0; i < count; i++)
332 JEntry *e = array + i;
334 if (JBE_ISNULL(*e) && key->type == jbvNull)
336 result->type = jbvNull;
337 result->estSize = sizeof(JEntry);
339 else if (JBE_ISSTRING(*e) && key->type == jbvString)
341 result->type = jbvString;
342 result->string.val = data + JBE_OFF(*e);
343 result->string.len = JBE_LEN(*e);
344 result->estSize = sizeof(JEntry) + result->string.len;
346 else if (JBE_ISNUMERIC(*e) && key->type == jbvNumeric)
348 result->type = jbvNumeric;
349 result->numeric = (Numeric) (data + INTALIGN(JBE_OFF(*e)));
350 result->estSize = 2 * sizeof(JEntry) +
351 VARSIZE_ANY(result->numeric);
353 else if (JBE_ISBOOL(*e) && key->type == jbvBool)
355 result->type = jbvBool;
356 result->boolean = JBE_ISBOOL_TRUE(*e) != 0;
357 result->estSize = sizeof(JEntry);
362 if (compareJsonbScalarValue(key, result) == 0)
366 else if (flags & JB_FOBJECT & superheader)
368 /* Since this is an object, account for *Pairs* of Jentrys */
369 char *data = (char *) (array + (superheader & JB_CMASK) * 2);
370 uint32 stopLow = lowbound ? *lowbound : 0,
373 /* Object key past by caller must be a string */
374 Assert(key->type == jbvString);
376 /* Binary search on object/pair keys *only* */
377 while (stopLow < count)
381 JsonbValue candidate;
384 * Note how we compensate for the fact that we're iterating through
385 * pairs (not entries) throughout.
387 stopMiddle = stopLow + (count - stopLow) / 2;
389 entry = array + stopMiddle * 2;
391 candidate.type = jbvString;
392 candidate.string.val = data + JBE_OFF(*entry);
393 candidate.string.len = JBE_LEN(*entry);
394 candidate.estSize = sizeof(JEntry) + candidate.string.len;
396 difference = lengthCompareJsonbStringValue(&candidate, key, NULL);
400 /* Found our value (from key/value pair) */
401 JEntry *v = entry + 1;
404 *lowbound = stopMiddle + 1;
408 result->type = jbvNull;
409 result->estSize = sizeof(JEntry);
411 else if (JBE_ISSTRING(*v))
413 result->type = jbvString;
414 result->string.val = data + JBE_OFF(*v);
415 result->string.len = JBE_LEN(*v);
416 result->estSize = sizeof(JEntry) + result->string.len;
418 else if (JBE_ISNUMERIC(*v))
420 result->type = jbvNumeric;
421 result->numeric = (Numeric) (data + INTALIGN(JBE_OFF(*v)));
422 result->estSize = 2 * sizeof(JEntry) +
423 VARSIZE_ANY(result->numeric);
425 else if (JBE_ISBOOL(*v))
427 result->type = jbvBool;
428 result->boolean = JBE_ISBOOL_TRUE(*v) != 0;
429 result->estSize = sizeof(JEntry);
434 * See header comments to understand why this never happens
437 result->type = jbvBinary;
438 result->binary.data = data + INTALIGN(JBE_OFF(*v));
439 result->binary.len = JBE_LEN(*v) -
440 (INTALIGN(JBE_OFF(*v)) - JBE_OFF(*v));
441 result->estSize = 2 * sizeof(JEntry) + result->binary.len;
449 stopLow = stopMiddle + 1;
465 * Get i-th value of Jsonb array from superheader.
467 * Returns palloc()'d copy of value.
470 getIthJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 i)
472 uint32 superheader = *(uint32 *) sheader;
478 result = palloc(sizeof(JsonbValue));
480 if (i >= (superheader & JB_CMASK))
483 array = (JEntry *) (sheader + sizeof(uint32));
485 if (superheader & JB_FARRAY)
488 data = (char *) (array + (superheader & JB_CMASK));
492 elog(ERROR, "not a jsonb array");
497 result->type = jbvNull;
498 result->estSize = sizeof(JEntry);
500 else if (JBE_ISSTRING(*e))
502 result->type = jbvString;
503 result->string.val = data + JBE_OFF(*e);
504 result->string.len = JBE_LEN(*e);
505 result->estSize = sizeof(JEntry) + result->string.len;
507 else if (JBE_ISNUMERIC(*e))
509 result->type = jbvNumeric;
510 result->numeric = (Numeric) (data + INTALIGN(JBE_OFF(*e)));
511 result->estSize = 2 * sizeof(JEntry) + VARSIZE_ANY(result->numeric);
513 else if (JBE_ISBOOL(*e))
515 result->type = jbvBool;
516 result->boolean = JBE_ISBOOL_TRUE(*e) != 0;
517 result->estSize = sizeof(JEntry);
521 result->type = jbvBinary;
522 result->binary.data = data + INTALIGN(JBE_OFF(*e));
523 result->binary.len = JBE_LEN(*e) - (INTALIGN(JBE_OFF(*e)) - JBE_OFF(*e));
524 result->estSize = result->binary.len + 2 * sizeof(JEntry);
531 * Push JsonbValue into JsonbParseState.
533 * Used when parsing JSON tokens to form Jsonb, or when converting an in-memory
534 * JsonbValue to a Jsonb.
536 * Initial state of *JsonbParseState is NULL, since it'll be allocated here
537 * originally (caller will get JsonbParseState back by reference).
539 * Only sequential tokens pertaining to non-container types should pass a
540 * JsonbValue. There is one exception -- WJB_BEGIN_ARRAY callers may pass a
541 * "raw scalar" pseudo array to append that.
544 pushJsonbValue(JsonbParseState ** pstate, int seq, JsonbValue * scalarVal)
546 JsonbValue *result = NULL;
550 case WJB_BEGIN_ARRAY:
551 Assert(!scalarVal || scalarVal->array.rawScalar);
552 *pstate = pushState(pstate);
553 result = &(*pstate)->contVal;
554 (*pstate)->contVal.type = jbvArray;
555 (*pstate)->contVal.estSize = 3 * sizeof(JEntry);
556 (*pstate)->contVal.array.nElems = 0;
557 (*pstate)->contVal.array.rawScalar = (scalarVal &&
558 scalarVal->array.rawScalar);
559 if (scalarVal && scalarVal->array.nElems > 0)
561 /* Assume that this array is still really a scalar */
562 Assert(scalarVal->type == jbvArray);
563 (*pstate)->size = scalarVal->array.nElems;
569 (*pstate)->contVal.array.elems = palloc(sizeof(JsonbValue) *
572 case WJB_BEGIN_OBJECT:
574 *pstate = pushState(pstate);
575 result = &(*pstate)->contVal;
576 (*pstate)->contVal.type = jbvObject;
577 (*pstate)->contVal.estSize = 3 * sizeof(JEntry);
578 (*pstate)->contVal.object.nPairs = 0;
580 (*pstate)->contVal.object.pairs = palloc(sizeof(JsonbPair) *
584 Assert(scalarVal->type == jbvString);
585 appendKey(*pstate, scalarVal);
588 Assert(IsAJsonbScalar(scalarVal) ||
589 scalarVal->type == jbvBinary);
590 appendValue(*pstate, scalarVal);
593 Assert(IsAJsonbScalar(scalarVal) ||
594 scalarVal->type == jbvBinary);
595 appendElement(*pstate, scalarVal);
598 uniqueifyJsonbObject(&(*pstate)->contVal);
600 /* Steps here common to WJB_END_OBJECT case */
602 result = &(*pstate)->contVal;
605 * Pop stack and push current array/object as value in parent
608 *pstate = (*pstate)->next;
611 switch ((*pstate)->contVal.type)
614 appendElement(*pstate, result);
617 appendValue(*pstate, result);
620 elog(ERROR, "invalid jsonb container type");
625 elog(ERROR, "unrecognized jsonb sequential processing token");
632 * Given a Jsonb superheader, expand to JsonbIterator to iterate over items
633 * fully expanded to in-memory representation for manipulation.
635 * See JsonbIteratorNext() for notes on memory management.
638 JsonbIteratorInit(JsonbSuperHeader sheader)
640 JsonbIterator *it = palloc(sizeof(JsonbIterator));
642 iteratorFromContainerBuf(it, sheader);
649 * Get next JsonbValue while iterating
651 * Caller should initially pass their own, original iterator. They may get
652 * back a child iterator palloc()'d here instead. The function can be relied
653 * on to free those child iterators, lest the memory allocated for highly
654 * nested objects become unreasonable, but only if callers don't end iteration
655 * early (by breaking upon having found something in a search, for example).
657 * Callers in such a scenario, that are particularly sensitive to leaking
658 * memory in a long-lived context may walk the ancestral tree from the final
659 * iterator we left them with to its oldest ancestor, pfree()ing as they go.
660 * They do not have to free any other memory previously allocated for iterators
661 * but not accessible as direct ancestors of the iterator they're last passed
664 * Returns "Jsonb sequential processing" token value. Iterator "state"
665 * reflects the current stage of the process in a less granular fashion, and is
666 * mostly used here to track things internally with respect to particular
669 * Clients of this function should not have to handle any jbvBinary values
670 * (since recursive calls will deal with this), provided skipNested is false.
671 * It is our job to expand the jbvBinary representation without bothering them
672 * with it. However, clients should not take it upon themselves to touch array
673 * or Object element/pair buffers, since their element/pair pointers are
677 JsonbIteratorNext(JsonbIterator ** it, JsonbValue * val, bool skipNested)
679 JsonbIterState state;
681 /* Guard against stack overflow due to overly complex Jsonb */
684 /* Recursive caller may have original caller's iterator */
688 state = (*it)->state;
690 if ((*it)->containerType == JB_FARRAY)
692 if (state == jbi_start)
694 /* Set v to array on first array call */
695 val->type = jbvArray;
696 val->array.nElems = (*it)->nElems;
698 * v->array.elems is not actually set, because we aren't doing a
701 val->array.rawScalar = (*it)->isScalar;
703 /* Set state for next call */
704 (*it)->state = jbi_elem;
705 return WJB_BEGIN_ARRAY;
707 else if (state == jbi_elem)
709 if ((*it)->i >= (*it)->nElems)
712 * All elements within array already processed. Report this to
713 * caller, and give it back original parent iterator (which
714 * independently tracks iteration progress at its level of
717 *it = freeAndGetParent(*it);
718 return WJB_END_ARRAY;
720 else if (formIterIsContainer(it, val, &(*it)->meta[(*it)->i++],
724 * New child iterator acquired within formIterIsContainer.
725 * Recurse into container. Don't directly return jbvBinary
726 * value to top-level client.
728 return JsonbIteratorNext(it, val, skipNested);
732 /* Scalar item in array */
737 else if ((*it)->containerType == JB_FOBJECT)
739 if (state == jbi_start)
741 /* Set v to object on first object call */
742 val->type = jbvObject;
743 val->object.nPairs = (*it)->nElems;
745 * v->object.pairs is not actually set, because we aren't doing a
749 /* Set state for next call */
750 (*it)->state = jbi_key;
751 return WJB_BEGIN_OBJECT;
753 else if (state == jbi_key)
755 if ((*it)->i >= (*it)->nElems)
758 * All pairs within object already processed. Report this to
759 * caller, and give it back original containing iterator (which
760 * independently tracks iteration progress at its level of
763 *it = freeAndGetParent(*it);
764 return WJB_END_OBJECT;
769 * Return binary item key (ensured by setting skipNested to
770 * false directly). No child iterator, no further recursion.
771 * When control reaches here, it's probably from a recursive
774 if (formIterIsContainer(it, val, &(*it)->meta[(*it)->i * 2], false))
775 elog(ERROR, "unexpected container as object key");
777 Assert(val->type == jbvString);
778 /* Set state for next call */
779 (*it)->state = jbi_value;
783 else if (state == jbi_value)
785 /* Set state for next call */
786 (*it)->state = jbi_key;
789 * Value may be a container, in which case we recurse with new,
790 * child iterator. If it is, don't bother !skipNested callers with
791 * dealing with the jbvBinary representation.
793 if (formIterIsContainer(it, val, &(*it)->meta[((*it)->i++) * 2 + 1],
795 return JsonbIteratorNext(it, val, skipNested);
801 elog(ERROR, "invalid iterator state");
806 * Worker for "contains" operator's function
808 * Formally speaking, containment is top-down, unordered subtree isomorphism.
810 * Takes iterators that belong to some container type. These iterators
811 * "belong" to those values in the sense that they've just been initialized in
812 * respect of them by the caller (perhaps in a nested fashion).
814 * "val" is lhs Jsonb, and mContained is rhs Jsonb when called from top level.
815 * We determine if mContained is contained within val.
818 JsonbDeepContains(JsonbIterator ** val, JsonbIterator ** mContained)
825 * Guard against stack overflow due to overly complex Jsonb.
827 * Functions called here independently take this precaution, but that might
828 * not be sufficient since this is also a recursive function.
832 rval = JsonbIteratorNext(val, &vval, false);
833 rcont = JsonbIteratorNext(mContained, &vcontained, false);
838 * The differing return values can immediately be taken as indicating
839 * two differing container types at this nesting level, which is
840 * sufficient reason to give up entirely (but it should be the case
841 * that they're both some container type).
843 Assert(rval == WJB_BEGIN_OBJECT || rval == WJB_BEGIN_ARRAY);
844 Assert(rcont == WJB_BEGIN_OBJECT || rcont == WJB_BEGIN_ARRAY);
847 else if (rcont == WJB_BEGIN_OBJECT)
849 JsonbValue *lhsVal; /* lhsVal is from pair in lhs object */
851 Assert(vcontained.type == jbvObject);
853 /* Work through rhs "is it contained within?" object */
856 rcont = JsonbIteratorNext(mContained, &vcontained, false);
859 * When we get through caller's rhs "is it contained within?"
860 * object without failing to find one of its values, it's
863 if (rcont == WJB_END_OBJECT)
866 Assert(rcont == WJB_KEY);
868 /* First, find value by key... */
869 lhsVal = findJsonbValueFromSuperHeader((*val)->buffer,
878 * ...at this stage it is apparent that there is at least a key
879 * match for this rhs pair.
881 rcont = JsonbIteratorNext(mContained, &vcontained, true);
883 Assert(rcont == WJB_VALUE);
886 * Compare rhs pair's value with lhs pair's value just found using
889 if (lhsVal->type != vcontained.type)
893 else if (IsAJsonbScalar(lhsVal))
895 if (compareJsonbScalarValue(lhsVal, &vcontained) != 0)
900 /* Nested container value (object or array) */
901 JsonbIterator *nestval, *nestContained;
903 Assert(lhsVal->type == jbvBinary);
904 Assert(vcontained.type == jbvBinary);
906 nestval = JsonbIteratorInit(lhsVal->binary.data);
907 nestContained = JsonbIteratorInit(vcontained.binary.data);
910 * Match "value" side of rhs datum object's pair recursively.
911 * It's a nested structure.
913 * Note that nesting still has to "match up" at the right
914 * nesting sub-levels. However, there need only be zero or
915 * more matching pairs (or elements) at each nesting level
916 * (provided the *rhs* pairs/elements *all* match on each
917 * level), which enables searching nested structures for a
918 * single String or other primitive type sub-datum quite
919 * effectively (provided the user constructed the rhs nested
920 * structure such that we "know where to look").
922 * In other words, the mapping of container nodes in the rhs
923 * "vcontained" Jsonb to internal nodes on the lhs is
924 * injective, and parent-child edges on the rhs must be mapped
925 * to parent-child edges on the lhs to satisfy the condition of
926 * containment (plus of course the mapped nodes must be equal).
928 if (!JsonbDeepContains(&nestval, &nestContained))
933 else if (rcont == WJB_BEGIN_ARRAY)
935 JsonbValue *lhsConts = NULL;
936 uint32 nLhsElems = vval.array.nElems;
938 Assert(vcontained.type == jbvArray);
941 * Handle distinction between "raw scalar" pseudo arrays, and real
944 * A raw scalar may contain another raw scalar, and an array may
945 * contain a raw scalar, but a raw scalar may not contain an array. We
946 * don't do something like this for the object case, since objects can
947 * only contain pairs, never raw scalars (a pair is represented by an
948 * rhs object argument with a single contained pair).
950 if (vval.array.rawScalar && !vcontained.array.rawScalar)
953 /* Work through rhs "is it contained within?" array */
956 rcont = JsonbIteratorNext(mContained, &vcontained, true);
959 * When we get through caller's rhs "is it contained within?" array
960 * without failing to find one of its values, it's contained.
962 if (rcont == WJB_END_ARRAY)
965 Assert(rcont == WJB_ELEM);
967 if (IsAJsonbScalar(&vcontained))
969 if (!findJsonbValueFromSuperHeader((*val)->buffer,
980 * If this is first container found in rhs array (at this
981 * depth), initialize temp lhs array of containers
983 if (lhsConts == NULL)
987 /* Make room for all possible values */
988 lhsConts = palloc(sizeof(JsonbValue) * nLhsElems);
990 for (i = 0; i < nLhsElems; i++)
992 /* Store all lhs elements in temp array*/
993 rcont = JsonbIteratorNext(val, &vval, true);
994 Assert(rcont == WJB_ELEM);
996 if (vval.type == jbvBinary)
997 lhsConts[j++] = vval;
1000 /* No container elements in temp array, so give up now */
1004 /* We may have only partially filled array */
1008 /* XXX: Nested array containment is O(N^2) */
1009 for (i = 0; i < nLhsElems; i++)
1011 /* Nested container value (object or array) */
1012 JsonbIterator *nestval, *nestContained;
1015 nestval = JsonbIteratorInit(lhsConts[i].binary.data);
1016 nestContained = JsonbIteratorInit(vcontained.binary.data);
1018 contains = JsonbDeepContains(&nestval, &nestContained);
1023 pfree(nestContained);
1029 * Report rhs container value is not contained if couldn't
1030 * match rhs container to *some* lhs cont
1039 elog(ERROR, "invalid jsonb container type");
1042 elog(ERROR, "unexpectedly fell off end of jsonb container");
1047 * Convert a Postgres text array to a Jsonb array, sorted and with
1048 * de-duplicated key elements. This is used for searching an object for items
1049 * in the array, so we enforce that the number of strings cannot exceed
1053 arrayToJsonbSortedArray(ArrayType *array)
1062 /* Extract data for sorting */
1063 deconstruct_array(array, TEXTOID, -1, false, 'i', &key_datums, &key_nulls,
1066 if (elem_count == 0)
1070 * A text array uses at least eight bytes per element, so any overflow in
1071 * "key_count * sizeof(JsonbPair)" is small enough for palloc() to catch.
1072 * However, credible improvements to the array format could invalidate that
1073 * assumption. Therefore, use an explicit check rather than relying on
1074 * palloc() to complain.
1076 if (elem_count > JSONB_MAX_PAIRS)
1078 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1079 errmsg("number of array elements (%d) exceeds maximum allowed Jsonb pairs (%zu)",
1080 elem_count, JSONB_MAX_PAIRS)));
1082 result = palloc(sizeof(JsonbValue));
1083 result->type = jbvArray;
1084 result->array.rawScalar = false;
1085 result->array.elems = palloc(sizeof(JsonbPair) * elem_count);
1087 for (i = 0, j = 0; i < elem_count; i++)
1091 result->array.elems[j].type = jbvString;
1092 result->array.elems[j].string.val = VARDATA(key_datums[i]);
1093 result->array.elems[j].string.len = VARSIZE(key_datums[i]) - VARHDRSZ;
1097 result->array.nElems = j;
1099 uniqueifyJsonbArray(result);
1104 * Hash a JsonbValue scalar value, mixing in the hash value with an existing
1105 * hash provided by the caller.
1107 * Some callers may wish to independently XOR in JB_FOBJECT and JB_FARRAY
1111 JsonbHashScalarValue(const JsonbValue * scalarVal, uint32 * hash)
1116 * Combine hash values of successive keys, values and elements by rotating
1117 * the previous value left 1 bit, then XOR'ing in the new
1118 * key/value/element's hash value.
1120 *hash = (*hash << 1) | (*hash >> 31);
1121 switch (scalarVal->type)
1127 tmp = hash_any((unsigned char *) scalarVal->string.val,
1128 scalarVal->string.len);
1132 /* Must be unaffected by trailing zeroes */
1133 tmp = DatumGetInt32(DirectFunctionCall1(hash_numeric,
1134 NumericGetDatum(scalarVal->numeric)));
1138 *hash ^= scalarVal->boolean? 0x02:0x04;
1141 elog(ERROR, "invalid jsonb scalar type");
1146 * Are two scalar JsonbValues of the same type a and b equal?
1148 * Does not use lexical comparisons. Therefore, it is essentially that this
1149 * never be used against Strings for anything other than searching for values
1150 * within a single jsonb.
1153 compareJsonbScalarValue(JsonbValue * aScalar, JsonbValue * bScalar)
1155 if (aScalar->type == bScalar->type)
1157 switch (aScalar->type)
1162 return lengthCompareJsonbStringValue(aScalar, bScalar, NULL);
1164 return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
1165 PointerGetDatum(aScalar->numeric),
1166 PointerGetDatum(bScalar->numeric)));
1168 if (aScalar->boolean != bScalar->boolean)
1169 return (aScalar->boolean > bScalar->boolean) ? 1 : -1;
1173 elog(ERROR, "invalid jsonb scalar type");
1176 elog(ERROR, "jsonb scalar type mismatch");
1181 * Standard lexical qsort() comparator of jsonb strings.
1183 * Sorts strings lexically, using the default database collation. Used by
1184 * B-Tree operators, where a lexical sort order is generally expected.
1187 lexicalCompareJsonbStringValue(const void *a, const void *b)
1189 const JsonbValue *va = (const JsonbValue *) a;
1190 const JsonbValue *vb = (const JsonbValue *) b;
1192 Assert(va->type == jbvString);
1193 Assert(vb->type == jbvString);
1195 return varstr_cmp(va->string.val, va->string.len, vb->string.val,
1196 vb->string.len, DEFAULT_COLLATION_OID);
1200 * Given a JsonbValue, convert to Jsonb and store in preallocated Jsonb buffer
1201 * sufficiently large to fit the value
1204 convertJsonb(JsonbValue * val, Jsonb *buffer)
1209 /* Should not already have binary representation */
1210 Assert(val->type != jbvBinary);
1212 state.buffer = buffer;
1213 /* Start from superheader */
1214 state.ptr = VARDATA(state.buffer);
1216 state.allState = palloc(sizeof(convertLevel) * state.levelSz);
1218 walkJsonbValueConversion(val, &state, 0);
1220 len = state.ptr - VARDATA(state.buffer);
1222 Assert(len <= val->estSize);
1227 * Walk the tree representation of Jsonb, as part of the process of converting
1228 * a JsonbValue to a Jsonb.
1230 * This high-level function takes care of recursion into sub-containers, but at
1231 * the top level calls putJsonbValueConversion once per sequential processing
1232 * token (in a manner similar to generic iteration).
1235 walkJsonbValueConversion(JsonbValue * val, convertState * cstate,
1240 check_stack_depth();
1249 putJsonbValueConversion(cstate, val, WJB_BEGIN_ARRAY, nestlevel);
1250 for (i = 0; i < val->array.nElems; i++)
1252 if (IsAJsonbScalar(&val->array.elems[i]) ||
1253 val->array.elems[i].type == jbvBinary)
1254 putJsonbValueConversion(cstate, val->array.elems + i,
1255 WJB_ELEM, nestlevel);
1257 walkJsonbValueConversion(val->array.elems + i, cstate,
1260 putJsonbValueConversion(cstate, val, WJB_END_ARRAY, nestlevel);
1265 putJsonbValueConversion(cstate, val, WJB_BEGIN_OBJECT, nestlevel);
1266 for (i = 0; i < val->object.nPairs; i++)
1268 putJsonbValueConversion(cstate, &val->object.pairs[i].key,
1269 WJB_KEY, nestlevel);
1271 if (IsAJsonbScalar(&val->object.pairs[i].value) ||
1272 val->object.pairs[i].value.type == jbvBinary)
1273 putJsonbValueConversion(cstate,
1274 &val->object.pairs[i].value,
1275 WJB_VALUE, nestlevel);
1277 walkJsonbValueConversion(&val->object.pairs[i].value,
1278 cstate, nestlevel + 1);
1280 putJsonbValueConversion(cstate, val, WJB_END_OBJECT, nestlevel);
1284 elog(ERROR, "unknown type of jsonb container");
1289 * walkJsonbValueConversion() worker. Add padding sufficient to int-align our
1290 * access to conversion buffer.
1293 short addPaddingInt(convertState * cstate)
1297 padlen = INTALIGN(cstate->ptr - VARDATA(cstate->buffer)) -
1298 (cstate->ptr - VARDATA(cstate->buffer));
1300 for (p = padlen; p > 0; p--)
1302 *cstate->ptr = '\0';
1310 * walkJsonbValueConversion() worker.
1312 * As part of the process of converting an arbitrary JsonbValue to a Jsonb,
1313 * copy over an arbitrary individual JsonbValue. This function may copy any
1314 * type of value, even containers (Objects/arrays). However, it is not
1315 * responsible for recursive aspects of walking the tree (so only top-level
1316 * Object/array details are handled).
1318 * No details about their keys/values/elements are handled recursively -
1319 * rather, the function is called as required for the start of an Object/Array,
1320 * and the end (i.e. there is one call per sequential processing WJB_* token).
1323 putJsonbValueConversion(convertState * cstate, JsonbValue * val, uint32 flags,
1326 if (level == cstate->levelSz)
1328 cstate->levelSz *= 2;
1329 cstate->allState = repalloc(cstate->allState,
1330 sizeof(convertLevel) * cstate->levelSz);
1333 cstate->contPtr = cstate->allState + level;
1335 if (flags & (WJB_BEGIN_ARRAY | WJB_BEGIN_OBJECT))
1337 Assert(((flags & WJB_BEGIN_ARRAY) && val->type == jbvArray) ||
1338 ((flags & WJB_BEGIN_OBJECT) && val->type == jbvObject));
1340 /* Initialize pointer into conversion buffer at this level */
1341 cstate->contPtr->begin = cstate->ptr;
1343 addPaddingInt(cstate);
1345 /* Initialize everything else at this level */
1346 cstate->contPtr->header = (uint32 *) cstate->ptr;
1347 /* Advance past header */
1348 cstate->ptr += sizeof(uint32);
1349 cstate->contPtr->meta = (JEntry *) cstate->ptr;
1350 cstate->contPtr->i = 0;
1352 if (val->type == jbvArray)
1354 *cstate->contPtr->header = val->array.nElems | JB_FARRAY;
1355 cstate->ptr += sizeof(JEntry) * val->array.nElems;
1357 if (val->array.rawScalar)
1359 Assert(val->array.nElems == 1);
1361 *cstate->contPtr->header |= JB_FSCALAR;
1366 *cstate->contPtr->header = val->object.nPairs | JB_FOBJECT;
1367 cstate->ptr += sizeof(JEntry) * val->object.nPairs * 2;
1370 else if (flags & WJB_ELEM)
1372 putScalarConversion(cstate, val, level, cstate->contPtr->i);
1373 cstate->contPtr->i++;
1375 else if (flags & WJB_KEY)
1377 Assert(val->type == jbvString);
1379 putScalarConversion(cstate, val, level, cstate->contPtr->i * 2);
1381 else if (flags & WJB_VALUE)
1383 putScalarConversion(cstate, val, level, cstate->contPtr->i * 2 + 1);
1384 cstate->contPtr->i++;
1386 else if (flags & (WJB_END_ARRAY | WJB_END_OBJECT))
1388 convertLevel *prevPtr; /* Prev container pointer */
1392 Assert(((flags & WJB_END_ARRAY) && val->type == jbvArray) ||
1393 ((flags & WJB_END_OBJECT) && val->type == jbvObject));
1398 len = cstate->ptr - (char *) cstate->contPtr->begin;
1400 prevPtr = cstate->contPtr - 1;
1402 if (*prevPtr->header & JB_FARRAY)
1406 prevPtr->meta[i].header = JENTRY_ISNEST;
1409 prevPtr->meta[0].header |= JENTRY_ISFIRST | len;
1411 prevPtr->meta[i].header |=
1412 (prevPtr->meta[i - 1].header & JENTRY_POSMASK) + len;
1414 else if (*prevPtr->header & JB_FOBJECT)
1416 i = 2 * prevPtr->i + 1; /* Value, not key */
1418 prevPtr->meta[i].header = JENTRY_ISNEST;
1420 prevPtr->meta[i].header |=
1421 (prevPtr->meta[i - 1].header & JENTRY_POSMASK) + len;
1425 elog(ERROR, "invalid jsonb container type");
1428 Assert(cstate->ptr - cstate->contPtr->begin <= val->estSize);
1433 elog(ERROR, "unknown flag encountered during jsonb tree walk");
1438 * As part of the process of converting an arbitrary JsonbValue to a Jsonb,
1439 * serialize and copy a scalar value into buffer.
1441 * This is a worker function for putJsonbValueConversion() (itself a worker for
1442 * walkJsonbValueConversion()). It handles the details with regard to Jentry
1443 * metadata peculiar to each scalar type.
1446 putScalarConversion(convertState * cstate, JsonbValue * scalarVal, uint32 level,
1452 cstate->contPtr = cstate->allState + level;
1455 cstate->contPtr->meta[0].header = JENTRY_ISFIRST;
1457 cstate->contPtr->meta[i].header = 0;
1459 switch (scalarVal->type)
1462 cstate->contPtr->meta[i].header |= JENTRY_ISNULL;
1465 cstate->contPtr->meta[i].header |=
1466 cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK;
1469 memcpy(cstate->ptr, scalarVal->string.val, scalarVal->string.len);
1470 cstate->ptr += scalarVal->string.len;
1473 cstate->contPtr->meta[0].header |= scalarVal->string.len;
1475 cstate->contPtr->meta[i].header |=
1476 (cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK) +
1477 scalarVal->string.len;
1480 numlen = VARSIZE_ANY(scalarVal->numeric);
1481 padlen = addPaddingInt(cstate);
1483 memcpy(cstate->ptr, scalarVal->numeric, numlen);
1484 cstate->ptr += numlen;
1486 cstate->contPtr->meta[i].header |= JENTRY_ISNUMERIC;
1488 cstate->contPtr->meta[0].header |= padlen + numlen;
1490 cstate->contPtr->meta[i].header |=
1491 (cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK)
1495 cstate->contPtr->meta[i].header |= (scalarVal->boolean) ?
1496 JENTRY_ISTRUE : JENTRY_ISFALSE;
1499 cstate->contPtr->meta[i].header |=
1500 cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK;
1503 elog(ERROR, "invalid jsonb scalar type");
1508 * Given superheader pointer into buffer, initialize iterator. Must be a
1512 iteratorFromContainerBuf(JsonbIterator * it, JsonbSuperHeader sheader)
1514 uint32 superheader = *(uint32 *) sheader;
1516 it->containerType = superheader & (JB_FARRAY | JB_FOBJECT);
1517 it->nElems = superheader & JB_CMASK;
1518 it->buffer = sheader;
1520 /* Array starts just after header */
1521 it->meta = (JEntry *) (sheader + sizeof(uint32));
1522 it->state = jbi_start;
1524 switch (it->containerType)
1528 (char *) it->meta + it->nElems * sizeof(JEntry);
1529 it->isScalar = (superheader & JB_FSCALAR) != 0;
1530 /* This is either a "raw scalar", or an array */
1531 Assert(!it->isScalar || it->nElems == 1);
1535 * Offset reflects that nElems indicates JsonbPairs in an object.
1536 * Each key and each value contain Jentry metadata just the same.
1539 (char *) it->meta + it->nElems * sizeof(JEntry) * 2;
1542 elog(ERROR, "unknown type of jsonb container");
1547 * JsonbIteratorNext() worker
1549 * Returns bool indicating if v was a non-jbvBinary container, and thus if
1550 * further recursion is required by caller (according to its skipNested
1551 * preference). If it is required, we set the caller's iterator for further
1552 * recursion into the nested value. If we're going to skip nested items, just
1553 * set v to a jbvBinary value, but don't set caller's iterator.
1555 * Unlike with containers (either in this function or in any
1556 * JsonbIteratorNext() infrastructure), we fully convert from what is
1557 * ultimately a Jsonb on-disk representation, to a JsonbValue in-memory
1558 * representation (for scalar values only). JsonbIteratorNext() initializes
1559 * container Jsonbvalues, but without a sane private buffer. For scalar values
1560 * it has to be done for real (even if we don't actually allocate more memory
1561 * to do this. The point is that our JsonbValues scalars can be passed around
1565 formIterIsContainer(JsonbIterator ** it, JsonbValue * val, JEntry * ent,
1568 if (JBE_ISNULL(*ent))
1570 val->type = jbvNull;
1571 val->estSize = sizeof(JEntry);
1575 else if (JBE_ISSTRING(*ent))
1577 val->type = jbvString;
1578 val->string.val = (*it)->dataProper + JBE_OFF(*ent);
1579 val->string.len = JBE_LEN(*ent);
1580 val->estSize = sizeof(JEntry) + val->string.len;
1584 else if (JBE_ISNUMERIC(*ent))
1586 val->type = jbvNumeric;
1587 val->numeric = (Numeric) ((*it)->dataProper + INTALIGN(JBE_OFF(*ent)));
1588 val->estSize = 2 * sizeof(JEntry) + VARSIZE_ANY(val->numeric);
1592 else if (JBE_ISBOOL(*ent))
1594 val->type = jbvBool;
1595 val->boolean = JBE_ISBOOL_TRUE(*ent) != 0;
1596 val->estSize = sizeof(JEntry);
1600 else if (skipNested)
1602 val->type = jbvBinary;
1603 val->binary.data = (*it)->dataProper + INTALIGN(JBE_OFF(*ent));
1604 val->binary.len = JBE_LEN(*ent) - (INTALIGN(JBE_OFF(*ent)) - JBE_OFF(*ent));
1605 val->estSize = val->binary.len + 2 * sizeof(JEntry);
1612 * Must be container type, so setup caller's iterator to point to that,
1613 * and return indication of that.
1615 * Get child iterator.
1617 JsonbIterator *child = palloc(sizeof(JsonbIterator));
1619 iteratorFromContainerBuf(child,
1620 (*it)->dataProper + INTALIGN(JBE_OFF(*ent)));
1622 child->parent = *it;
1630 * JsonbIteratorNext() worker: Return parent, while freeing memory for current
1633 static JsonbIterator *
1634 freeAndGetParent(JsonbIterator * it)
1636 JsonbIterator *v = it->parent;
1643 * pushJsonbValue() worker: Iteration-like forming of Jsonb
1645 static JsonbParseState *
1646 pushState(JsonbParseState ** pstate)
1648 JsonbParseState *ns = palloc(sizeof(JsonbParseState));
1655 * pushJsonbValue() worker: Append a pair key to state when generating a Jsonb
1658 appendKey(JsonbParseState * pstate, JsonbValue * string)
1660 JsonbValue *object = &pstate->contVal;
1662 Assert(object->type == jbvObject);
1663 Assert(string->type == jbvString);
1665 if (object->object.nPairs >= JSONB_MAX_PAIRS)
1667 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1668 errmsg("number of jsonb object pairs exceeds the maximum allowed (%zu)",
1671 if (object->object.nPairs >= pstate->size)
1674 object->object.pairs = repalloc(object->object.pairs,
1675 sizeof(JsonbPair) * pstate->size);
1678 object->object.pairs[object->object.nPairs].key = *string;
1679 object->object.pairs[object->object.nPairs].order = object->object.nPairs;
1681 object->estSize += string->estSize;
1685 * pushJsonbValue() worker: Append a pair value to state when generating a
1689 appendValue(JsonbParseState * pstate, JsonbValue * scalarVal)
1691 JsonbValue *object = &pstate->contVal;
1693 Assert(object->type == jbvObject);
1695 object->object.pairs[object->object.nPairs++].value = *scalarVal;
1696 object->estSize += scalarVal->estSize;
1700 * pushJsonbValue() worker: Append an element to state when generating a Jsonb
1703 appendElement(JsonbParseState * pstate, JsonbValue * scalarVal)
1705 JsonbValue *array = &pstate->contVal;
1707 Assert(array->type == jbvArray);
1709 if (array->array.nElems >= JSONB_MAX_ELEMS)
1711 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1712 errmsg("number of jsonb array elements exceeds the maximum allowed (%zu)",
1715 if (array->array.nElems >= pstate->size)
1718 array->array.elems = repalloc(array->array.elems,
1719 sizeof(JsonbValue) * pstate->size);
1722 array->array.elems[array->array.nElems++] = *scalarVal;
1723 array->estSize += scalarVal->estSize;
1727 * Compare two jbvString JsonbValue values, a and b.
1729 * This is a special qsort_arg() comparator used to sort strings in certain
1730 * internal contexts where it is sufficient to have a well-defined sort order.
1731 * In particular, object pair keys are sorted according to this criteria to
1732 * facilitate cheap binary searches where we don't care about lexical sort
1735 * a and b are first sorted based on their length. If a tie-breaker is
1736 * required, only then do we consider string binary equality.
1738 * Third argument 'binequal' may point to a bool. If it's set, *binequal is set
1739 * to true iff a and b have full binary equality, since some callers have an
1740 * interest in whether the two values are equal or merely equivalent.
1743 lengthCompareJsonbStringValue(const void *a, const void *b, void *binequal)
1745 const JsonbValue *va = (const JsonbValue *) a;
1746 const JsonbValue *vb = (const JsonbValue *) b;
1749 Assert(va->type == jbvString);
1750 Assert(vb->type == jbvString);
1752 if (va->string.len == vb->string.len)
1754 res = memcmp(va->string.val, vb->string.val, va->string.len);
1755 if (res == 0 && binequal)
1756 *((bool *) binequal) = true;
1760 res = (va->string.len > vb->string.len) ? 1 : -1;
1767 * qsort_arg() comparator to compare JsonbPair values.
1769 * Function implemented in terms of lengthCompareJsonbStringValue(), and thus the
1770 * same "arg setting" hack will be applied here in respect of the pair's key
1773 * N.B: String comparisons here are "length-wise"
1775 * Pairs with equals keys are ordered such that the order field is respected.
1778 lengthCompareJsonbPair(const void *a, const void *b, void *binequal)
1780 const JsonbPair *pa = (const JsonbPair *) a;
1781 const JsonbPair *pb = (const JsonbPair *) b;
1784 res = lengthCompareJsonbStringValue(&pa->key, &pb->key, binequal);
1787 * Guarantee keeping order of equal pair. Unique algorithm will prefer
1788 * first element as value.
1791 res = (pa->order > pb->order) ? -1 : 1;
1797 * Sort and unique-ify pairs in JsonbValue object
1800 uniqueifyJsonbObject(JsonbValue * object)
1802 bool hasNonUniq = false;
1804 Assert(object->type == jbvObject);
1806 if (object->object.nPairs > 1)
1807 qsort_arg(object->object.pairs, object->object.nPairs, sizeof(JsonbPair),
1808 lengthCompareJsonbPair, &hasNonUniq);
1812 JsonbPair *ptr = object->object.pairs + 1,
1813 *res = object->object.pairs;
1815 while (ptr - object->object.pairs < object->object.nPairs)
1817 /* Avoid copying over duplicate */
1818 if (lengthCompareJsonbStringValue(ptr, res, NULL) == 0)
1820 object->estSize -= ptr->key.estSize + ptr->value.estSize;
1826 memcpy(res, ptr, sizeof(JsonbPair));
1831 object->object.nPairs = res + 1 - object->object.pairs;
1836 * Sort and unique-ify JsonbArray.
1838 * Sorting uses internal ordering.
1841 uniqueifyJsonbArray(JsonbValue * array)
1843 bool hasNonUniq = false;
1845 Assert(array->type == jbvArray);
1848 * Actually sort values, determining if any were equal on the basis of full
1849 * binary equality (rather than just having the same string length).
1851 if (array->array.nElems > 1)
1852 qsort_arg(array->array.elems, array->array.nElems,
1853 sizeof(JsonbValue), lengthCompareJsonbStringValue,
1858 JsonbValue *ptr = array->array.elems + 1,
1859 *res = array->array.elems;
1861 while (ptr - array->array.elems < array->array.nElems)
1863 /* Avoid copying over duplicate */
1864 if (lengthCompareJsonbStringValue(ptr, res, NULL) != 0)
1873 array->array.nElems = res + 1 - array->array.elems;