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