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.val.array.rawScalar = true;
124 scalarArray.val.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->val.binary.len);
146 SET_VARSIZE(out, VARHDRSZ + val->val.binary.len);
147 memcpy(VARDATA(out), val->val.binary.data, val->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
186 * expectation of the same container types having differing lengths
187 * (as when we 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);
213 * This could be a "raw scalar" pseudo array. That's
214 * a special case here though, since we still want the
215 * general type-based comparisons to apply, and as far
216 * as we're concerned a pseudo array is just a scalar.
218 if (va.val.array.rawScalar != vb.val.array.rawScalar)
219 res = (va.val.array.rawScalar) ? -1 : 1;
220 if (va.val.array.nElems != vb.val.array.nElems)
221 res = (va.val.array.nElems > vb.val.array.nElems) ? 1 : -1;
224 if (va.val.object.nPairs != vb.val.object.nPairs)
225 res = (va.val.object.nPairs > vb.val.object.nPairs) ? 1 : -1;
228 elog(ERROR, "unexpected jbvBinary value");
233 /* Type-defined order */
234 res = (va.type > vb.type) ? 1 : -1;
240 * It's safe to assume that the types differed.
242 * If the two values were the same container type, then there'd
243 * have been a chance to observe the variation in the number of
244 * elements/pairs (when processing WJB_BEGIN_OBJECT, say). They
245 * can't be scalar types either, because then they'd have to be
246 * contained in containers already ruled unequal due to differing
247 * numbers of pairs/elements, or already directly ruled unequal
248 * with a call to the underlying type's comparator.
250 Assert(va.type != vb.type);
251 Assert(va.type == jbvArray || va.type == jbvObject);
252 Assert(vb.type == jbvArray || vb.type == jbvObject);
253 /* Type-defined order */
254 res = (va.type > vb.type) ? 1 : -1;
261 JsonbIterator *i = ita->parent;
268 JsonbIterator *i = itb->parent;
278 * Find value in object (i.e. the "value" part of some key/value pair in an
279 * object), or find a matching element if we're looking through an array. Do
280 * so on the basis of equality of the object keys only, or alternatively
281 * element values only, with a caller-supplied value "key". The "flags"
282 * argument allows the caller to specify which container types are of interest.
284 * This exported utility function exists to facilitate various cases concerned
285 * with "containment". If asked to look through an object, the caller had
286 * better pass a Jsonb String, because their keys can only be strings.
287 * Otherwise, for an array, any type of JsonbValue will do.
289 * In order to proceed with the search, it is necessary for callers to have
290 * both specified an interest in exactly one particular container type with an
291 * appropriate flag, as well as having the pointed-to Jsonb superheader be of
292 * one of those same container types at the top level. (Actually, we just do
293 * whichever makes sense to save callers the trouble of figuring it out - at
294 * most one can make sense, because the super header either points to an array
295 * (possible a "raw scalar" pseudo array) or an object.)
297 * Note that we can return a jbvBinary JsonbValue if this is called on an
298 * object, but we never do so on an array. If the caller asks to look through
299 * a container type that is not of the type pointed to by the superheader,
300 * immediately fall through and return NULL. If we cannot find the value,
301 * return NULL. Otherwise, return palloc()'d copy of value.
303 * lowbound can be NULL, but if not it's used to establish a point at which to
304 * start searching. If the value searched for is found, then lowbound is then
305 * set to an offset into the array or object. Typically, this is used to
306 * exploit the ordering of objects to avoid redundant work, by also sorting a
307 * list of items to be checked using the internal sort criteria for objects
308 * (object pair keys), and then, when searching for the second or subsequent
309 * item, picking it up where we left off knowing that the second or subsequent
310 * item can not be at a point below the low bound set when the first was found.
311 * This is only useful for objects, not arrays (which have a user-defined
312 * order), so array superheader Jsonbs should just pass NULL. Moreover, it's
313 * only useful because we only match object pairs on the basis of their key, so
314 * presumably anyone exploiting this is only interested in matching Object keys
315 * with a String. lowbound is given in units of pairs, not underlying values.
318 findJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 flags,
319 uint32 *lowbound, JsonbValue *key)
321 uint32 superheader = *(uint32 *) sheader;
322 JEntry *array = (JEntry *) (sheader + sizeof(uint32));
323 int count = (superheader & JB_CMASK);
324 JsonbValue *result = palloc(sizeof(JsonbValue));
326 Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
328 if (flags & JB_FARRAY & superheader)
330 char *data = (char *) (array + (superheader & JB_CMASK));
333 for (i = 0; i < count; i++)
335 JEntry *e = array + i;
337 if (JBE_ISNULL(*e) && key->type == jbvNull)
339 result->type = jbvNull;
340 result->estSize = sizeof(JEntry);
342 else if (JBE_ISSTRING(*e) && key->type == jbvString)
344 result->type = jbvString;
345 result->val.string.val = data + JBE_OFF(*e);
346 result->val.string.len = JBE_LEN(*e);
347 result->estSize = sizeof(JEntry) + result->val.string.len;
349 else if (JBE_ISNUMERIC(*e) && key->type == jbvNumeric)
351 result->type = jbvNumeric;
352 result->val.numeric = (Numeric) (data + INTALIGN(JBE_OFF(*e)));
354 result->estSize = 2 * sizeof(JEntry) +
355 VARSIZE_ANY(result->val.numeric);
357 else if (JBE_ISBOOL(*e) && key->type == jbvBool)
359 result->type = jbvBool;
360 result->val.boolean = JBE_ISBOOL_TRUE(*e) != 0;
361 result->estSize = sizeof(JEntry);
366 if (compareJsonbScalarValue(key, result) == 0)
370 else if (flags & JB_FOBJECT & superheader)
372 /* Since this is an object, account for *Pairs* of Jentrys */
373 char *data = (char *) (array + (superheader & JB_CMASK) * 2);
374 uint32 stopLow = lowbound ? *lowbound : 0,
377 /* Object key past by caller must be a string */
378 Assert(key->type == jbvString);
380 /* Binary search on object/pair keys *only* */
381 while (stopLow < count)
385 JsonbValue candidate;
388 * Note how we compensate for the fact that we're iterating
389 * through pairs (not entries) throughout.
391 stopMiddle = stopLow + (count - stopLow) / 2;
393 entry = array + stopMiddle * 2;
395 candidate.type = jbvString;
396 candidate.val.string.val = data + JBE_OFF(*entry);
397 candidate.val.string.len = JBE_LEN(*entry);
398 candidate.estSize = sizeof(JEntry) + candidate.val.string.len;
400 difference = lengthCompareJsonbStringValue(&candidate, key, NULL);
404 /* Found our value (from key/value pair) */
405 JEntry *v = entry + 1;
408 *lowbound = stopMiddle + 1;
412 result->type = jbvNull;
413 result->estSize = sizeof(JEntry);
415 else if (JBE_ISSTRING(*v))
417 result->type = jbvString;
418 result->val.string.val = data + JBE_OFF(*v);
419 result->val.string.len = JBE_LEN(*v);
420 result->estSize = sizeof(JEntry) + result->val.string.len;
422 else if (JBE_ISNUMERIC(*v))
424 result->type = jbvNumeric;
425 result->val.numeric = (Numeric) (data + INTALIGN(JBE_OFF(*v)));
427 result->estSize = 2 * sizeof(JEntry) +
428 VARSIZE_ANY(result->val.numeric);
430 else if (JBE_ISBOOL(*v))
432 result->type = jbvBool;
433 result->val.boolean = JBE_ISBOOL_TRUE(*v) != 0;
434 result->estSize = sizeof(JEntry);
439 * See header comments to understand why this never
440 * happens with arrays
442 result->type = jbvBinary;
443 result->val.binary.data = data + INTALIGN(JBE_OFF(*v));
444 result->val.binary.len = JBE_LEN(*v) -
445 (INTALIGN(JBE_OFF(*v)) - JBE_OFF(*v));
446 result->estSize = 2 * sizeof(JEntry) + result->val.binary.len;
454 stopLow = stopMiddle + 1;
470 * Get i-th value of Jsonb array from superheader.
472 * Returns palloc()'d copy of value.
475 getIthJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 i)
477 uint32 superheader = *(uint32 *) sheader;
483 result = palloc(sizeof(JsonbValue));
485 if (i >= (superheader & JB_CMASK))
488 array = (JEntry *) (sheader + sizeof(uint32));
490 if (superheader & JB_FARRAY)
493 data = (char *) (array + (superheader & JB_CMASK));
497 elog(ERROR, "not a jsonb array");
502 result->type = jbvNull;
503 result->estSize = sizeof(JEntry);
505 else if (JBE_ISSTRING(*e))
507 result->type = jbvString;
508 result->val.string.val = data + JBE_OFF(*e);
509 result->val.string.len = JBE_LEN(*e);
510 result->estSize = sizeof(JEntry) + result->val.string.len;
512 else if (JBE_ISNUMERIC(*e))
514 result->type = jbvNumeric;
515 result->val.numeric = (Numeric) (data + INTALIGN(JBE_OFF(*e)));
517 result->estSize = 2 * sizeof(JEntry) + VARSIZE_ANY(result->val.numeric);
519 else if (JBE_ISBOOL(*e))
521 result->type = jbvBool;
522 result->val.boolean = JBE_ISBOOL_TRUE(*e) != 0;
523 result->estSize = sizeof(JEntry);
527 result->type = jbvBinary;
528 result->val.binary.data = data + INTALIGN(JBE_OFF(*e));
529 result->val.binary.len = JBE_LEN(*e) - (INTALIGN(JBE_OFF(*e)) - JBE_OFF(*e));
530 result->estSize = result->val.binary.len + 2 * sizeof(JEntry);
537 * Push JsonbValue into JsonbParseState.
539 * Used when parsing JSON tokens to form Jsonb, or when converting an in-memory
540 * JsonbValue to a Jsonb.
542 * Initial state of *JsonbParseState is NULL, since it'll be allocated here
543 * originally (caller will get JsonbParseState back by reference).
545 * Only sequential tokens pertaining to non-container types should pass a
546 * JsonbValue. There is one exception -- WJB_BEGIN_ARRAY callers may pass a
547 * "raw scalar" pseudo array to append that.
550 pushJsonbValue(JsonbParseState **pstate, int seq, JsonbValue *scalarVal)
552 JsonbValue *result = NULL;
556 case WJB_BEGIN_ARRAY:
557 Assert(!scalarVal || scalarVal->val.array.rawScalar);
558 *pstate = pushState(pstate);
559 result = &(*pstate)->contVal;
560 (*pstate)->contVal.type = jbvArray;
561 (*pstate)->contVal.estSize = 3 * sizeof(JEntry);
562 (*pstate)->contVal.val.array.nElems = 0;
563 (*pstate)->contVal.val.array.rawScalar = (scalarVal &&
564 scalarVal->val.array.rawScalar);
565 if (scalarVal && scalarVal->val.array.nElems > 0)
567 /* Assume that this array is still really a scalar */
568 Assert(scalarVal->type == jbvArray);
569 (*pstate)->size = scalarVal->val.array.nElems;
575 (*pstate)->contVal.val.array.elems = palloc(sizeof(JsonbValue) *
578 case WJB_BEGIN_OBJECT:
580 *pstate = pushState(pstate);
581 result = &(*pstate)->contVal;
582 (*pstate)->contVal.type = jbvObject;
583 (*pstate)->contVal.estSize = 3 * sizeof(JEntry);
584 (*pstate)->contVal.val.object.nPairs = 0;
586 (*pstate)->contVal.val.object.pairs = palloc(sizeof(JsonbPair) *
590 Assert(scalarVal->type == jbvString);
591 appendKey(*pstate, scalarVal);
594 Assert(IsAJsonbScalar(scalarVal) ||
595 scalarVal->type == jbvBinary);
596 appendValue(*pstate, scalarVal);
599 Assert(IsAJsonbScalar(scalarVal) ||
600 scalarVal->type == jbvBinary);
601 appendElement(*pstate, scalarVal);
604 uniqueifyJsonbObject(&(*pstate)->contVal);
606 /* Steps here common to WJB_END_OBJECT case */
608 result = &(*pstate)->contVal;
611 * Pop stack and push current array/object as value in parent
614 *pstate = (*pstate)->next;
617 switch ((*pstate)->contVal.type)
620 appendElement(*pstate, result);
623 appendValue(*pstate, result);
626 elog(ERROR, "invalid jsonb container type");
631 elog(ERROR, "unrecognized jsonb sequential processing token");
638 * Given a Jsonb superheader, expand to JsonbIterator to iterate over items
639 * fully expanded to in-memory representation for manipulation.
641 * See JsonbIteratorNext() for notes on memory management.
644 JsonbIteratorInit(JsonbSuperHeader sheader)
646 JsonbIterator *it = palloc(sizeof(JsonbIterator));
648 iteratorFromContainerBuf(it, sheader);
655 * Get next JsonbValue while iterating
657 * Caller should initially pass their own, original iterator. They may get
658 * back a child iterator palloc()'d here instead. The function can be relied
659 * on to free those child iterators, lest the memory allocated for highly
660 * nested objects become unreasonable, but only if callers don't end iteration
661 * early (by breaking upon having found something in a search, for example).
663 * Callers in such a scenario, that are particularly sensitive to leaking
664 * memory in a long-lived context may walk the ancestral tree from the final
665 * iterator we left them with to its oldest ancestor, pfree()ing as they go.
666 * They do not have to free any other memory previously allocated for iterators
667 * but not accessible as direct ancestors of the iterator they're last passed
670 * Returns "Jsonb sequential processing" token value. Iterator "state"
671 * reflects the current stage of the process in a less granular fashion, and is
672 * mostly used here to track things internally with respect to particular
675 * Clients of this function should not have to handle any jbvBinary values
676 * (since recursive calls will deal with this), provided skipNested is false.
677 * It is our job to expand the jbvBinary representation without bothering them
678 * with it. However, clients should not take it upon themselves to touch array
679 * or Object element/pair buffers, since their element/pair pointers are
683 JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
685 JsonbIterState state;
687 /* Guard against stack overflow due to overly complex Jsonb */
690 /* Recursive caller may have original caller's iterator */
694 state = (*it)->state;
696 if ((*it)->containerType == JB_FARRAY)
698 if (state == jbi_start)
700 /* Set v to array on first array call */
701 val->type = jbvArray;
702 val->val.array.nElems = (*it)->nElems;
705 * v->val.array.elems is not actually set, because we aren't doing
708 val->val.array.rawScalar = (*it)->isScalar;
710 /* Set state for next call */
711 (*it)->state = jbi_elem;
712 return WJB_BEGIN_ARRAY;
714 else if (state == jbi_elem)
716 if ((*it)->i >= (*it)->nElems)
719 * All elements within array already processed. Report this
720 * to caller, and give it back original parent iterator (which
721 * independently tracks iteration progress at its level of
724 *it = freeAndGetParent(*it);
725 return WJB_END_ARRAY;
727 else if (formIterIsContainer(it, val, &(*it)->meta[(*it)->i++],
731 * New child iterator acquired within formIterIsContainer.
732 * Recurse into container. Don't directly return jbvBinary
733 * value to top-level client.
735 return JsonbIteratorNext(it, val, skipNested);
739 /* Scalar item in array */
744 else if ((*it)->containerType == JB_FOBJECT)
746 if (state == jbi_start)
748 /* Set v to object on first object call */
749 val->type = jbvObject;
750 val->val.object.nPairs = (*it)->nElems;
753 * v->val.object.pairs is not actually set, because we aren't
754 * doing a full conversion
757 /* Set state for next call */
758 (*it)->state = jbi_key;
759 return WJB_BEGIN_OBJECT;
761 else if (state == jbi_key)
763 if ((*it)->i >= (*it)->nElems)
766 * All pairs within object already processed. Report this to
767 * caller, and give it back original containing iterator
768 * (which independently tracks iteration progress at its level
771 *it = freeAndGetParent(*it);
772 return WJB_END_OBJECT;
777 * Return binary item key (ensured by setting skipNested to
778 * false directly). No child iterator, no further recursion.
779 * When control reaches here, it's probably from a recursive
782 if (formIterIsContainer(it, val, &(*it)->meta[(*it)->i * 2], false))
783 elog(ERROR, "unexpected container as object key");
785 Assert(val->type == jbvString);
786 /* Set state for next call */
787 (*it)->state = jbi_value;
791 else if (state == jbi_value)
793 /* Set state for next call */
794 (*it)->state = jbi_key;
797 * Value may be a container, in which case we recurse with new,
798 * child iterator. If it is, don't bother !skipNested callers
799 * with dealing with the jbvBinary representation.
801 if (formIterIsContainer(it, val, &(*it)->meta[((*it)->i++) * 2 + 1],
803 return JsonbIteratorNext(it, val, skipNested);
809 elog(ERROR, "invalid iterator state");
814 * Worker for "contains" operator's function
816 * Formally speaking, containment is top-down, unordered subtree isomorphism.
818 * Takes iterators that belong to some container type. These iterators
819 * "belong" to those values in the sense that they've just been initialized in
820 * respect of them by the caller (perhaps in a nested fashion).
822 * "val" is lhs Jsonb, and mContained is rhs Jsonb when called from top level.
823 * We determine if mContained is contained within val.
826 JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
834 * Guard against stack overflow due to overly complex Jsonb.
836 * Functions called here independently take this precaution, but that
837 * might not be sufficient since this is also a recursive function.
841 rval = JsonbIteratorNext(val, &vval, false);
842 rcont = JsonbIteratorNext(mContained, &vcontained, false);
847 * The differing return values can immediately be taken as indicating
848 * two differing container types at this nesting level, which is
849 * sufficient reason to give up entirely (but it should be the case
850 * that they're both some container type).
852 Assert(rval == WJB_BEGIN_OBJECT || rval == WJB_BEGIN_ARRAY);
853 Assert(rcont == WJB_BEGIN_OBJECT || rcont == WJB_BEGIN_ARRAY);
856 else if (rcont == WJB_BEGIN_OBJECT)
858 JsonbValue *lhsVal; /* lhsVal is from pair in lhs object */
860 Assert(vcontained.type == jbvObject);
862 /* Work through rhs "is it contained within?" object */
865 rcont = JsonbIteratorNext(mContained, &vcontained, false);
868 * When we get through caller's rhs "is it contained within?"
869 * object without failing to find one of its values, it's
872 if (rcont == WJB_END_OBJECT)
875 Assert(rcont == WJB_KEY);
877 /* First, find value by key... */
878 lhsVal = findJsonbValueFromSuperHeader((*val)->buffer,
887 * ...at this stage it is apparent that there is at least a key
888 * match for this rhs pair.
890 rcont = JsonbIteratorNext(mContained, &vcontained, true);
892 Assert(rcont == WJB_VALUE);
895 * Compare rhs pair's value with lhs pair's value just found using
898 if (lhsVal->type != vcontained.type)
902 else if (IsAJsonbScalar(lhsVal))
904 if (compareJsonbScalarValue(lhsVal, &vcontained) != 0)
909 /* Nested container value (object or array) */
910 JsonbIterator *nestval,
913 Assert(lhsVal->type == jbvBinary);
914 Assert(vcontained.type == jbvBinary);
916 nestval = JsonbIteratorInit(lhsVal->val.binary.data);
917 nestContained = JsonbIteratorInit(vcontained.val.binary.data);
920 * Match "value" side of rhs datum object's pair recursively.
921 * It's a nested structure.
923 * Note that nesting still has to "match up" at the right
924 * nesting sub-levels. However, there need only be zero or
925 * more matching pairs (or elements) at each nesting level
926 * (provided the *rhs* pairs/elements *all* match on each
927 * level), which enables searching nested structures for a
928 * single String or other primitive type sub-datum quite
929 * effectively (provided the user constructed the rhs nested
930 * structure such that we "know where to look").
932 * In other words, the mapping of container nodes in the rhs
933 * "vcontained" Jsonb to internal nodes on the lhs is
934 * injective, and parent-child edges on the rhs must be mapped
935 * to parent-child edges on the lhs to satisfy the condition
936 * of containment (plus of course the mapped nodes must be
939 if (!JsonbDeepContains(&nestval, &nestContained))
944 else if (rcont == WJB_BEGIN_ARRAY)
946 JsonbValue *lhsConts = NULL;
947 uint32 nLhsElems = vval.val.array.nElems;
949 Assert(vcontained.type == jbvArray);
952 * Handle distinction between "raw scalar" pseudo arrays, and real
955 * A raw scalar may contain another raw scalar, and an array may
956 * contain a raw scalar, but a raw scalar may not contain an array. We
957 * don't do something like this for the object case, since objects can
958 * only contain pairs, never raw scalars (a pair is represented by an
959 * rhs object argument with a single contained pair).
961 if (vval.val.array.rawScalar && !vcontained.val.array.rawScalar)
964 /* Work through rhs "is it contained within?" array */
967 rcont = JsonbIteratorNext(mContained, &vcontained, true);
970 * When we get through caller's rhs "is it contained within?"
971 * array without failing to find one of its values, it's
974 if (rcont == WJB_END_ARRAY)
977 Assert(rcont == WJB_ELEM);
979 if (IsAJsonbScalar(&vcontained))
981 if (!findJsonbValueFromSuperHeader((*val)->buffer,
992 * If this is first container found in rhs array (at this
993 * depth), initialize temp lhs array of containers
995 if (lhsConts == NULL)
999 /* Make room for all possible values */
1000 lhsConts = palloc(sizeof(JsonbValue) * nLhsElems);
1002 for (i = 0; i < nLhsElems; i++)
1004 /* Store all lhs elements in temp array */
1005 rcont = JsonbIteratorNext(val, &vval, true);
1006 Assert(rcont == WJB_ELEM);
1008 if (vval.type == jbvBinary)
1009 lhsConts[j++] = vval;
1012 /* No container elements in temp array, so give up now */
1016 /* We may have only partially filled array */
1020 /* XXX: Nested array containment is O(N^2) */
1021 for (i = 0; i < nLhsElems; i++)
1023 /* Nested container value (object or array) */
1024 JsonbIterator *nestval,
1028 nestval = JsonbIteratorInit(lhsConts[i].val.binary.data);
1029 nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1031 contains = JsonbDeepContains(&nestval, &nestContained);
1036 pfree(nestContained);
1042 * Report rhs container value is not contained if couldn't
1043 * match rhs container to *some* lhs cont
1052 elog(ERROR, "invalid jsonb container type");
1055 elog(ERROR, "unexpectedly fell off end of jsonb container");
1060 * Convert a Postgres text array to a Jsonb array, sorted and with
1061 * de-duplicated key elements. This is used for searching an object for items
1062 * in the array, so we enforce that the number of strings cannot exceed
1066 arrayToJsonbSortedArray(ArrayType *array)
1075 /* Extract data for sorting */
1076 deconstruct_array(array, TEXTOID, -1, false, 'i', &key_datums, &key_nulls,
1079 if (elem_count == 0)
1083 * A text array uses at least eight bytes per element, so any overflow in
1084 * "key_count * sizeof(JsonbPair)" is small enough for palloc() to catch.
1085 * However, credible improvements to the array format could invalidate
1086 * that assumption. Therefore, use an explicit check rather than relying
1087 * on palloc() to complain.
1089 if (elem_count > JSONB_MAX_PAIRS)
1091 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1092 errmsg("number of array elements (%d) exceeds maximum allowed Jsonb pairs (%zu)",
1093 elem_count, JSONB_MAX_PAIRS)));
1095 result = palloc(sizeof(JsonbValue));
1096 result->type = jbvArray;
1097 result->val.array.rawScalar = false;
1098 result->val.array.elems = palloc(sizeof(JsonbPair) * elem_count);
1100 for (i = 0, j = 0; i < elem_count; i++)
1104 result->val.array.elems[j].type = jbvString;
1105 result->val.array.elems[j].val.string.val = VARDATA(key_datums[i]);
1106 result->val.array.elems[j].val.string.len = VARSIZE(key_datums[i]) - VARHDRSZ;
1110 result->val.array.nElems = j;
1112 uniqueifyJsonbArray(result);
1117 * Hash a JsonbValue scalar value, mixing the hash value into an existing
1118 * hash provided by the caller.
1120 * Some callers may wish to independently XOR in JB_FOBJECT and JB_FARRAY
1124 JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash)
1128 /* Compute hash value for scalarVal */
1129 switch (scalarVal->type)
1135 tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->val.string.val,
1136 scalarVal->val.string.len));
1139 /* Must hash equal numerics to equal hash codes */
1140 tmp = DatumGetUInt32(DirectFunctionCall1(hash_numeric,
1141 NumericGetDatum(scalarVal->val.numeric)));
1144 tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1147 elog(ERROR, "invalid jsonb scalar type");
1148 tmp = 0; /* keep compiler quiet */
1153 * Combine hash values of successive keys, values and elements by rotating
1154 * the previous value left 1 bit, then XOR'ing in the new
1155 * key/value/element's hash value.
1157 *hash = (*hash << 1) | (*hash >> 31);
1162 * Are two scalar JsonbValues of the same type a and b equal?
1164 * Does not use lexical comparisons. Therefore, it is essentially that this
1165 * never be used against Strings for anything other than searching for values
1166 * within a single jsonb.
1169 compareJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar)
1171 if (aScalar->type == bScalar->type)
1173 switch (aScalar->type)
1178 return lengthCompareJsonbStringValue(aScalar, bScalar, NULL);
1180 return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
1181 PointerGetDatum(aScalar->val.numeric),
1182 PointerGetDatum(bScalar->val.numeric)));
1184 if (aScalar->val.boolean != bScalar->val.boolean)
1185 return (aScalar->val.boolean > bScalar->val.boolean) ? 1 : -1;
1189 elog(ERROR, "invalid jsonb scalar type");
1192 elog(ERROR, "jsonb scalar type mismatch");
1197 * Standard lexical qsort() comparator of jsonb strings.
1199 * Sorts strings lexically, using the default database collation. Used by
1200 * B-Tree operators, where a lexical sort order is generally expected.
1203 lexicalCompareJsonbStringValue(const void *a, const void *b)
1205 const JsonbValue *va = (const JsonbValue *) a;
1206 const JsonbValue *vb = (const JsonbValue *) b;
1208 Assert(va->type == jbvString);
1209 Assert(vb->type == jbvString);
1211 return varstr_cmp(va->val.string.val, va->val.string.len, vb->val.string.val,
1212 vb->val.string.len, DEFAULT_COLLATION_OID);
1216 * Given a JsonbValue, convert to Jsonb and store in preallocated Jsonb buffer
1217 * sufficiently large to fit the value
1220 convertJsonb(JsonbValue *val, Jsonb *buffer)
1225 /* Should not already have binary representation */
1226 Assert(val->type != jbvBinary);
1228 state.buffer = buffer;
1229 /* Start from superheader */
1230 state.ptr = VARDATA(state.buffer);
1232 state.allState = palloc(sizeof(convertLevel) * state.levelSz);
1234 walkJsonbValueConversion(val, &state, 0);
1236 len = state.ptr - VARDATA(state.buffer);
1238 Assert(len <= val->estSize);
1243 * Walk the tree representation of Jsonb, as part of the process of converting
1244 * a JsonbValue to a Jsonb.
1246 * This high-level function takes care of recursion into sub-containers, but at
1247 * the top level calls putJsonbValueConversion once per sequential processing
1248 * token (in a manner similar to generic iteration).
1251 walkJsonbValueConversion(JsonbValue *val, convertState *cstate,
1256 check_stack_depth();
1265 putJsonbValueConversion(cstate, val, WJB_BEGIN_ARRAY, nestlevel);
1266 for (i = 0; i < val->val.array.nElems; i++)
1268 if (IsAJsonbScalar(&val->val.array.elems[i]) ||
1269 val->val.array.elems[i].type == jbvBinary)
1270 putJsonbValueConversion(cstate, val->val.array.elems + i,
1271 WJB_ELEM, nestlevel);
1273 walkJsonbValueConversion(val->val.array.elems + i, cstate,
1276 putJsonbValueConversion(cstate, val, WJB_END_ARRAY, nestlevel);
1281 putJsonbValueConversion(cstate, val, WJB_BEGIN_OBJECT, nestlevel);
1282 for (i = 0; i < val->val.object.nPairs; i++)
1284 putJsonbValueConversion(cstate, &val->val.object.pairs[i].key,
1285 WJB_KEY, nestlevel);
1287 if (IsAJsonbScalar(&val->val.object.pairs[i].value) ||
1288 val->val.object.pairs[i].value.type == jbvBinary)
1289 putJsonbValueConversion(cstate,
1290 &val->val.object.pairs[i].value,
1291 WJB_VALUE, nestlevel);
1293 walkJsonbValueConversion(&val->val.object.pairs[i].value,
1294 cstate, nestlevel + 1);
1296 putJsonbValueConversion(cstate, val, WJB_END_OBJECT, nestlevel);
1300 elog(ERROR, "unknown type of jsonb container");
1305 * walkJsonbValueConversion() worker. Add padding sufficient to int-align our
1306 * access to conversion buffer.
1310 addPaddingInt(convertState *cstate)
1315 padlen = INTALIGN(cstate->ptr - VARDATA(cstate->buffer)) -
1316 (cstate->ptr - VARDATA(cstate->buffer));
1318 for (p = padlen; p > 0; p--)
1320 *cstate->ptr = '\0';
1328 * walkJsonbValueConversion() worker.
1330 * As part of the process of converting an arbitrary JsonbValue to a Jsonb,
1331 * copy over an arbitrary individual JsonbValue. This function may copy any
1332 * type of value, even containers (Objects/arrays). However, it is not
1333 * responsible for recursive aspects of walking the tree (so only top-level
1334 * Object/array details are handled).
1336 * No details about their keys/values/elements are handled recursively -
1337 * rather, the function is called as required for the start of an Object/Array,
1338 * and the end (i.e. there is one call per sequential processing WJB_* token).
1341 putJsonbValueConversion(convertState *cstate, JsonbValue *val, uint32 flags,
1344 if (level == cstate->levelSz)
1346 cstate->levelSz *= 2;
1347 cstate->allState = repalloc(cstate->allState,
1348 sizeof(convertLevel) * cstate->levelSz);
1351 cstate->contPtr = cstate->allState + level;
1353 if (flags & (WJB_BEGIN_ARRAY | WJB_BEGIN_OBJECT))
1355 Assert(((flags & WJB_BEGIN_ARRAY) && val->type == jbvArray) ||
1356 ((flags & WJB_BEGIN_OBJECT) && val->type == jbvObject));
1358 /* Initialize pointer into conversion buffer at this level */
1359 cstate->contPtr->begin = cstate->ptr;
1361 addPaddingInt(cstate);
1363 /* Initialize everything else at this level */
1364 cstate->contPtr->header = (uint32 *) cstate->ptr;
1365 /* Advance past header */
1366 cstate->ptr += sizeof(uint32);
1367 cstate->contPtr->meta = (JEntry *) cstate->ptr;
1368 cstate->contPtr->i = 0;
1370 if (val->type == jbvArray)
1372 *cstate->contPtr->header = val->val.array.nElems | JB_FARRAY;
1373 cstate->ptr += sizeof(JEntry) * val->val.array.nElems;
1375 if (val->val.array.rawScalar)
1377 Assert(val->val.array.nElems == 1);
1379 *cstate->contPtr->header |= JB_FSCALAR;
1384 *cstate->contPtr->header = val->val.object.nPairs | JB_FOBJECT;
1385 cstate->ptr += sizeof(JEntry) * val->val.object.nPairs * 2;
1388 else if (flags & WJB_ELEM)
1390 putScalarConversion(cstate, val, level, cstate->contPtr->i);
1391 cstate->contPtr->i++;
1393 else if (flags & WJB_KEY)
1395 Assert(val->type == jbvString);
1397 putScalarConversion(cstate, val, level, cstate->contPtr->i * 2);
1399 else if (flags & WJB_VALUE)
1401 putScalarConversion(cstate, val, level, cstate->contPtr->i * 2 + 1);
1402 cstate->contPtr->i++;
1404 else if (flags & (WJB_END_ARRAY | WJB_END_OBJECT))
1406 convertLevel *prevPtr; /* Prev container pointer */
1410 Assert(((flags & WJB_END_ARRAY) && val->type == jbvArray) ||
1411 ((flags & WJB_END_OBJECT) && val->type == jbvObject));
1416 len = cstate->ptr - (char *) cstate->contPtr->begin;
1418 prevPtr = cstate->contPtr - 1;
1420 if (*prevPtr->header & JB_FARRAY)
1424 prevPtr->meta[i].header = JENTRY_ISNEST;
1427 prevPtr->meta[0].header |= JENTRY_ISFIRST | len;
1429 prevPtr->meta[i].header |=
1430 (prevPtr->meta[i - 1].header & JENTRY_POSMASK) + len;
1432 else if (*prevPtr->header & JB_FOBJECT)
1434 i = 2 * prevPtr->i + 1; /* Value, not key */
1436 prevPtr->meta[i].header = JENTRY_ISNEST;
1438 prevPtr->meta[i].header |=
1439 (prevPtr->meta[i - 1].header & JENTRY_POSMASK) + len;
1443 elog(ERROR, "invalid jsonb container type");
1446 Assert(cstate->ptr - cstate->contPtr->begin <= val->estSize);
1451 elog(ERROR, "unknown flag encountered during jsonb tree walk");
1456 * As part of the process of converting an arbitrary JsonbValue to a Jsonb,
1457 * serialize and copy a scalar value into buffer.
1459 * This is a worker function for putJsonbValueConversion() (itself a worker for
1460 * walkJsonbValueConversion()). It handles the details with regard to Jentry
1461 * metadata peculiar to each scalar type.
1464 putScalarConversion(convertState *cstate, JsonbValue *scalarVal, uint32 level,
1470 cstate->contPtr = cstate->allState + level;
1473 cstate->contPtr->meta[0].header = JENTRY_ISFIRST;
1475 cstate->contPtr->meta[i].header = 0;
1477 switch (scalarVal->type)
1480 cstate->contPtr->meta[i].header |= JENTRY_ISNULL;
1483 cstate->contPtr->meta[i].header |=
1484 cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK;
1487 memcpy(cstate->ptr, scalarVal->val.string.val, scalarVal->val.string.len);
1488 cstate->ptr += scalarVal->val.string.len;
1491 cstate->contPtr->meta[0].header |= scalarVal->val.string.len;
1493 cstate->contPtr->meta[i].header |=
1494 (cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK) +
1495 scalarVal->val.string.len;
1498 numlen = VARSIZE_ANY(scalarVal->val.numeric);
1499 padlen = addPaddingInt(cstate);
1501 memcpy(cstate->ptr, scalarVal->val.numeric, numlen);
1502 cstate->ptr += numlen;
1504 cstate->contPtr->meta[i].header |= JENTRY_ISNUMERIC;
1506 cstate->contPtr->meta[0].header |= padlen + numlen;
1508 cstate->contPtr->meta[i].header |=
1509 (cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK)
1513 cstate->contPtr->meta[i].header |= (scalarVal->val.boolean) ?
1514 JENTRY_ISTRUE : JENTRY_ISFALSE;
1517 cstate->contPtr->meta[i].header |=
1518 cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK;
1521 elog(ERROR, "invalid jsonb scalar type");
1526 * Given superheader pointer into buffer, initialize iterator. Must be a
1530 iteratorFromContainerBuf(JsonbIterator *it, JsonbSuperHeader sheader)
1532 uint32 superheader = *(uint32 *) sheader;
1534 it->containerType = superheader & (JB_FARRAY | JB_FOBJECT);
1535 it->nElems = superheader & JB_CMASK;
1536 it->buffer = sheader;
1538 /* Array starts just after header */
1539 it->meta = (JEntry *) (sheader + sizeof(uint32));
1540 it->state = jbi_start;
1542 switch (it->containerType)
1546 (char *) it->meta + it->nElems * sizeof(JEntry);
1547 it->isScalar = (superheader & JB_FSCALAR) != 0;
1548 /* This is either a "raw scalar", or an array */
1549 Assert(!it->isScalar || it->nElems == 1);
1554 * Offset reflects that nElems indicates JsonbPairs in an object.
1555 * Each key and each value contain Jentry metadata just the same.
1558 (char *) it->meta + it->nElems * sizeof(JEntry) * 2;
1561 elog(ERROR, "unknown type of jsonb container");
1566 * JsonbIteratorNext() worker
1568 * Returns bool indicating if v was a non-jbvBinary container, and thus if
1569 * further recursion is required by caller (according to its skipNested
1570 * preference). If it is required, we set the caller's iterator for further
1571 * recursion into the nested value. If we're going to skip nested items, just
1572 * set v to a jbvBinary value, but don't set caller's iterator.
1574 * Unlike with containers (either in this function or in any
1575 * JsonbIteratorNext() infrastructure), we fully convert from what is
1576 * ultimately a Jsonb on-disk representation, to a JsonbValue in-memory
1577 * representation (for scalar values only). JsonbIteratorNext() initializes
1578 * container Jsonbvalues, but without a sane private buffer. For scalar values
1579 * it has to be done for real (even if we don't actually allocate more memory
1580 * to do this. The point is that our JsonbValues scalars can be passed around
1584 formIterIsContainer(JsonbIterator **it, JsonbValue *val, JEntry *ent,
1587 if (JBE_ISNULL(*ent))
1589 val->type = jbvNull;
1590 val->estSize = sizeof(JEntry);
1594 else if (JBE_ISSTRING(*ent))
1596 val->type = jbvString;
1597 val->val.string.val = (*it)->dataProper + JBE_OFF(*ent);
1598 val->val.string.len = JBE_LEN(*ent);
1599 val->estSize = sizeof(JEntry) + val->val.string.len;
1603 else if (JBE_ISNUMERIC(*ent))
1605 val->type = jbvNumeric;
1606 val->val.numeric = (Numeric) ((*it)->dataProper + INTALIGN(JBE_OFF(*ent)));
1608 val->estSize = 2 * sizeof(JEntry) + VARSIZE_ANY(val->val.numeric);
1612 else if (JBE_ISBOOL(*ent))
1614 val->type = jbvBool;
1615 val->val.boolean = JBE_ISBOOL_TRUE(*ent) != 0;
1616 val->estSize = sizeof(JEntry);
1620 else if (skipNested)
1622 val->type = jbvBinary;
1623 val->val.binary.data = (*it)->dataProper + INTALIGN(JBE_OFF(*ent));
1624 val->val.binary.len = JBE_LEN(*ent) - (INTALIGN(JBE_OFF(*ent)) - JBE_OFF(*ent));
1625 val->estSize = val->val.binary.len + 2 * sizeof(JEntry);
1632 * Must be container type, so setup caller's iterator to point to
1633 * that, and return indication of that.
1635 * Get child iterator.
1637 JsonbIterator *child = palloc(sizeof(JsonbIterator));
1639 iteratorFromContainerBuf(child,
1640 (*it)->dataProper + INTALIGN(JBE_OFF(*ent)));
1642 child->parent = *it;
1650 * JsonbIteratorNext() worker: Return parent, while freeing memory for current
1653 static JsonbIterator *
1654 freeAndGetParent(JsonbIterator *it)
1656 JsonbIterator *v = it->parent;
1663 * pushJsonbValue() worker: Iteration-like forming of Jsonb
1665 static JsonbParseState *
1666 pushState(JsonbParseState **pstate)
1668 JsonbParseState *ns = palloc(sizeof(JsonbParseState));
1675 * pushJsonbValue() worker: Append a pair key to state when generating a Jsonb
1678 appendKey(JsonbParseState *pstate, JsonbValue *string)
1680 JsonbValue *object = &pstate->contVal;
1682 Assert(object->type == jbvObject);
1683 Assert(string->type == jbvString);
1685 if (object->val.object.nPairs >= JSONB_MAX_PAIRS)
1687 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1688 errmsg("number of jsonb object pairs exceeds the maximum allowed (%zu)",
1691 if (object->val.object.nPairs >= pstate->size)
1694 object->val.object.pairs = repalloc(object->val.object.pairs,
1695 sizeof(JsonbPair) * pstate->size);
1698 object->val.object.pairs[object->val.object.nPairs].key = *string;
1699 object->val.object.pairs[object->val.object.nPairs].order = object->val.object.nPairs;
1701 object->estSize += string->estSize;
1705 * pushJsonbValue() worker: Append a pair value to state when generating a
1709 appendValue(JsonbParseState *pstate, JsonbValue *scalarVal)
1711 JsonbValue *object = &pstate->contVal;
1713 Assert(object->type == jbvObject);
1715 object->val.object.pairs[object->val.object.nPairs++].value = *scalarVal;
1716 object->estSize += scalarVal->estSize;
1720 * pushJsonbValue() worker: Append an element to state when generating a Jsonb
1723 appendElement(JsonbParseState *pstate, JsonbValue *scalarVal)
1725 JsonbValue *array = &pstate->contVal;
1727 Assert(array->type == jbvArray);
1729 if (array->val.array.nElems >= JSONB_MAX_ELEMS)
1731 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1732 errmsg("number of jsonb array elements exceeds the maximum allowed (%zu)",
1735 if (array->val.array.nElems >= pstate->size)
1738 array->val.array.elems = repalloc(array->val.array.elems,
1739 sizeof(JsonbValue) * pstate->size);
1742 array->val.array.elems[array->val.array.nElems++] = *scalarVal;
1743 array->estSize += scalarVal->estSize;
1747 * Compare two jbvString JsonbValue values, a and b.
1749 * This is a special qsort_arg() comparator used to sort strings in certain
1750 * internal contexts where it is sufficient to have a well-defined sort order.
1751 * In particular, object pair keys are sorted according to this criteria to
1752 * facilitate cheap binary searches where we don't care about lexical sort
1755 * a and b are first sorted based on their length. If a tie-breaker is
1756 * required, only then do we consider string binary equality.
1758 * Third argument 'binequal' may point to a bool. If it's set, *binequal is set
1759 * to true iff a and b have full binary equality, since some callers have an
1760 * interest in whether the two values are equal or merely equivalent.
1763 lengthCompareJsonbStringValue(const void *a, const void *b, void *binequal)
1765 const JsonbValue *va = (const JsonbValue *) a;
1766 const JsonbValue *vb = (const JsonbValue *) b;
1769 Assert(va->type == jbvString);
1770 Assert(vb->type == jbvString);
1772 if (va->val.string.len == vb->val.string.len)
1774 res = memcmp(va->val.string.val, vb->val.string.val, va->val.string.len);
1775 if (res == 0 && binequal)
1776 *((bool *) binequal) = true;
1780 res = (va->val.string.len > vb->val.string.len) ? 1 : -1;
1787 * qsort_arg() comparator to compare JsonbPair values.
1789 * Function implemented in terms of lengthCompareJsonbStringValue(), and thus the
1790 * same "arg setting" hack will be applied here in respect of the pair's key
1793 * N.B: String comparisons here are "length-wise"
1795 * Pairs with equals keys are ordered such that the order field is respected.
1798 lengthCompareJsonbPair(const void *a, const void *b, void *binequal)
1800 const JsonbPair *pa = (const JsonbPair *) a;
1801 const JsonbPair *pb = (const JsonbPair *) b;
1804 res = lengthCompareJsonbStringValue(&pa->key, &pb->key, binequal);
1807 * Guarantee keeping order of equal pair. Unique algorithm will prefer
1808 * first element as value.
1811 res = (pa->order > pb->order) ? -1 : 1;
1817 * Sort and unique-ify pairs in JsonbValue object
1820 uniqueifyJsonbObject(JsonbValue *object)
1822 bool hasNonUniq = false;
1824 Assert(object->type == jbvObject);
1826 if (object->val.object.nPairs > 1)
1827 qsort_arg(object->val.object.pairs, object->val.object.nPairs, sizeof(JsonbPair),
1828 lengthCompareJsonbPair, &hasNonUniq);
1832 JsonbPair *ptr = object->val.object.pairs + 1,
1833 *res = object->val.object.pairs;
1835 while (ptr - object->val.object.pairs < object->val.object.nPairs)
1837 /* Avoid copying over duplicate */
1838 if (lengthCompareJsonbStringValue(ptr, res, NULL) == 0)
1840 object->estSize -= ptr->key.estSize + ptr->value.estSize;
1846 memcpy(res, ptr, sizeof(JsonbPair));
1851 object->val.object.nPairs = res + 1 - object->val.object.pairs;
1856 * Sort and unique-ify JsonbArray.
1858 * Sorting uses internal ordering.
1861 uniqueifyJsonbArray(JsonbValue *array)
1863 bool hasNonUniq = false;
1865 Assert(array->type == jbvArray);
1868 * Actually sort values, determining if any were equal on the basis of
1869 * full binary equality (rather than just having the same string length).
1871 if (array->val.array.nElems > 1)
1872 qsort_arg(array->val.array.elems, array->val.array.nElems,
1873 sizeof(JsonbValue), lengthCompareJsonbStringValue,
1878 JsonbValue *ptr = array->val.array.elems + 1,
1879 *res = array->val.array.elems;
1881 while (ptr - array->val.array.elems < array->val.array.nElems)
1883 /* Avoid copying over duplicate */
1884 if (lengthCompareJsonbStringValue(ptr, res, NULL) != 0)
1893 array->val.array.nElems = res + 1 - array->val.array.elems;