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