TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * jsonb_util.c
4 : * converting between Jsonb and JsonbValues, and iterating.
5 : *
6 : * Copyright (c) 2014-2023, PostgreSQL Global Development Group
7 : *
8 : *
9 : * IDENTIFICATION
10 : * src/backend/utils/adt/jsonb_util.c
11 : *
12 : *-------------------------------------------------------------------------
13 : */
14 : #include "postgres.h"
15 :
16 : #include "catalog/pg_collation.h"
17 : #include "catalog/pg_type.h"
18 : #include "common/hashfn.h"
19 : #include "common/jsonapi.h"
20 : #include "miscadmin.h"
21 : #include "port/pg_bitutils.h"
22 : #include "utils/builtins.h"
23 : #include "utils/datetime.h"
24 : #include "utils/json.h"
25 : #include "utils/jsonb.h"
26 : #include "utils/memutils.h"
27 : #include "utils/varlena.h"
28 :
29 : /*
30 : * Maximum number of elements in an array (or key/value pairs in an object).
31 : * This is limited by two things: the size of the JEntry array must fit
32 : * in MaxAllocSize, and the number of elements (or pairs) must fit in the bits
33 : * reserved for that in the JsonbContainer.header field.
34 : *
35 : * (The total size of an array's or object's elements is also limited by
36 : * JENTRY_OFFLENMASK, but we're not concerned about that here.)
37 : */
38 : #define JSONB_MAX_ELEMS (Min(MaxAllocSize / sizeof(JsonbValue), JB_CMASK))
39 : #define JSONB_MAX_PAIRS (Min(MaxAllocSize / sizeof(JsonbPair), JB_CMASK))
40 :
41 : static void fillJsonbValue(JsonbContainer *container, int index,
42 : char *base_addr, uint32 offset,
43 : JsonbValue *result);
44 : static bool equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b);
45 : static int compareJsonbScalarValue(JsonbValue *a, JsonbValue *b);
46 : static Jsonb *convertToJsonb(JsonbValue *val);
47 : static void convertJsonbValue(StringInfo buffer, JEntry *header, JsonbValue *val, int level);
48 : static void convertJsonbArray(StringInfo buffer, JEntry *header, JsonbValue *val, int level);
49 : static void convertJsonbObject(StringInfo buffer, JEntry *header, JsonbValue *val, int level);
50 : static void convertJsonbScalar(StringInfo buffer, JEntry *header, JsonbValue *scalarVal);
51 :
52 : static int reserveFromBuffer(StringInfo buffer, int len);
53 : static void appendToBuffer(StringInfo buffer, const char *data, int len);
54 : static void copyToBuffer(StringInfo buffer, int offset, const char *data, int len);
55 : static short padBufferToInt(StringInfo buffer);
56 :
57 : static JsonbIterator *iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent);
58 : static JsonbIterator *freeAndGetParent(JsonbIterator *it);
59 : static JsonbParseState *pushState(JsonbParseState **pstate);
60 : static void appendKey(JsonbParseState *pstate, JsonbValue *string);
61 : static void appendValue(JsonbParseState *pstate, JsonbValue *scalarVal);
62 : static void appendElement(JsonbParseState *pstate, JsonbValue *scalarVal);
63 : static int lengthCompareJsonbStringValue(const void *a, const void *b);
64 : static int lengthCompareJsonbString(const char *val1, int len1,
65 : const char *val2, int len2);
66 : static int lengthCompareJsonbPair(const void *a, const void *b, void *binequal);
67 : static void uniqueifyJsonbObject(JsonbValue *object, bool unique_keys,
68 : bool skip_nulls);
69 : static JsonbValue *pushJsonbValueScalar(JsonbParseState **pstate,
70 : JsonbIteratorToken seq,
71 : JsonbValue *scalarVal);
72 :
73 : void
74 GIC 327 : JsonbToJsonbValue(Jsonb *jsonb, JsonbValue *val)
75 ECB : {
76 GIC 327 : val->type = jbvBinary;
77 CBC 327 : val->val.binary.data = &jsonb->root;
78 327 : val->val.binary.len = VARSIZE(jsonb) - VARHDRSZ;
79 327 : }
80 ECB :
81 : /*
82 : * Turn an in-memory JsonbValue into a Jsonb for on-disk storage.
83 : *
84 : * Generally we find it more convenient to directly iterate through the Jsonb
85 : * representation and only really convert nested scalar values.
86 : * JsonbIteratorNext() does this, so that clients of the iteration code don't
87 : * have to directly deal with the binary representation (JsonbDeepContains() is
88 : * a notable exception, although all exceptions are internal to this module).
89 : * In general, functions that accept a JsonbValue argument are concerned with
90 : * the manipulation of scalar values, or simple containers of scalar values,
91 : * where it would be inconvenient to deal with a great amount of other state.
92 : */
93 : Jsonb *
94 GIC 45049 : JsonbValueToJsonb(JsonbValue *val)
95 ECB : {
96 : Jsonb *out;
97 :
98 GIC 45049 : if (IsAJsonbScalar(val))
99 CBC 32395 : {
100 ECB : /* Scalar value */
101 GIC 32395 : JsonbParseState *pstate = NULL;
102 ECB : JsonbValue *res;
103 : JsonbValue scalarArray;
104 :
105 GIC 32395 : scalarArray.type = jbvArray;
106 CBC 32395 : scalarArray.val.array.rawScalar = true;
107 32395 : scalarArray.val.array.nElems = 1;
108 ECB :
109 GIC 32395 : pushJsonbValue(&pstate, WJB_BEGIN_ARRAY, &scalarArray);
110 CBC 32395 : pushJsonbValue(&pstate, WJB_ELEM, val);
111 32395 : res = pushJsonbValue(&pstate, WJB_END_ARRAY, NULL);
112 ECB :
113 GIC 32395 : out = convertToJsonb(res);
114 ECB : }
115 GIC 12654 : else if (val->type == jbvObject || val->type == jbvArray)
116 ECB : {
117 GIC 12111 : out = convertToJsonb(val);
118 ECB : }
119 : else
120 : {
121 GIC 543 : Assert(val->type == jbvBinary);
122 CBC 543 : out = palloc(VARHDRSZ + val->val.binary.len);
123 543 : SET_VARSIZE(out, VARHDRSZ + val->val.binary.len);
124 543 : memcpy(VARDATA(out), val->val.binary.data, val->val.binary.len);
125 ECB : }
126 :
127 GIC 45049 : return out;
128 ECB : }
129 :
130 : /*
131 : * Get the offset of the variable-length portion of a Jsonb node within
132 : * the variable-length-data part of its container. The node is identified
133 : * by index within the container's JEntry array.
134 : */
135 : uint32
136 GIC 937059 : getJsonbOffset(const JsonbContainer *jc, int index)
137 ECB : {
138 GIC 937059 : uint32 offset = 0;
139 ECB : int i;
140 :
141 : /*
142 : * Start offset of this entry is equal to the end offset of the previous
143 : * entry. Walk backwards to the most recent entry stored as an end
144 : * offset, returning that offset plus any lengths in between.
145 : */
146 GIC 2802446 : for (i = index - 1; i >= 0; i--)
147 ECB : {
148 GIC 2454462 : offset += JBE_OFFLENFLD(jc->children[i]);
149 CBC 2454462 : if (JBE_HAS_OFF(jc->children[i]))
150 589075 : break;
151 ECB : }
152 :
153 GIC 937059 : return offset;
154 ECB : }
155 :
156 : /*
157 : * Get the length of the variable-length portion of a Jsonb node.
158 : * The node is identified by index within the container's JEntry array.
159 : */
160 : uint32
161 GIC 826066 : getJsonbLength(const JsonbContainer *jc, int index)
162 ECB : {
163 : uint32 off;
164 : uint32 len;
165 :
166 : /*
167 : * If the length is stored directly in the JEntry, just return it.
168 : * Otherwise, get the begin offset of the entry, and subtract that from
169 : * the stored end+1 offset.
170 : */
171 GIC 826066 : if (JBE_HAS_OFF(jc->children[index]))
172 ECB : {
173 GIC 269651 : off = getJsonbOffset(jc, index);
174 CBC 269651 : len = JBE_OFFLENFLD(jc->children[index]) - off;
175 ECB : }
176 : else
177 GIC 556415 : len = JBE_OFFLENFLD(jc->children[index]);
178 ECB :
179 GIC 826066 : return len;
180 ECB : }
181 :
182 : /*
183 : * BT comparator worker function. Returns an integer less than, equal to, or
184 : * greater than zero, indicating whether a is less than, equal to, or greater
185 : * than b. Consistent with the requirements for a B-Tree operator class
186 : *
187 : * Strings are compared lexically, in contrast with other places where we use a
188 : * much simpler comparator logic for searching through Strings. Since this is
189 : * called from B-Tree support function 1, we're careful about not leaking
190 : * memory here.
191 : */
192 : int
193 GIC 136572 : compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
194 ECB : {
195 : JsonbIterator *ita,
196 : *itb;
197 GIC 136572 : int res = 0;
198 ECB :
199 GIC 136572 : ita = JsonbIteratorInit(a);
200 CBC 136572 : itb = JsonbIteratorInit(b);
201 ECB :
202 : do
203 : {
204 : JsonbValue va,
205 : vb;
206 : JsonbIteratorToken ra,
207 : rb;
208 :
209 GIC 399233 : ra = JsonbIteratorNext(&ita, &va, false);
210 CBC 399233 : rb = JsonbIteratorNext(&itb, &vb, false);
211 ECB :
212 GIC 399233 : if (ra == rb)
213 ECB : {
214 GIC 399233 : if (ra == WJB_DONE)
215 ECB : {
216 : /* Decisively equal */
217 GIC 13835 : break;
218 ECB : }
219 :
220 GIC 385398 : if (ra == WJB_END_ARRAY || ra == WJB_END_OBJECT)
221 ECB : {
222 : /*
223 : * There is no array or object to compare at this stage of
224 : * processing. jbvArray/jbvObject values are compared
225 : * initially, at the WJB_BEGIN_ARRAY and WJB_BEGIN_OBJECT
226 : * tokens.
227 : */
228 GIC 13911 : continue;
229 ECB : }
230 :
231 GIC 371487 : if (va.type == vb.type)
232 ECB : {
233 GIC 371487 : switch (va.type)
234 ECB : {
235 GIC 234682 : case jbvString:
236 ECB : case jbvNull:
237 : case jbvNumeric:
238 : case jbvBool:
239 GIC 234682 : res = compareJsonbScalarValue(&va, &vb);
240 CBC 234682 : break;
241 192 : case jbvArray:
242 ECB :
243 : /*
244 : * This could be a "raw scalar" pseudo array. That's
245 : * a special case here though, since we still want the
246 : * general type-based comparisons to apply, and as far
247 : * as we're concerned a pseudo array is just a scalar.
248 : */
249 GIC 192 : if (va.val.array.rawScalar != vb.val.array.rawScalar)
250 LBC 0 : res = (va.val.array.rawScalar) ? -1 : 1;
251 GBC 192 : if (va.val.array.nElems != vb.val.array.nElems)
252 CBC 91 : res = (va.val.array.nElems > vb.val.array.nElems) ? 1 : -1;
253 192 : break;
254 136613 : case jbvObject:
255 136613 : if (va.val.object.nPairs != vb.val.object.nPairs)
256 43851 : res = (va.val.object.nPairs > vb.val.object.nPairs) ? 1 : -1;
257 136613 : break;
258 LBC 0 : case jbvBinary:
259 UBC 0 : elog(ERROR, "unexpected jbvBinary value");
260 EUB : break;
261 UIC 0 : case jbvDatetime:
262 UBC 0 : elog(ERROR, "unexpected jbvDatetime value");
263 EUB : break;
264 : }
265 : }
266 : else
267 : {
268 : /* Type-defined order */
269 UIC 0 : res = (va.type > vb.type) ? 1 : -1;
270 EUB : }
271 : }
272 : else
273 : {
274 : /*
275 : * It's safe to assume that the types differed, and that the va
276 : * and vb values passed were set.
277 : *
278 : * If the two values were of the same container type, then there'd
279 : * have been a chance to observe the variation in the number of
280 : * elements/pairs (when processing WJB_BEGIN_OBJECT, say). They're
281 : * either two heterogeneously-typed containers, or a container and
282 : * some scalar type.
283 : *
284 : * We don't have to consider the WJB_END_ARRAY and WJB_END_OBJECT
285 : * cases here, because we would have seen the corresponding
286 : * WJB_BEGIN_ARRAY and WJB_BEGIN_OBJECT tokens first, and
287 : * concluded that they don't match.
288 : */
289 UIC 0 : Assert(ra != WJB_END_ARRAY && ra != WJB_END_OBJECT);
290 UBC 0 : Assert(rb != WJB_END_ARRAY && rb != WJB_END_OBJECT);
291 EUB :
292 UIC 0 : Assert(va.type != vb.type);
293 UBC 0 : Assert(va.type != jbvBinary);
294 0 : Assert(vb.type != jbvBinary);
295 EUB : /* Type-defined order */
296 UIC 0 : res = (va.type > vb.type) ? 1 : -1;
297 EUB : }
298 : }
299 GIC 385398 : while (res == 0);
300 ECB :
301 GIC 259466 : while (ita != NULL)
302 ECB : {
303 GIC 122894 : JsonbIterator *i = ita->parent;
304 ECB :
305 GIC 122894 : pfree(ita);
306 CBC 122894 : ita = i;
307 ECB : }
308 GIC 259466 : while (itb != NULL)
309 ECB : {
310 GIC 122894 : JsonbIterator *i = itb->parent;
311 ECB :
312 GIC 122894 : pfree(itb);
313 CBC 122894 : itb = i;
314 ECB : }
315 :
316 GIC 136572 : return res;
317 ECB : }
318 :
319 : /*
320 : * Find value in object (i.e. the "value" part of some key/value pair in an
321 : * object), or find a matching element if we're looking through an array. Do
322 : * so on the basis of equality of the object keys only, or alternatively
323 : * element values only, with a caller-supplied value "key". The "flags"
324 : * argument allows the caller to specify which container types are of interest.
325 : *
326 : * This exported utility function exists to facilitate various cases concerned
327 : * with "containment". If asked to look through an object, the caller had
328 : * better pass a Jsonb String, because their keys can only be strings.
329 : * Otherwise, for an array, any type of JsonbValue will do.
330 : *
331 : * In order to proceed with the search, it is necessary for callers to have
332 : * both specified an interest in exactly one particular container type with an
333 : * appropriate flag, as well as having the pointed-to Jsonb container be of
334 : * one of those same container types at the top level. (Actually, we just do
335 : * whichever makes sense to save callers the trouble of figuring it out - at
336 : * most one can make sense, because the container either points to an array
337 : * (possibly a "raw scalar" pseudo array) or an object.)
338 : *
339 : * Note that we can return a jbvBinary JsonbValue if this is called on an
340 : * object, but we never do so on an array. If the caller asks to look through
341 : * a container type that is not of the type pointed to by the container,
342 : * immediately fall through and return NULL. If we cannot find the value,
343 : * return NULL. Otherwise, return palloc()'d copy of value.
344 : */
345 : JsonbValue *
346 GIC 103060 : findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
347 ECB : JsonbValue *key)
348 : {
349 GIC 103060 : JEntry *children = container->children;
350 CBC 103060 : int count = JsonContainerSize(container);
351 ECB :
352 GIC 103060 : Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
353 ECB :
354 : /* Quick out without a palloc cycle if object/array is empty */
355 GIC 103060 : if (count <= 0)
356 CBC 11016 : return NULL;
357 ECB :
358 GIC 92044 : if ((flags & JB_FARRAY) && JsonContainerIsArray(container))
359 CBC 48 : {
360 240 : JsonbValue *result = palloc(sizeof(JsonbValue));
361 240 : char *base_addr = (char *) (children + count);
362 240 : uint32 offset = 0;
363 ECB : int i;
364 :
365 GIC 447 : for (i = 0; i < count; i++)
366 ECB : {
367 GIC 399 : fillJsonbValue(container, i, base_addr, offset, result);
368 ECB :
369 GIC 399 : if (key->type == result->type)
370 ECB : {
371 GIC 354 : if (equalsJsonbScalarValue(key, result))
372 CBC 192 : return result;
373 ECB : }
374 :
375 GIC 207 : JBE_ADVANCE_OFFSET(offset, children[i]);
376 ECB : }
377 :
378 GIC 48 : pfree(result);
379 ECB : }
380 GIC 91804 : else if ((flags & JB_FOBJECT) && JsonContainerIsObject(container))
381 ECB : {
382 : /* Object key passed by caller must be a string */
383 GIC 91804 : Assert(key->type == jbvString);
384 ECB :
385 GIC 91804 : return getKeyJsonValueFromContainer(container, key->val.string.val,
386 ECB : key->val.string.len, NULL);
387 : }
388 :
389 : /* Not found */
390 GIC 48 : return NULL;
391 ECB : }
392 :
393 : /*
394 : * Find value by key in Jsonb object and fetch it into 'res', which is also
395 : * returned.
396 : *
397 : * 'res' can be passed in as NULL, in which case it's newly palloc'ed here.
398 : */
399 : JsonbValue *
400 GIC 125875 : getKeyJsonValueFromContainer(JsonbContainer *container,
401 ECB : const char *keyVal, int keyLen, JsonbValue *res)
402 : {
403 GIC 125875 : JEntry *children = container->children;
404 CBC 125875 : int count = JsonContainerSize(container);
405 ECB : char *baseAddr;
406 : uint32 stopLow,
407 : stopHigh;
408 :
409 GIC 125875 : Assert(JsonContainerIsObject(container));
410 ECB :
411 : /* Quick out without a palloc cycle if object is empty */
412 GIC 125875 : if (count <= 0)
413 CBC 1416 : return NULL;
414 ECB :
415 : /*
416 : * Binary search the container. Since we know this is an object, account
417 : * for *Pairs* of Jentrys
418 : */
419 GIC 124459 : baseAddr = (char *) (children + count * 2);
420 CBC 124459 : stopLow = 0;
421 124459 : stopHigh = count;
422 401164 : while (stopLow < stopHigh)
423 ECB : {
424 : uint32 stopMiddle;
425 : int difference;
426 : const char *candidateVal;
427 : int candidateLen;
428 :
429 GIC 301105 : stopMiddle = stopLow + (stopHigh - stopLow) / 2;
430 ECB :
431 GIC 301105 : candidateVal = baseAddr + getJsonbOffset(container, stopMiddle);
432 CBC 301105 : candidateLen = getJsonbLength(container, stopMiddle);
433 ECB :
434 GIC 301105 : difference = lengthCompareJsonbString(candidateVal, candidateLen,
435 ECB : keyVal, keyLen);
436 :
437 GIC 301105 : if (difference == 0)
438 ECB : {
439 : /* Found our key, return corresponding value */
440 GIC 24400 : int index = stopMiddle + count;
441 ECB :
442 GIC 24400 : if (!res)
443 CBC 21973 : res = palloc(sizeof(JsonbValue));
444 ECB :
445 GIC 24400 : fillJsonbValue(container, index, baseAddr,
446 ECB : getJsonbOffset(container, index),
447 : res);
448 :
449 GIC 24400 : return res;
450 ECB : }
451 : else
452 : {
453 GIC 276705 : if (difference < 0)
454 CBC 102564 : stopLow = stopMiddle + 1;
455 ECB : else
456 GIC 174141 : stopHigh = stopMiddle;
457 ECB : }
458 : }
459 :
460 : /* Not found */
461 GIC 100059 : return NULL;
462 ECB : }
463 :
464 : /*
465 : * Get i-th value of a Jsonb array.
466 : *
467 : * Returns palloc()'d copy of the value, or NULL if it does not exist.
468 : */
469 : JsonbValue *
470 GIC 402 : getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)
471 ECB : {
472 : JsonbValue *result;
473 : char *base_addr;
474 : uint32 nelements;
475 :
476 GIC 402 : if (!JsonContainerIsArray(container))
477 LBC 0 : elog(ERROR, "not a jsonb array");
478 EUB :
479 GIC 402 : nelements = JsonContainerSize(container);
480 CBC 402 : base_addr = (char *) &container->children[nelements];
481 ECB :
482 GIC 402 : if (i >= nelements)
483 CBC 30 : return NULL;
484 ECB :
485 GIC 372 : result = palloc(sizeof(JsonbValue));
486 ECB :
487 GIC 372 : fillJsonbValue(container, i, base_addr,
488 ECB : getJsonbOffset(container, i),
489 : result);
490 :
491 GIC 372 : return result;
492 ECB : }
493 :
494 : /*
495 : * A helper function to fill in a JsonbValue to represent an element of an
496 : * array, or a key or value of an object.
497 : *
498 : * The node's JEntry is at container->children[index], and its variable-length
499 : * data is at base_addr + offset. We make the caller determine the offset
500 : * since in many cases the caller can amortize that work across multiple
501 : * children. When it can't, it can just call getJsonbOffset().
502 : *
503 : * A nested array or object will be returned as jbvBinary, ie. it won't be
504 : * expanded.
505 : */
506 : static void
507 GIC 756774 : fillJsonbValue(JsonbContainer *container, int index,
508 ECB : char *base_addr, uint32 offset,
509 : JsonbValue *result)
510 : {
511 GIC 756774 : JEntry entry = container->children[index];
512 ECB :
513 GIC 756774 : if (JBE_ISNULL(entry))
514 ECB : {
515 GIC 2146 : result->type = jbvNull;
516 ECB : }
517 GIC 754628 : else if (JBE_ISSTRING(entry))
518 ECB : {
519 GIC 518086 : result->type = jbvString;
520 CBC 518086 : result->val.string.val = base_addr + offset;
521 518086 : result->val.string.len = getJsonbLength(container, index);
522 518086 : Assert(result->val.string.len >= 0);
523 ECB : }
524 GIC 236542 : else if (JBE_ISNUMERIC(entry))
525 ECB : {
526 GIC 156689 : result->type = jbvNumeric;
527 CBC 156689 : result->val.numeric = (Numeric) (base_addr + INTALIGN(offset));
528 ECB : }
529 GIC 79853 : else if (JBE_ISBOOL_TRUE(entry))
530 ECB : {
531 GIC 35199 : result->type = jbvBool;
532 CBC 35199 : result->val.boolean = true;
533 ECB : }
534 GIC 44654 : else if (JBE_ISBOOL_FALSE(entry))
535 ECB : {
536 GIC 37779 : result->type = jbvBool;
537 CBC 37779 : result->val.boolean = false;
538 ECB : }
539 : else
540 : {
541 GIC 6875 : Assert(JBE_ISCONTAINER(entry));
542 CBC 6875 : result->type = jbvBinary;
543 ECB : /* Remove alignment padding from data pointer and length */
544 GIC 6875 : result->val.binary.data = (JsonbContainer *) (base_addr + INTALIGN(offset));
545 CBC 6875 : result->val.binary.len = getJsonbLength(container, index) -
546 6875 : (INTALIGN(offset) - offset);
547 ECB : }
548 GIC 756774 : }
549 ECB :
550 : /*
551 : * Push JsonbValue into JsonbParseState.
552 : *
553 : * Used when parsing JSON tokens to form Jsonb, or when converting an in-memory
554 : * JsonbValue to a Jsonb.
555 : *
556 : * Initial state of *JsonbParseState is NULL, since it'll be allocated here
557 : * originally (caller will get JsonbParseState back by reference).
558 : *
559 : * Only sequential tokens pertaining to non-container types should pass a
560 : * JsonbValue. There is one exception -- WJB_BEGIN_ARRAY callers may pass a
561 : * "raw scalar" pseudo array to append it - the actual scalar should be passed
562 : * next and it will be added as the only member of the array.
563 : *
564 : * Values of type jbvBinary, which are rolled up arrays and objects,
565 : * are unpacked before being added to the result.
566 : */
567 : JsonbValue *
568 GIC 199842 : pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq,
569 ECB : JsonbValue *jbval)
570 : {
571 : JsonbIterator *it;
572 GIC 199842 : JsonbValue *res = NULL;
573 ECB : JsonbValue v;
574 : JsonbIteratorToken tok;
575 : int i;
576 :
577 GIC 199842 : if (jbval && (seq == WJB_ELEM || seq == WJB_VALUE) && jbval->type == jbvObject)
578 ECB : {
579 UIC 0 : pushJsonbValue(pstate, WJB_BEGIN_OBJECT, NULL);
580 UBC 0 : for (i = 0; i < jbval->val.object.nPairs; i++)
581 EUB : {
582 UIC 0 : pushJsonbValue(pstate, WJB_KEY, &jbval->val.object.pairs[i].key);
583 UBC 0 : pushJsonbValue(pstate, WJB_VALUE, &jbval->val.object.pairs[i].value);
584 EUB : }
585 :
586 UIC 0 : return pushJsonbValue(pstate, WJB_END_OBJECT, NULL);
587 EUB : }
588 :
589 GIC 199842 : if (jbval && (seq == WJB_ELEM || seq == WJB_VALUE) && jbval->type == jbvArray)
590 ECB : {
591 UIC 0 : pushJsonbValue(pstate, WJB_BEGIN_ARRAY, NULL);
592 UBC 0 : for (i = 0; i < jbval->val.array.nElems; i++)
593 EUB : {
594 UIC 0 : pushJsonbValue(pstate, WJB_ELEM, &jbval->val.array.elems[i]);
595 EUB : }
596 :
597 UIC 0 : return pushJsonbValue(pstate, WJB_END_ARRAY, NULL);
598 EUB : }
599 :
600 GIC 199842 : if (!jbval || (seq != WJB_ELEM && seq != WJB_VALUE) ||
601 CBC 66027 : jbval->type != jbvBinary)
602 ECB : {
603 : /* drop through */
604 GIC 199446 : return pushJsonbValueScalar(pstate, seq, jbval);
605 ECB : }
606 :
607 : /* unpack the binary and add each piece to the pstate */
608 GIC 396 : it = JsonbIteratorInit(jbval->val.binary.data);
609 ECB :
610 GIC 396 : if ((jbval->val.binary.data->header & JB_FSCALAR) && *pstate)
611 ECB : {
612 GIC 171 : tok = JsonbIteratorNext(&it, &v, true);
613 CBC 171 : Assert(tok == WJB_BEGIN_ARRAY);
614 171 : Assert(v.type == jbvArray && v.val.array.rawScalar);
615 ECB :
616 GIC 171 : tok = JsonbIteratorNext(&it, &v, true);
617 CBC 171 : Assert(tok == WJB_ELEM);
618 ECB :
619 GIC 171 : res = pushJsonbValueScalar(pstate, seq, &v);
620 ECB :
621 GIC 171 : tok = JsonbIteratorNext(&it, &v, true);
622 CBC 171 : Assert(tok == WJB_END_ARRAY);
623 171 : Assert(it == NULL);
624 ECB :
625 GIC 171 : return res;
626 ECB : }
627 :
628 GIC 1608 : while ((tok = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
629 CBC 2013 : res = pushJsonbValueScalar(pstate, tok,
630 630 : tok < WJB_BEGIN_ARRAY ||
631 162 : (tok == WJB_BEGIN_ARRAY &&
632 162 : v.val.array.rawScalar) ? &v : NULL);
633 ECB :
634 GIC 225 : return res;
635 ECB : }
636 :
637 : /*
638 : * Do the actual pushing, with only scalar or pseudo-scalar-array values
639 : * accepted.
640 : */
641 : static JsonbValue *
642 GIC 201000 : pushJsonbValueScalar(JsonbParseState **pstate, JsonbIteratorToken seq,
643 ECB : JsonbValue *scalarVal)
644 : {
645 GIC 201000 : JsonbValue *result = NULL;
646 ECB :
647 GIC 201000 : switch (seq)
648 ECB : {
649 GIC 40399 : case WJB_BEGIN_ARRAY:
650 CBC 40399 : Assert(!scalarVal || scalarVal->val.array.rawScalar);
651 40399 : *pstate = pushState(pstate);
652 40399 : result = &(*pstate)->contVal;
653 40399 : (*pstate)->contVal.type = jbvArray;
654 40399 : (*pstate)->contVal.val.array.nElems = 0;
655 74188 : (*pstate)->contVal.val.array.rawScalar = (scalarVal &&
656 33789 : scalarVal->val.array.rawScalar);
657 40399 : if (scalarVal && scalarVal->val.array.nElems > 0)
658 ECB : {
659 : /* Assume that this array is still really a scalar */
660 GIC 33789 : Assert(scalarVal->type == jbvArray);
661 CBC 33789 : (*pstate)->size = scalarVal->val.array.nElems;
662 ECB : }
663 : else
664 : {
665 GIC 6610 : (*pstate)->size = 4;
666 ECB : }
667 GIC 80798 : (*pstate)->contVal.val.array.elems = palloc(sizeof(JsonbValue) *
668 CBC 40399 : (*pstate)->size);
669 40399 : break;
670 14128 : case WJB_BEGIN_OBJECT:
671 14128 : Assert(!scalarVal);
672 14128 : *pstate = pushState(pstate);
673 14128 : result = &(*pstate)->contVal;
674 14128 : (*pstate)->contVal.type = jbvObject;
675 14128 : (*pstate)->contVal.val.object.nPairs = 0;
676 14128 : (*pstate)->size = 4;
677 28256 : (*pstate)->contVal.val.object.pairs = palloc(sizeof(JsonbPair) *
678 14128 : (*pstate)->size);
679 14128 : break;
680 30016 : case WJB_KEY:
681 30016 : Assert(scalarVal->type == jbvString);
682 30016 : appendKey(*pstate, scalarVal);
683 30016 : break;
684 24515 : case WJB_VALUE:
685 24515 : Assert(IsAJsonbScalar(scalarVal));
686 24515 : appendValue(*pstate, scalarVal);
687 24515 : break;
688 41749 : case WJB_ELEM:
689 41749 : Assert(IsAJsonbScalar(scalarVal));
690 41749 : appendElement(*pstate, scalarVal);
691 41749 : break;
692 12012 : case WJB_END_OBJECT:
693 GNC 12012 : uniqueifyJsonbObject(&(*pstate)->contVal,
694 12012 : (*pstate)->unique_keys,
695 12012 : (*pstate)->skip_nulls);
696 ECB : /* fall through! */
697 CBC 50178 : case WJB_END_ARRAY:
698 ECB : /* Steps here common to WJB_END_OBJECT case */
699 GIC 50178 : Assert(!scalarVal);
700 CBC 50178 : result = &(*pstate)->contVal;
701 :
702 ECB : /*
703 : * Pop stack and push current array/object as value in parent
704 : * array/object
705 : */
706 GIC 50178 : *pstate = (*pstate)->next;
707 50178 : if (*pstate)
708 : {
709 CBC 5672 : switch ((*pstate)->contVal.type)
710 ECB : {
711 GIC 2182 : case jbvArray:
712 CBC 2182 : appendElement(*pstate, result);
713 GIC 2182 : break;
714 CBC 3490 : case jbvObject:
715 3490 : appendValue(*pstate, result);
716 3490 : break;
717 LBC 0 : default:
718 0 : elog(ERROR, "invalid jsonb container type");
719 ECB : }
720 EUB : }
721 GBC 50178 : break;
722 UIC 0 : default:
723 0 : elog(ERROR, "unrecognized jsonb sequential processing token");
724 ECB : }
725 EUB :
726 GBC 200985 : return result;
727 : }
728 :
729 ECB : /*
730 : * pushJsonbValue() worker: Iteration-like forming of Jsonb
731 : */
732 : static JsonbParseState *
733 GIC 54527 : pushState(JsonbParseState **pstate)
734 : {
735 54527 : JsonbParseState *ns = palloc(sizeof(JsonbParseState));
736 ECB :
737 GIC 54527 : ns->next = *pstate;
738 GNC 54527 : ns->unique_keys = false;
739 54527 : ns->skip_nulls = false;
740 :
741 CBC 54527 : return ns;
742 : }
743 ECB :
744 : /*
745 : * pushJsonbValue() worker: Append a pair key to state when generating a Jsonb
746 : */
747 : static void
748 GIC 30016 : appendKey(JsonbParseState *pstate, JsonbValue *string)
749 : {
750 30016 : JsonbValue *object = &pstate->contVal;
751 :
752 30016 : Assert(object->type == jbvObject);
753 30016 : Assert(string->type == jbvString);
754 ECB :
755 GIC 30016 : if (object->val.object.nPairs >= JSONB_MAX_PAIRS)
756 LBC 0 : ereport(ERROR,
757 : (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
758 ECB : errmsg("number of jsonb object pairs exceeds the maximum allowed (%zu)",
759 : JSONB_MAX_PAIRS)));
760 :
761 CBC 30016 : if (object->val.object.nPairs >= pstate->size)
762 EUB : {
763 GIC 2838 : pstate->size *= 2;
764 2838 : object->val.object.pairs = repalloc(object->val.object.pairs,
765 2838 : sizeof(JsonbPair) * pstate->size);
766 : }
767 ECB :
768 GIC 30016 : object->val.object.pairs[object->val.object.nPairs].key = *string;
769 CBC 30016 : object->val.object.pairs[object->val.object.nPairs].order = object->val.object.nPairs;
770 30016 : }
771 ECB :
772 : /*
773 : * pushJsonbValue() worker: Append a pair value to state when generating a
774 : * Jsonb
775 : */
776 : static void
777 GIC 28005 : appendValue(JsonbParseState *pstate, JsonbValue *scalarVal)
778 : {
779 28005 : JsonbValue *object = &pstate->contVal;
780 :
781 28005 : Assert(object->type == jbvObject);
782 :
783 CBC 28005 : object->val.object.pairs[object->val.object.nPairs++].value = *scalarVal;
784 GIC 28005 : }
785 ECB :
786 : /*
787 : * pushJsonbValue() worker: Append an element to state when generating a Jsonb
788 : */
789 : static void
790 CBC 43931 : appendElement(JsonbParseState *pstate, JsonbValue *scalarVal)
791 : {
792 GIC 43931 : JsonbValue *array = &pstate->contVal;
793 :
794 43931 : Assert(array->type == jbvArray);
795 :
796 CBC 43931 : if (array->val.array.nElems >= JSONB_MAX_ELEMS)
797 UIC 0 : ereport(ERROR,
798 ECB : (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
799 : errmsg("number of jsonb array elements exceeds the maximum allowed (%zu)",
800 : JSONB_MAX_ELEMS)));
801 :
802 CBC 43931 : if (array->val.array.nElems >= pstate->size)
803 EUB : {
804 GIC 522 : pstate->size *= 2;
805 522 : array->val.array.elems = repalloc(array->val.array.elems,
806 522 : sizeof(JsonbValue) * pstate->size);
807 : }
808 ECB :
809 GIC 43931 : array->val.array.elems[array->val.array.nElems++] = *scalarVal;
810 CBC 43931 : }
811 ECB :
812 : /*
813 : * Given a JsonbContainer, expand to JsonbIterator to iterate over items
814 : * fully expanded to in-memory representation for manipulation.
815 : *
816 : * See JsonbIteratorNext() for notes on memory management.
817 : */
818 : JsonbIterator *
819 GIC 347807 : JsonbIteratorInit(JsonbContainer *container)
820 : {
821 347807 : return iteratorFromContainer(container, NULL);
822 : }
823 :
824 : /*
825 ECB : * Get next JsonbValue while iterating
826 : *
827 : * Caller should initially pass their own, original iterator. They may get
828 : * back a child iterator palloc()'d here instead. The function can be relied
829 : * on to free those child iterators, lest the memory allocated for highly
830 : * nested objects become unreasonable, but only if callers don't end iteration
831 : * early (by breaking upon having found something in a search, for example).
832 : *
833 : * Callers in such a scenario, that are particularly sensitive to leaking
834 : * memory in a long-lived context may walk the ancestral tree from the final
835 : * iterator we left them with to its oldest ancestor, pfree()ing as they go.
836 : * They do not have to free any other memory previously allocated for iterators
837 : * but not accessible as direct ancestors of the iterator they're last passed
838 : * back.
839 : *
840 : * Returns "Jsonb sequential processing" token value. Iterator "state"
841 : * reflects the current stage of the process in a less granular fashion, and is
842 : * mostly used here to track things internally with respect to particular
843 : * iterators.
844 : *
845 : * Clients of this function should not have to handle any jbvBinary values
846 : * (since recursive calls will deal with this), provided skipNested is false.
847 : * It is our job to expand the jbvBinary representation without bothering them
848 : * with it. However, clients should not take it upon themselves to touch array
849 : * or Object element/pair buffers, since their element/pair pointers are
850 : * garbage. Also, *val will not be set when returning WJB_END_ARRAY or
851 : * WJB_END_OBJECT, on the assumption that it's only useful to access values
852 : * when recursing in.
853 : */
854 : JsonbIteratorToken
855 GIC 1204914 : JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
856 : {
857 1204914 : if (*it == NULL)
858 57606 : return WJB_DONE;
859 :
860 : /*
861 ECB : * When stepping into a nested container, we jump back here to start
862 : * processing the child. We will not recurse further in one call, because
863 : * processing the child will always begin in JBI_ARRAY_START or
864 : * JBI_OBJECT_START state.
865 : */
866 GIC 1150825 : recurse:
867 1150825 : switch ((*it)->state)
868 : {
869 9793 : case JBI_ARRAY_START:
870 : /* Set v to array on first array call */
871 9793 : val->type = jbvArray;
872 CBC 9793 : val->val.array.nElems = (*it)->nElems;
873 ECB :
874 : /*
875 : * v->val.array.elems is not actually set, because we aren't doing
876 : * a full conversion
877 : */
878 CBC 9793 : val->val.array.rawScalar = (*it)->isScalar;
879 GIC 9793 : (*it)->curIndex = 0;
880 9793 : (*it)->curDataOffset = 0;
881 9793 : (*it)->curValueOffset = 0; /* not actually used */
882 : /* Set state for next call */
883 9793 : (*it)->state = JBI_ARRAY_ELEM;
884 CBC 9793 : return WJB_BEGIN_ARRAY;
885 ECB :
886 CBC 24391 : case JBI_ARRAY_ELEM:
887 24391 : if ((*it)->curIndex >= (*it)->nElems)
888 : {
889 ECB : /*
890 : * All elements within array already processed. Report this
891 : * to caller, and give it back original parent iterator (which
892 : * independently tracks iteration progress at its level of
893 : * nesting).
894 : */
895 GIC 8904 : *it = freeAndGetParent(*it);
896 8904 : return WJB_END_ARRAY;
897 : }
898 :
899 15487 : fillJsonbValue((*it)->container, (*it)->curIndex,
900 15487 : (*it)->dataProper, (*it)->curDataOffset,
901 ECB : val);
902 :
903 GIC 15487 : JBE_ADVANCE_OFFSET((*it)->curDataOffset,
904 : (*it)->children[(*it)->curIndex]);
905 CBC 15487 : (*it)->curIndex++;
906 ECB :
907 GIC 15487 : if (!IsAJsonbScalar(val) && !skipNested)
908 : {
909 ECB : /* Recurse into container. */
910 GIC 906 : *it = iteratorFromContainer(val->val.binary.data, *it);
911 CBC 906 : goto recurse;
912 : }
913 ECB : else
914 : {
915 : /*
916 : * Scalar item in array, or a container and caller didn't want
917 : * us to recurse into it.
918 : */
919 GIC 14581 : return WJB_ELEM;
920 : }
921 :
922 341531 : case JBI_OBJECT_START:
923 : /* Set v to object on first object call */
924 341531 : val->type = jbvObject;
925 CBC 341531 : val->val.object.nPairs = (*it)->nElems;
926 :
927 : /*
928 ECB : * v->val.object.pairs is not actually set, because we aren't
929 : * doing a full conversion
930 : */
931 CBC 341531 : (*it)->curIndex = 0;
932 GIC 341531 : (*it)->curDataOffset = 0;
933 683062 : (*it)->curValueOffset = getJsonbOffset((*it)->container,
934 341531 : (*it)->nElems);
935 : /* Set state for next call */
936 341531 : (*it)->state = JBI_OBJECT_KEY;
937 CBC 341531 : return WJB_BEGIN_OBJECT;
938 ECB :
939 CBC 454062 : case JBI_OBJECT_KEY:
940 454062 : if ((*it)->curIndex >= (*it)->nElems)
941 : {
942 ECB : /*
943 : * All pairs within object already processed. Report this to
944 : * caller, and give it back original containing iterator
945 : * (which independently tracks iteration progress at its level
946 : * of nesting).
947 : */
948 GIC 58994 : *it = freeAndGetParent(*it);
949 58994 : return WJB_END_OBJECT;
950 : }
951 : else
952 : {
953 : /* Return key of a key/value pair. */
954 CBC 395068 : fillJsonbValue((*it)->container, (*it)->curIndex,
955 395068 : (*it)->dataProper, (*it)->curDataOffset,
956 : val);
957 GIC 395068 : if (val->type != jbvString)
958 UIC 0 : elog(ERROR, "unexpected jsonb type as object key");
959 :
960 ECB : /* Set state for next call */
961 CBC 395068 : (*it)->state = JBI_OBJECT_VALUE;
962 GIC 395068 : return WJB_KEY;
963 ECB : }
964 EUB :
965 GIC 321048 : case JBI_OBJECT_VALUE:
966 : /* Set state for next call */
967 CBC 321048 : (*it)->state = JBI_OBJECT_KEY;
968 ECB :
969 GIC 321048 : fillJsonbValue((*it)->container, (*it)->curIndex + (*it)->nElems,
970 321048 : (*it)->dataProper, (*it)->curValueOffset,
971 ECB : val);
972 :
973 CBC 321048 : JBE_ADVANCE_OFFSET((*it)->curDataOffset,
974 : (*it)->children[(*it)->curIndex]);
975 321048 : JBE_ADVANCE_OFFSET((*it)->curValueOffset,
976 ECB : (*it)->children[(*it)->curIndex + (*it)->nElems]);
977 GIC 321048 : (*it)->curIndex++;
978 :
979 ECB : /*
980 : * Value may be a container, in which case we recurse with new,
981 : * child iterator (unless the caller asked not to, by passing
982 : * skipNested).
983 : */
984 GIC 321048 : if (!IsAJsonbScalar(val) && !skipNested)
985 : {
986 2611 : *it = iteratorFromContainer(val->val.binary.data, *it);
987 2611 : goto recurse;
988 : }
989 : else
990 CBC 318437 : return WJB_VALUE;
991 : }
992 ECB :
993 LBC 0 : elog(ERROR, "invalid iterator state");
994 : return -1;
995 : }
996 ECB :
997 : /*
998 : * Initialize an iterator for iterating all elements in a container.
999 EUB : */
1000 : static JsonbIterator *
1001 GIC 351324 : iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent)
1002 : {
1003 : JsonbIterator *it;
1004 :
1005 351324 : it = palloc0(sizeof(JsonbIterator));
1006 351324 : it->container = container;
1007 CBC 351324 : it->parent = parent;
1008 GIC 351324 : it->nElems = JsonContainerSize(container);
1009 :
1010 : /* Array starts just after header */
1011 CBC 351324 : it->children = container->children;
1012 ECB :
1013 CBC 351324 : switch (container->header & (JB_FARRAY | JB_FOBJECT))
1014 ECB : {
1015 GIC 9793 : case JB_FARRAY:
1016 9793 : it->dataProper =
1017 CBC 9793 : (char *) it->children + it->nElems * sizeof(JEntry);
1018 GIC 9793 : it->isScalar = JsonContainerIsScalar(container);
1019 ECB : /* This is either a "raw scalar", or an array */
1020 GIC 9793 : Assert(!it->isScalar || it->nElems == 1);
1021 ECB :
1022 CBC 9793 : it->state = JBI_ARRAY_START;
1023 9793 : break;
1024 ECB :
1025 GIC 341531 : case JB_FOBJECT:
1026 CBC 341531 : it->dataProper =
1027 GIC 341531 : (char *) it->children + it->nElems * sizeof(JEntry) * 2;
1028 CBC 341531 : it->state = JBI_OBJECT_START;
1029 341531 : break;
1030 :
1031 LBC 0 : default:
1032 0 : elog(ERROR, "unknown type of jsonb container");
1033 ECB : }
1034 :
1035 CBC 351324 : return it;
1036 : }
1037 EUB :
1038 : /*
1039 : * JsonbIteratorNext() worker: Return parent, while freeing memory for current
1040 : * iterator
1041 ECB : */
1042 : static JsonbIterator *
1043 GIC 67898 : freeAndGetParent(JsonbIterator *it)
1044 : {
1045 67898 : JsonbIterator *v = it->parent;
1046 :
1047 67898 : pfree(it);
1048 67898 : return v;
1049 ECB : }
1050 :
1051 : /*
1052 : * Worker for "contains" operator's function
1053 : *
1054 : * Formally speaking, containment is top-down, unordered subtree isomorphism.
1055 : *
1056 : * Takes iterators that belong to some container type. These iterators
1057 : * "belong" to those values in the sense that they've just been initialized in
1058 : * respect of them by the caller (perhaps in a nested fashion).
1059 : *
1060 : * "val" is lhs Jsonb, and mContained is rhs Jsonb when called from top level.
1061 : * We determine if mContained is contained within val.
1062 : */
1063 : bool
1064 GIC 21810 : JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
1065 : {
1066 : JsonbValue vval,
1067 : vcontained;
1068 : JsonbIteratorToken rval,
1069 : rcont;
1070 ECB :
1071 : /*
1072 : * Guard against stack overflow due to overly complex Jsonb.
1073 : *
1074 : * Functions called here independently take this precaution, but that
1075 : * might not be sufficient since this is also a recursive function.
1076 : */
1077 GIC 21810 : check_stack_depth();
1078 :
1079 21810 : rval = JsonbIteratorNext(val, &vval, false);
1080 21810 : rcont = JsonbIteratorNext(mContained, &vcontained, false);
1081 :
1082 21810 : if (rval != rcont)
1083 ECB : {
1084 : /*
1085 : * The differing return values can immediately be taken as indicating
1086 : * two differing container types at this nesting level, which is
1087 : * sufficient reason to give up entirely (but it should be the case
1088 : * that they're both some container type).
1089 : */
1090 GIC 6 : Assert(rval == WJB_BEGIN_OBJECT || rval == WJB_BEGIN_ARRAY);
1091 6 : Assert(rcont == WJB_BEGIN_OBJECT || rcont == WJB_BEGIN_ARRAY);
1092 6 : return false;
1093 : }
1094 21804 : else if (rcont == WJB_BEGIN_OBJECT)
1095 : {
1096 CBC 21624 : Assert(vval.type == jbvObject);
1097 21624 : Assert(vcontained.type == jbvObject);
1098 ECB :
1099 : /*
1100 : * If the lhs has fewer pairs than the rhs, it can't possibly contain
1101 : * the rhs. (This conclusion is safe only because we de-duplicate
1102 : * keys in all Jsonb objects; thus there can be no corresponding
1103 : * optimization in the array case.) The case probably won't arise
1104 : * often, but since it's such a cheap check we may as well make it.
1105 : */
1106 GIC 21624 : if (vval.val.object.nPairs < vcontained.val.object.nPairs)
1107 1800 : return false;
1108 :
1109 : /* Work through rhs "is it contained within?" object */
1110 : for (;;)
1111 405 : {
1112 ECB : JsonbValue *lhsVal; /* lhsVal is from pair in lhs object */
1113 : JsonbValue lhsValBuf;
1114 :
1115 GIC 20229 : rcont = JsonbIteratorNext(mContained, &vcontained, false);
1116 :
1117 ECB : /*
1118 : * When we get through caller's rhs "is it contained within?"
1119 : * object without failing to find one of its values, it's
1120 : * contained.
1121 : */
1122 GIC 20229 : if (rcont == WJB_END_OBJECT)
1123 19824 : return true;
1124 :
1125 13848 : Assert(rcont == WJB_KEY);
1126 13848 : Assert(vcontained.type == jbvString);
1127 :
1128 ECB : /* First, find value by key... */
1129 : lhsVal =
1130 GIC 13848 : getKeyJsonValueFromContainer((*val)->container,
1131 CBC 13848 : vcontained.val.string.val,
1132 ECB : vcontained.val.string.len,
1133 : &lhsValBuf);
1134 GIC 13848 : if (!lhsVal)
1135 11718 : return false;
1136 ECB :
1137 : /*
1138 : * ...at this stage it is apparent that there is at least a key
1139 : * match for this rhs pair.
1140 : */
1141 CBC 2130 : rcont = JsonbIteratorNext(mContained, &vcontained, true);
1142 :
1143 GIC 2130 : Assert(rcont == WJB_VALUE);
1144 :
1145 : /*
1146 : * Compare rhs pair's value with lhs pair's value just found using
1147 ECB : * key
1148 : */
1149 CBC 2130 : if (lhsVal->type != vcontained.type)
1150 : {
1151 GIC 585 : return false;
1152 : }
1153 1545 : else if (IsAJsonbScalar(lhsVal))
1154 : {
1155 CBC 1479 : if (!equalsJsonbScalarValue(lhsVal, &vcontained))
1156 GIC 1122 : return false;
1157 ECB : }
1158 : else
1159 : {
1160 : /* Nested container value (object or array) */
1161 : JsonbIterator *nestval,
1162 : *nestContained;
1163 :
1164 GIC 66 : Assert(lhsVal->type == jbvBinary);
1165 66 : Assert(vcontained.type == jbvBinary);
1166 :
1167 66 : nestval = JsonbIteratorInit(lhsVal->val.binary.data);
1168 66 : nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1169 :
1170 ECB : /*
1171 : * Match "value" side of rhs datum object's pair recursively.
1172 : * It's a nested structure.
1173 : *
1174 : * Note that nesting still has to "match up" at the right
1175 : * nesting sub-levels. However, there need only be zero or
1176 : * more matching pairs (or elements) at each nesting level
1177 : * (provided the *rhs* pairs/elements *all* match on each
1178 : * level), which enables searching nested structures for a
1179 : * single String or other primitive type sub-datum quite
1180 : * effectively (provided the user constructed the rhs nested
1181 : * structure such that we "know where to look").
1182 : *
1183 : * In other words, the mapping of container nodes in the rhs
1184 : * "vcontained" Jsonb to internal nodes on the lhs is
1185 : * injective, and parent-child edges on the rhs must be mapped
1186 : * to parent-child edges on the lhs to satisfy the condition
1187 : * of containment (plus of course the mapped nodes must be
1188 : * equal).
1189 : */
1190 GIC 66 : if (!JsonbDeepContains(&nestval, &nestContained))
1191 18 : return false;
1192 : }
1193 : }
1194 : }
1195 180 : else if (rcont == WJB_BEGIN_ARRAY)
1196 ECB : {
1197 CBC 180 : JsonbValue *lhsConts = NULL;
1198 GIC 180 : uint32 nLhsElems = vval.val.array.nElems;
1199 :
1200 180 : Assert(vval.type == jbvArray);
1201 CBC 180 : Assert(vcontained.type == jbvArray);
1202 :
1203 ECB : /*
1204 : * Handle distinction between "raw scalar" pseudo arrays, and real
1205 : * arrays.
1206 : *
1207 : * A raw scalar may contain another raw scalar, and an array may
1208 : * contain a raw scalar, but a raw scalar may not contain an array. We
1209 : * don't do something like this for the object case, since objects can
1210 : * only contain pairs, never raw scalars (a pair is represented by an
1211 : * rhs object argument with a single contained pair).
1212 : */
1213 GIC 180 : if (vval.val.array.rawScalar && !vcontained.val.array.rawScalar)
1214 3 : return false;
1215 :
1216 : /* Work through rhs "is it contained within?" array */
1217 : for (;;)
1218 : {
1219 CBC 408 : rcont = JsonbIteratorNext(mContained, &vcontained, true);
1220 ECB :
1221 : /*
1222 : * When we get through caller's rhs "is it contained within?"
1223 : * array without failing to find one of its values, it's
1224 : * contained.
1225 : */
1226 GIC 408 : if (rcont == WJB_END_ARRAY)
1227 144 : return true;
1228 :
1229 264 : Assert(rcont == WJB_ELEM);
1230 :
1231 264 : if (IsAJsonbScalar(&vcontained))
1232 ECB : {
1233 CBC 201 : if (!findJsonbValueFromContainer((*val)->container,
1234 : JB_FARRAY,
1235 ECB : &vcontained))
1236 GIC 27 : return false;
1237 ECB : }
1238 : else
1239 : {
1240 : uint32 i;
1241 :
1242 : /*
1243 : * If this is first container found in rhs array (at this
1244 : * depth), initialize temp lhs array of containers
1245 : */
1246 GIC 63 : if (lhsConts == NULL)
1247 : {
1248 60 : uint32 j = 0;
1249 :
1250 : /* Make room for all possible values */
1251 60 : lhsConts = palloc(sizeof(JsonbValue) * nLhsElems);
1252 ECB :
1253 GIC 198 : for (i = 0; i < nLhsElems; i++)
1254 ECB : {
1255 : /* Store all lhs elements in temp array */
1256 GIC 138 : rcont = JsonbIteratorNext(val, &vval, true);
1257 CBC 138 : Assert(rcont == WJB_ELEM);
1258 :
1259 138 : if (vval.type == jbvBinary)
1260 GIC 69 : lhsConts[j++] = vval;
1261 : }
1262 ECB :
1263 : /* No container elements in temp array, so give up now */
1264 GIC 60 : if (j == 0)
1265 LBC 0 : return false;
1266 ECB :
1267 : /* We may have only partially filled array */
1268 GIC 60 : nLhsElems = j;
1269 : }
1270 ECB :
1271 EUB : /* XXX: Nested array containment is O(N^2) */
1272 GIC 78 : for (i = 0; i < nLhsElems; i++)
1273 : {
1274 ECB : /* Nested container value (object or array) */
1275 : JsonbIterator *nestval,
1276 : *nestContained;
1277 : bool contains;
1278 :
1279 GIC 72 : nestval = JsonbIteratorInit(lhsConts[i].val.binary.data);
1280 72 : nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1281 :
1282 72 : contains = JsonbDeepContains(&nestval, &nestContained);
1283 :
1284 72 : if (nestval)
1285 CBC 72 : pfree(nestval);
1286 72 : if (nestContained)
1287 GIC 15 : pfree(nestContained);
1288 CBC 72 : if (contains)
1289 GIC 57 : break;
1290 ECB : }
1291 :
1292 : /*
1293 : * Report rhs container value is not contained if couldn't
1294 : * match rhs container to *some* lhs cont
1295 : */
1296 GIC 63 : if (i == nLhsElems)
1297 6 : return false;
1298 : }
1299 : }
1300 : }
1301 : else
1302 ECB : {
1303 LBC 0 : elog(ERROR, "invalid jsonb container type");
1304 : }
1305 :
1306 : elog(ERROR, "unexpectedly fell off end of jsonb container");
1307 : return false;
1308 : }
1309 EUB :
1310 : /*
1311 : * Hash a JsonbValue scalar value, mixing the hash value into an existing
1312 : * hash provided by the caller.
1313 : *
1314 : * Some callers may wish to independently XOR in JB_FOBJECT and JB_FARRAY
1315 : * flags.
1316 : */
1317 : void
1318 GIC 86883 : JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash)
1319 : {
1320 : uint32 tmp;
1321 :
1322 : /* Compute hash value for scalarVal */
1323 86883 : switch (scalarVal->type)
1324 ECB : {
1325 GIC 48 : case jbvNull:
1326 48 : tmp = 0x01;
1327 48 : break;
1328 63600 : case jbvString:
1329 CBC 63600 : tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->val.string.val,
1330 GIC 63600 : scalarVal->val.string.len));
1331 CBC 63600 : break;
1332 14913 : case jbvNumeric:
1333 ECB : /* Must hash equal numerics to equal hash codes */
1334 CBC 14913 : tmp = DatumGetUInt32(DirectFunctionCall1(hash_numeric,
1335 ECB : NumericGetDatum(scalarVal->val.numeric)));
1336 CBC 14913 : break;
1337 8322 : case jbvBool:
1338 8322 : tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1339 :
1340 8322 : break;
1341 UIC 0 : default:
1342 LBC 0 : elog(ERROR, "invalid jsonb scalar type");
1343 ECB : tmp = 0; /* keep compiler quiet */
1344 : break;
1345 : }
1346 :
1347 EUB : /*
1348 : * Combine hash values of successive keys, values and elements by rotating
1349 : * the previous value left 1 bit, then XOR'ing in the new
1350 : * key/value/element's hash value.
1351 : */
1352 GIC 86883 : *hash = pg_rotate_left32(*hash, 1);
1353 86883 : *hash ^= tmp;
1354 86883 : }
1355 :
1356 : /*
1357 : * Hash a value to a 64-bit value, with a seed. Otherwise, similar to
1358 ECB : * JsonbHashScalarValue.
1359 : */
1360 : void
1361 GIC 108 : JsonbHashScalarValueExtended(const JsonbValue *scalarVal, uint64 *hash,
1362 : uint64 seed)
1363 : {
1364 : uint64 tmp;
1365 :
1366 108 : switch (scalarVal->type)
1367 ECB : {
1368 GIC 6 : case jbvNull:
1369 6 : tmp = seed + 0x01;
1370 6 : break;
1371 90 : case jbvString:
1372 CBC 90 : tmp = DatumGetUInt64(hash_any_extended((const unsigned char *) scalarVal->val.string.val,
1373 GIC 90 : scalarVal->val.string.len,
1374 ECB : seed));
1375 CBC 90 : break;
1376 6 : case jbvNumeric:
1377 6 : tmp = DatumGetUInt64(DirectFunctionCall2(hash_numeric_extended,
1378 ECB : NumericGetDatum(scalarVal->val.numeric),
1379 : UInt64GetDatum(seed)));
1380 GIC 6 : break;
1381 CBC 6 : case jbvBool:
1382 6 : if (seed)
1383 3 : tmp = DatumGetUInt64(DirectFunctionCall2(hashcharextended,
1384 : BoolGetDatum(scalarVal->val.boolean),
1385 : UInt64GetDatum(seed)));
1386 ECB : else
1387 CBC 3 : tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1388 ECB :
1389 CBC 6 : break;
1390 UIC 0 : default:
1391 0 : elog(ERROR, "invalid jsonb scalar type");
1392 : break;
1393 ECB : }
1394 :
1395 CBC 108 : *hash = ROTATE_HIGH_AND_LOW_32BITS(*hash);
1396 GBC 108 : *hash ^= tmp;
1397 108 : }
1398 :
1399 : /*
1400 : * Are two scalar JsonbValues of the same type a and b equal?
1401 ECB : */
1402 : static bool
1403 GNC 1833 : equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b)
1404 : {
1405 1833 : if (a->type == b->type)
1406 : {
1407 1833 : switch (a->type)
1408 : {
1409 CBC 21 : case jbvNull:
1410 GIC 21 : return true;
1411 CBC 1524 : case jbvString:
1412 GNC 1524 : return lengthCompareJsonbStringValue(a, b) == 0;
1413 CBC 261 : case jbvNumeric:
1414 GIC 261 : return DatumGetBool(DirectFunctionCall2(numeric_eq,
1415 : PointerGetDatum(a->val.numeric),
1416 : PointerGetDatum(b->val.numeric)));
1417 CBC 27 : case jbvBool:
1418 GNC 27 : return a->val.boolean == b->val.boolean;
1419 ECB :
1420 LBC 0 : default:
1421 UIC 0 : elog(ERROR, "invalid jsonb scalar type");
1422 : }
1423 ECB : }
1424 LBC 0 : elog(ERROR, "jsonb scalar type mismatch");
1425 : return false;
1426 EUB : }
1427 :
1428 : /*
1429 : * Compare two scalar JsonbValues, returning -1, 0, or 1.
1430 : *
1431 : * Strings are compared using the default collation. Used by B-tree
1432 : * operators, where a lexical sort order is generally expected.
1433 : */
1434 : static int
1435 GNC 234682 : compareJsonbScalarValue(JsonbValue *a, JsonbValue *b)
1436 : {
1437 234682 : if (a->type == b->type)
1438 : {
1439 234682 : switch (a->type)
1440 : {
1441 CBC 11 : case jbvNull:
1442 GIC 11 : return 0;
1443 CBC 159859 : case jbvString:
1444 GNC 159859 : return varstr_cmp(a->val.string.val,
1445 : a->val.string.len,
1446 159859 : b->val.string.val,
1447 : b->val.string.len,
1448 ECB : DEFAULT_COLLATION_OID);
1449 CBC 55509 : case jbvNumeric:
1450 55509 : return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
1451 : PointerGetDatum(a->val.numeric),
1452 : PointerGetDatum(b->val.numeric)));
1453 GIC 19303 : case jbvBool:
1454 GNC 19303 : if (a->val.boolean == b->val.boolean)
1455 CBC 16835 : return 0;
1456 GNC 2468 : else if (a->val.boolean > b->val.boolean)
1457 GIC 1316 : return 1;
1458 : else
1459 CBC 1152 : return -1;
1460 LBC 0 : default:
1461 0 : elog(ERROR, "invalid jsonb scalar type");
1462 ECB : }
1463 : }
1464 UIC 0 : elog(ERROR, "jsonb scalar type mismatch");
1465 ECB : return -1;
1466 EUB : }
1467 :
1468 :
1469 : /*
1470 : * Functions for manipulating the resizable buffer used by convertJsonb and
1471 : * its subroutines.
1472 : */
1473 :
1474 : /*
1475 : * Reserve 'len' bytes, at the end of the buffer, enlarging it if necessary.
1476 : * Returns the offset to the reserved area. The caller is expected to fill
1477 : * the reserved area later with copyToBuffer().
1478 : */
1479 : static int
1480 GIC 301113 : reserveFromBuffer(StringInfo buffer, int len)
1481 : {
1482 : int offset;
1483 :
1484 : /* Make more room if needed */
1485 301113 : enlargeStringInfo(buffer, len);
1486 ECB :
1487 : /* remember current offset */
1488 GIC 301113 : offset = buffer->len;
1489 :
1490 : /* reserve the space */
1491 CBC 301113 : buffer->len += len;
1492 :
1493 : /*
1494 ECB : * Keep a trailing null in place, even though it's not useful for us; it
1495 : * seems best to preserve the invariants of StringInfos.
1496 : */
1497 CBC 301113 : buffer->data[buffer->len] = '\0';
1498 :
1499 GIC 301113 : return offset;
1500 : }
1501 :
1502 : /*
1503 ECB : * Copy 'len' bytes to a previously reserved area in buffer.
1504 : */
1505 : static void
1506 GIC 230556 : copyToBuffer(StringInfo buffer, int offset, const char *data, int len)
1507 : {
1508 230556 : memcpy(buffer->data + offset, data, len);
1509 230556 : }
1510 :
1511 : /*
1512 ECB : * A shorthand for reserveFromBuffer + copyToBuffer.
1513 : */
1514 : static void
1515 CBC 131014 : appendToBuffer(StringInfo buffer, const char *data, int len)
1516 : {
1517 : int offset;
1518 :
1519 GIC 131014 : offset = reserveFromBuffer(buffer, len);
1520 131014 : copyToBuffer(buffer, offset, data, len);
1521 CBC 131014 : }
1522 :
1523 :
1524 : /*
1525 ECB : * Append padding, so that the length of the StringInfo is int-aligned.
1526 : * Returns the number of padding bytes appended.
1527 : */
1528 : static short
1529 GIC 75430 : padBufferToInt(StringInfo buffer)
1530 : {
1531 : int padlen,
1532 : p,
1533 : offset;
1534 :
1535 CBC 75430 : padlen = INTALIGN(buffer->len) - buffer->len;
1536 :
1537 GIC 75430 : offset = reserveFromBuffer(buffer, padlen);
1538 :
1539 : /* padlen must be small, so this is probably faster than a memset */
1540 96966 : for (p = 0; p < padlen; p++)
1541 CBC 21536 : buffer->data[offset + p] = '\0';
1542 :
1543 75430 : return padlen;
1544 : }
1545 :
1546 ECB : /*
1547 : * Given a JsonbValue, convert to Jsonb. The result is palloc'd.
1548 : */
1549 : static Jsonb *
1550 GIC 44506 : convertToJsonb(JsonbValue *val)
1551 : {
1552 : StringInfoData buffer;
1553 : JEntry jentry;
1554 : Jsonb *res;
1555 :
1556 ECB : /* Should not already have binary representation */
1557 GIC 44506 : Assert(val->type != jbvBinary);
1558 :
1559 : /* Allocate an output buffer. It will be enlarged as needed */
1560 44506 : initStringInfo(&buffer);
1561 :
1562 : /* Make room for the varlena header */
1563 CBC 44506 : reserveFromBuffer(&buffer, VARHDRSZ);
1564 :
1565 GIC 44506 : convertJsonbValue(&buffer, &jentry, val, 0);
1566 ECB :
1567 : /*
1568 : * Note: the JEntry of the root is discarded. Therefore the root
1569 : * JsonbContainer struct must contain enough information to tell what kind
1570 : * of value it is.
1571 : */
1572 :
1573 GIC 44506 : res = (Jsonb *) buffer.data;
1574 :
1575 44506 : SET_VARSIZE(res, buffer.len);
1576 :
1577 44506 : return res;
1578 : }
1579 ECB :
1580 : /*
1581 : * Subroutine of convertJsonb: serialize a single JsonbValue into buffer.
1582 : *
1583 : * The JEntry header for this node is returned in *header. It is filled in
1584 : * with the length of this value and appropriate type bits. If we wish to
1585 : * store an end offset rather than a length, it is the caller's responsibility
1586 : * to adjust for that.
1587 : *
1588 : * If the value is an array or an object, this recurses. 'level' is only used
1589 : * for debugging purposes.
1590 : */
1591 : static void
1592 GIC 116223 : convertJsonbValue(StringInfo buffer, JEntry *header, JsonbValue *val, int level)
1593 : {
1594 116223 : check_stack_depth();
1595 :
1596 116223 : if (!val)
1597 UIC 0 : return;
1598 ECB :
1599 : /*
1600 : * A JsonbValue passed as val should never have a type of jbvBinary, and
1601 : * neither should any of its sub-components. Those values will be produced
1602 : * by convertJsonbArray and convertJsonbObject, the results of which will
1603 EUB : * not be passed back to this function as an argument.
1604 : */
1605 :
1606 GIC 116223 : if (IsAJsonbScalar(val))
1607 66060 : convertJsonbScalar(buffer, header, val);
1608 50163 : else if (val->type == jbvArray)
1609 38169 : convertJsonbArray(buffer, header, val, level);
1610 11994 : else if (val->type == jbvObject)
1611 11994 : convertJsonbObject(buffer, header, val, level);
1612 ECB : else
1613 LBC 0 : elog(ERROR, "unknown type of jsonb container to convert");
1614 ECB : }
1615 :
1616 : static void
1617 GNC 38169 : convertJsonbArray(StringInfo buffer, JEntry *header, JsonbValue *val, int level)
1618 : {
1619 EUB : int base_offset;
1620 : int jentry_offset;
1621 : int i;
1622 : int totallen;
1623 : uint32 containerhead;
1624 GIC 38169 : int nElems = val->val.array.nElems;
1625 :
1626 : /* Remember where in the buffer this array starts. */
1627 38169 : base_offset = buffer->len;
1628 :
1629 : /* Align to 4-byte boundary (any padding counts as part of my data) */
1630 CBC 38169 : padBufferToInt(buffer);
1631 :
1632 : /*
1633 ECB : * Construct the header Jentry and store it in the beginning of the
1634 : * variable-length payload.
1635 : */
1636 GNC 38169 : containerhead = nElems | JB_FARRAY;
1637 GIC 38169 : if (val->val.array.rawScalar)
1638 : {
1639 33786 : Assert(nElems == 1);
1640 33786 : Assert(level == 0);
1641 GNC 33786 : containerhead |= JB_FSCALAR;
1642 ECB : }
1643 :
1644 GNC 38169 : appendToBuffer(buffer, (char *) &containerhead, sizeof(uint32));
1645 ECB :
1646 : /* Reserve space for the JEntries of the elements. */
1647 CBC 38169 : jentry_offset = reserveFromBuffer(buffer, sizeof(JEntry) * nElems);
1648 :
1649 GIC 38169 : totallen = 0;
1650 CBC 82061 : for (i = 0; i < nElems; i++)
1651 : {
1652 GIC 43892 : JsonbValue *elem = &val->val.array.elems[i];
1653 ECB : int len;
1654 : JEntry meta;
1655 :
1656 : /*
1657 : * Convert element, producing a JEntry and appending its
1658 : * variable-length data to buffer
1659 : */
1660 GIC 43892 : convertJsonbValue(buffer, &meta, elem, level + 1);
1661 :
1662 43892 : len = JBE_OFFLENFLD(meta);
1663 43892 : totallen += len;
1664 :
1665 : /*
1666 ECB : * Bail out if total variable-length data exceeds what will fit in a
1667 : * JEntry length field. We check this in each iteration, not just
1668 : * once at the end, to forestall possible integer overflow.
1669 : */
1670 GIC 43892 : if (totallen > JENTRY_OFFLENMASK)
1671 UIC 0 : ereport(ERROR,
1672 : (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1673 : errmsg("total size of jsonb array elements exceeds the maximum of %d bytes",
1674 : JENTRY_OFFLENMASK)));
1675 :
1676 ECB : /*
1677 EUB : * Convert each JB_OFFSET_STRIDE'th length to an offset.
1678 : */
1679 GIC 43892 : if ((i % JB_OFFSET_STRIDE) == 0)
1680 37757 : meta = (meta & JENTRY_TYPEMASK) | totallen | JENTRY_HAS_OFF;
1681 :
1682 43892 : copyToBuffer(buffer, jentry_offset, (char *) &meta, sizeof(JEntry));
1683 43892 : jentry_offset += sizeof(JEntry);
1684 : }
1685 ECB :
1686 : /* Total data size is everything we've appended to buffer */
1687 GIC 38169 : totallen = buffer->len - base_offset;
1688 ECB :
1689 : /* Check length again, since we didn't include the metadata above */
1690 GIC 38169 : if (totallen > JENTRY_OFFLENMASK)
1691 UIC 0 : ereport(ERROR,
1692 : (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1693 : errmsg("total size of jsonb array elements exceeds the maximum of %d bytes",
1694 : JENTRY_OFFLENMASK)));
1695 :
1696 ECB : /* Initialize the header of this node in the container's JEntry array */
1697 GNC 38169 : *header = JENTRY_ISCONTAINER | totallen;
1698 GIC 38169 : }
1699 :
1700 : static void
1701 GNC 11994 : convertJsonbObject(StringInfo buffer, JEntry *header, JsonbValue *val, int level)
1702 : {
1703 ECB : int base_offset;
1704 : int jentry_offset;
1705 : int i;
1706 : int totallen;
1707 : uint32 containerheader;
1708 GIC 11994 : int nPairs = val->val.object.nPairs;
1709 :
1710 : /* Remember where in the buffer this object starts. */
1711 11994 : base_offset = buffer->len;
1712 :
1713 : /* Align to 4-byte boundary (any padding counts as part of my data) */
1714 CBC 11994 : padBufferToInt(buffer);
1715 :
1716 : /*
1717 ECB : * Construct the header Jentry and store it in the beginning of the
1718 : * variable-length payload.
1719 : */
1720 GNC 11994 : containerheader = nPairs | JB_FOBJECT;
1721 11994 : appendToBuffer(buffer, (char *) &containerheader, sizeof(uint32));
1722 :
1723 : /* Reserve space for the JEntries of the keys and values. */
1724 GIC 11994 : jentry_offset = reserveFromBuffer(buffer, sizeof(JEntry) * nPairs * 2);
1725 :
1726 ECB : /*
1727 : * Iterate over the keys, then over the values, since that is the ordering
1728 : * we want in the on-disk representation.
1729 : */
1730 CBC 11994 : totallen = 0;
1731 GIC 39819 : for (i = 0; i < nPairs; i++)
1732 : {
1733 27825 : JsonbPair *pair = &val->val.object.pairs[i];
1734 : int len;
1735 : JEntry meta;
1736 ECB :
1737 : /*
1738 : * Convert key, producing a JEntry and appending its variable-length
1739 : * data to buffer
1740 : */
1741 GIC 27825 : convertJsonbScalar(buffer, &meta, &pair->key);
1742 :
1743 27825 : len = JBE_OFFLENFLD(meta);
1744 27825 : totallen += len;
1745 :
1746 : /*
1747 ECB : * Bail out if total variable-length data exceeds what will fit in a
1748 : * JEntry length field. We check this in each iteration, not just
1749 : * once at the end, to forestall possible integer overflow.
1750 : */
1751 GIC 27825 : if (totallen > JENTRY_OFFLENMASK)
1752 UIC 0 : ereport(ERROR,
1753 : (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1754 : errmsg("total size of jsonb object elements exceeds the maximum of %d bytes",
1755 : JENTRY_OFFLENMASK)));
1756 :
1757 ECB : /*
1758 EUB : * Convert each JB_OFFSET_STRIDE'th length to an offset.
1759 : */
1760 GIC 27825 : if ((i % JB_OFFSET_STRIDE) == 0)
1761 8321 : meta = (meta & JENTRY_TYPEMASK) | totallen | JENTRY_HAS_OFF;
1762 :
1763 27825 : copyToBuffer(buffer, jentry_offset, (char *) &meta, sizeof(JEntry));
1764 27825 : jentry_offset += sizeof(JEntry);
1765 : }
1766 CBC 39819 : for (i = 0; i < nPairs; i++)
1767 ECB : {
1768 GIC 27825 : JsonbPair *pair = &val->val.object.pairs[i];
1769 ECB : int len;
1770 : JEntry meta;
1771 :
1772 : /*
1773 : * Convert value, producing a JEntry and appending its variable-length
1774 : * data to buffer
1775 : */
1776 GIC 27825 : convertJsonbValue(buffer, &meta, &pair->value, level + 1);
1777 :
1778 27825 : len = JBE_OFFLENFLD(meta);
1779 27825 : totallen += len;
1780 :
1781 : /*
1782 ECB : * Bail out if total variable-length data exceeds what will fit in a
1783 : * JEntry length field. We check this in each iteration, not just
1784 : * once at the end, to forestall possible integer overflow.
1785 : */
1786 GIC 27825 : if (totallen > JENTRY_OFFLENMASK)
1787 UIC 0 : ereport(ERROR,
1788 : (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1789 : errmsg("total size of jsonb object elements exceeds the maximum of %d bytes",
1790 : JENTRY_OFFLENMASK)));
1791 :
1792 ECB : /*
1793 EUB : * Convert each JB_OFFSET_STRIDE'th length to an offset.
1794 : */
1795 GIC 27825 : if (((i + nPairs) % JB_OFFSET_STRIDE) == 0)
1796 69 : meta = (meta & JENTRY_TYPEMASK) | totallen | JENTRY_HAS_OFF;
1797 :
1798 27825 : copyToBuffer(buffer, jentry_offset, (char *) &meta, sizeof(JEntry));
1799 27825 : jentry_offset += sizeof(JEntry);
1800 : }
1801 ECB :
1802 : /* Total data size is everything we've appended to buffer */
1803 GIC 11994 : totallen = buffer->len - base_offset;
1804 ECB :
1805 : /* Check length again, since we didn't include the metadata above */
1806 GIC 11994 : if (totallen > JENTRY_OFFLENMASK)
1807 UIC 0 : ereport(ERROR,
1808 : (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1809 : errmsg("total size of jsonb object elements exceeds the maximum of %d bytes",
1810 : JENTRY_OFFLENMASK)));
1811 :
1812 ECB : /* Initialize the header of this node in the container's JEntry array */
1813 GNC 11994 : *header = JENTRY_ISCONTAINER | totallen;
1814 GIC 11994 : }
1815 :
1816 : static void
1817 GNC 93885 : convertJsonbScalar(StringInfo buffer, JEntry *header, JsonbValue *scalarVal)
1818 : {
1819 ECB : int numlen;
1820 : short padlen;
1821 :
1822 GIC 93885 : switch (scalarVal->type)
1823 ECB : {
1824 GIC 1412 : case jbvNull:
1825 GNC 1412 : *header = JENTRY_ISNULL;
1826 GIC 1412 : break;
1827 :
1828 CBC 55347 : case jbvString:
1829 GIC 55347 : appendToBuffer(buffer, scalarVal->val.string.val, scalarVal->val.string.len);
1830 ECB :
1831 GNC 55347 : *header = scalarVal->val.string.len;
1832 CBC 55347 : break;
1833 :
1834 25267 : case jbvNumeric:
1835 25267 : numlen = VARSIZE_ANY(scalarVal->val.numeric);
1836 GIC 25267 : padlen = padBufferToInt(buffer);
1837 ECB :
1838 CBC 25267 : appendToBuffer(buffer, (char *) scalarVal->val.numeric, numlen);
1839 :
1840 GNC 25267 : *header = JENTRY_ISNUMERIC | (padlen + numlen);
1841 CBC 25267 : break;
1842 ECB :
1843 GIC 11622 : case jbvBool:
1844 GNC 23244 : *header = (scalarVal->val.boolean) ?
1845 GIC 11622 : JENTRY_ISBOOL_TRUE : JENTRY_ISBOOL_FALSE;
1846 CBC 11622 : break;
1847 ECB :
1848 GIC 237 : case jbvDatetime:
1849 ECB : {
1850 : char buf[MAXDATELEN + 1];
1851 : size_t len;
1852 :
1853 GIC 237 : JsonEncodeDateTime(buf,
1854 ECB : scalarVal->val.datetime.value,
1855 : scalarVal->val.datetime.typid,
1856 GIC 237 : &scalarVal->val.datetime.tz);
1857 237 : len = strlen(buf);
1858 237 : appendToBuffer(buffer, buf, len);
1859 ECB :
1860 GNC 237 : *header = len;
1861 : }
1862 CBC 237 : break;
1863 ECB :
1864 LBC 0 : default:
1865 UIC 0 : elog(ERROR, "invalid jsonb scalar type");
1866 ECB : }
1867 GIC 93885 : }
1868 ECB :
1869 : /*
1870 EUB : * Compare two jbvString JsonbValue values, a and b.
1871 : *
1872 : * This is a special qsort() comparator used to sort strings in certain
1873 ECB : * internal contexts where it is sufficient to have a well-defined sort order.
1874 : * In particular, object pair keys are sorted according to this criteria to
1875 : * facilitate cheap binary searches where we don't care about lexical sort
1876 : * order.
1877 : *
1878 : * a and b are first sorted based on their length. If a tie-breaker is
1879 : * required, only then do we consider string binary equality.
1880 : */
1881 : static int
1882 GIC 41094 : lengthCompareJsonbStringValue(const void *a, const void *b)
1883 : {
1884 41094 : const JsonbValue *va = (const JsonbValue *) a;
1885 41094 : const JsonbValue *vb = (const JsonbValue *) b;
1886 :
1887 41094 : Assert(va->type == jbvString);
1888 CBC 41094 : Assert(vb->type == jbvString);
1889 :
1890 82188 : return lengthCompareJsonbString(va->val.string.val, va->val.string.len,
1891 41094 : vb->val.string.val, vb->val.string.len);
1892 : }
1893 ECB :
1894 : /*
1895 : * Subroutine for lengthCompareJsonbStringValue
1896 : *
1897 : * This is also useful separately to implement binary search on
1898 : * JsonbContainers.
1899 : */
1900 : static int
1901 GIC 342199 : lengthCompareJsonbString(const char *val1, int len1, const char *val2, int len2)
1902 : {
1903 342199 : if (len1 == len2)
1904 105755 : return memcmp(val1, val2, len1);
1905 : else
1906 236444 : return len1 > len2 ? 1 : -1;
1907 ECB : }
1908 :
1909 : /*
1910 : * qsort_arg() comparator to compare JsonbPair values.
1911 : *
1912 : * Third argument 'binequal' may point to a bool. If it's set, *binequal is set
1913 : * to true iff a and b have full binary equality, since some callers have an
1914 : * interest in whether the two values are equal or merely equivalent.
1915 : *
1916 : * N.B: String comparisons here are "length-wise"
1917 : *
1918 : * Pairs with equals keys are ordered such that the order field is respected.
1919 : */
1920 : static int
1921 GIC 39432 : lengthCompareJsonbPair(const void *a, const void *b, void *binequal)
1922 : {
1923 39432 : const JsonbPair *pa = (const JsonbPair *) a;
1924 39432 : const JsonbPair *pb = (const JsonbPair *) b;
1925 : int res;
1926 :
1927 CBC 39432 : res = lengthCompareJsonbStringValue(&pa->key, &pb->key);
1928 GIC 39432 : if (res == 0 && binequal)
1929 CBC 87 : *((bool *) binequal) = true;
1930 ECB :
1931 : /*
1932 : * Guarantee keeping order of equal pair. Unique algorithm will prefer
1933 : * first element as value.
1934 : */
1935 CBC 39432 : if (res == 0)
1936 GIC 87 : res = (pa->order > pb->order) ? -1 : 1;
1937 :
1938 39432 : return res;
1939 : }
1940 :
1941 ECB : /*
1942 : * Sort and unique-ify pairs in JsonbValue object
1943 : */
1944 : static void
1945 GNC 12012 : uniqueifyJsonbObject(JsonbValue *object, bool unique_keys, bool skip_nulls)
1946 : {
1947 GIC 12012 : bool hasNonUniq = false;
1948 :
1949 12012 : Assert(object->type == jbvObject);
1950 :
1951 CBC 12012 : if (object->val.object.nPairs > 1)
1952 GIC 5317 : qsort_arg(object->val.object.pairs, object->val.object.nPairs, sizeof(JsonbPair),
1953 ECB : lengthCompareJsonbPair, &hasNonUniq);
1954 :
1955 GNC 12012 : if (hasNonUniq && unique_keys)
1956 15 : ereport(ERROR,
1957 : errcode(ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE),
1958 : errmsg("duplicate JSON object key"));
1959 :
1960 11997 : if (hasNonUniq || skip_nulls)
1961 : {
1962 : JsonbPair *ptr,
1963 : *res;
1964 :
1965 76 : while (skip_nulls && object->val.object.nPairs > 0 &&
1966 10 : object->val.object.pairs->value.type == jbvNull)
1967 ECB : {
1968 : /* If skip_nulls is true, remove leading items with null */
1969 UNC 0 : object->val.object.pairs++;
1970 0 : object->val.object.nPairs--;
1971 : }
1972 ECB :
1973 GNC 76 : if (object->val.object.nPairs > 0)
1974 : {
1975 76 : ptr = object->val.object.pairs + 1;
1976 76 : res = object->val.object.pairs;
1977 :
1978 214 : while (ptr - object->val.object.pairs < object->val.object.nPairs)
1979 : {
1980 : /* Avoid copying over duplicate or null */
1981 138 : if (lengthCompareJsonbStringValue(ptr, res) != 0 &&
1982 66 : (!skip_nulls || ptr->value.type != jbvNull))
1983 : {
1984 60 : res++;
1985 60 : if (ptr != res)
1986 54 : memcpy(res, ptr, sizeof(JsonbPair));
1987 : }
1988 138 : ptr++;
1989 : }
1990 :
1991 76 : object->val.object.nPairs = res + 1 - object->val.object.pairs;
1992 : }
1993 : }
1994 GIC 11997 : }
|