PostgreSQL Source Code  git master
jsonb.h File Reference
#include "lib/stringinfo.h"
#include "utils/array.h"
#include "utils/numeric.h"
Include dependency graph for jsonb.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  JsonbContainer
 
struct  Jsonb
 
struct  JsonbValue
 
struct  JsonbPair
 
struct  JsonbParseState
 
struct  JsonbIterator
 

Macros

#define JsonbContainsStrategyNumber   7
 
#define JsonbExistsStrategyNumber   9
 
#define JsonbExistsAnyStrategyNumber   10
 
#define JsonbExistsAllStrategyNumber   11
 
#define JsonbJsonpathExistsStrategyNumber   15
 
#define JsonbJsonpathPredicateStrategyNumber   16
 
#define JGINFLAG_KEY   0x01 /* key (or string array element) */
 
#define JGINFLAG_NULL   0x02 /* null value */
 
#define JGINFLAG_BOOL   0x03 /* boolean value */
 
#define JGINFLAG_NUM   0x04 /* numeric value */
 
#define JGINFLAG_STR   0x05 /* string value (if not an array element) */
 
#define JGINFLAG_HASHED   0x10 /* OR'd into flag if value was hashed */
 
#define JGIN_MAXLENGTH   125 /* max length of text part before hashing */
 
#define DatumGetJsonbP(d)   ((Jsonb *) PG_DETOAST_DATUM(d))
 
#define DatumGetJsonbPCopy(d)   ((Jsonb *) PG_DETOAST_DATUM_COPY(d))
 
#define JsonbPGetDatum(p)   PointerGetDatum(p)
 
#define PG_GETARG_JSONB_P(x)   DatumGetJsonbP(PG_GETARG_DATUM(x))
 
#define PG_GETARG_JSONB_P_COPY(x)   DatumGetJsonbPCopy(PG_GETARG_DATUM(x))
 
#define PG_RETURN_JSONB_P(x)   PG_RETURN_POINTER(x)
 
#define JENTRY_OFFLENMASK   0x0FFFFFFF
 
#define JENTRY_TYPEMASK   0x70000000
 
#define JENTRY_HAS_OFF   0x80000000
 
#define JENTRY_ISSTRING   0x00000000
 
#define JENTRY_ISNUMERIC   0x10000000
 
#define JENTRY_ISBOOL_FALSE   0x20000000
 
#define JENTRY_ISBOOL_TRUE   0x30000000
 
#define JENTRY_ISNULL   0x40000000
 
#define JENTRY_ISCONTAINER   0x50000000 /* array or object */
 
#define JBE_OFFLENFLD(je_)   ((je_) & JENTRY_OFFLENMASK)
 
#define JBE_HAS_OFF(je_)   (((je_) & JENTRY_HAS_OFF) != 0)
 
#define JBE_ISSTRING(je_)   (((je_) & JENTRY_TYPEMASK) == JENTRY_ISSTRING)
 
#define JBE_ISNUMERIC(je_)   (((je_) & JENTRY_TYPEMASK) == JENTRY_ISNUMERIC)
 
#define JBE_ISCONTAINER(je_)   (((je_) & JENTRY_TYPEMASK) == JENTRY_ISCONTAINER)
 
#define JBE_ISNULL(je_)   (((je_) & JENTRY_TYPEMASK) == JENTRY_ISNULL)
 
#define JBE_ISBOOL_TRUE(je_)   (((je_) & JENTRY_TYPEMASK) == JENTRY_ISBOOL_TRUE)
 
#define JBE_ISBOOL_FALSE(je_)   (((je_) & JENTRY_TYPEMASK) == JENTRY_ISBOOL_FALSE)
 
#define JBE_ISBOOL(je_)   (JBE_ISBOOL_TRUE(je_) || JBE_ISBOOL_FALSE(je_))
 
#define JBE_ADVANCE_OFFSET(offset, je)
 
#define JB_OFFSET_STRIDE   32
 
#define JB_CMASK   0x0FFFFFFF /* mask for count field */
 
#define JB_FSCALAR   0x10000000 /* flag bits */
 
#define JB_FOBJECT   0x20000000
 
#define JB_FARRAY   0x40000000
 
#define JsonContainerSize(jc)   ((jc)->header & JB_CMASK)
 
#define JsonContainerIsScalar(jc)   (((jc)->header & JB_FSCALAR) != 0)
 
#define JsonContainerIsObject(jc)   (((jc)->header & JB_FOBJECT) != 0)
 
#define JsonContainerIsArray(jc)   (((jc)->header & JB_FARRAY) != 0)
 
#define JB_ROOT_COUNT(jbp_)   (*(uint32 *) VARDATA(jbp_) & JB_CMASK)
 
#define JB_ROOT_IS_SCALAR(jbp_)   ((*(uint32 *) VARDATA(jbp_) & JB_FSCALAR) != 0)
 
#define JB_ROOT_IS_OBJECT(jbp_)   ((*(uint32 *) VARDATA(jbp_) & JB_FOBJECT) != 0)
 
#define JB_ROOT_IS_ARRAY(jbp_)   ((*(uint32 *) VARDATA(jbp_) & JB_FARRAY) != 0)
 
#define IsAJsonbScalar(jsonbval)
 

Typedefs

typedef struct JsonbPair JsonbPair
 
typedef struct JsonbValue JsonbValue
 
typedef uint32 JEntry
 
typedef struct JsonbContainer JsonbContainer
 
typedef struct JsonbParseState JsonbParseState
 
typedef struct JsonbIterator JsonbIterator
 

Enumerations

enum  JsonbIteratorToken {
  WJB_DONE, WJB_KEY, WJB_VALUE, WJB_ELEM,
  WJB_BEGIN_ARRAY, WJB_END_ARRAY, WJB_BEGIN_OBJECT, WJB_END_OBJECT
}
 
enum  jbvType {
  jbvNull = 0x0, jbvString, jbvNumeric, jbvBool,
  jbvArray = 0x10, jbvObject, jbvBinary
}
 
enum  JsonbIterState {
  JBI_ARRAY_START, JBI_ARRAY_ELEM, JBI_OBJECT_START, JBI_OBJECT_KEY,
  JBI_OBJECT_VALUE
}
 

Functions

uint32 getJsonbOffset (const JsonbContainer *jc, int index)
 
uint32 getJsonbLength (const JsonbContainer *jc, int index)
 
int compareJsonbContainers (JsonbContainer *a, JsonbContainer *b)
 
JsonbValuefindJsonbValueFromContainer (JsonbContainer *sheader, uint32 flags, JsonbValue *key)
 
JsonbValuegetKeyJsonValueFromContainer (JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
 
JsonbValuegetIthJsonbValueFromContainer (JsonbContainer *sheader, uint32 i)
 
JsonbValuepushJsonbValue (JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
 
JsonbIteratorJsonbIteratorInit (JsonbContainer *container)
 
JsonbIteratorToken JsonbIteratorNext (JsonbIterator **it, JsonbValue *val, bool skipNested)
 
JsonbJsonbValueToJsonb (JsonbValue *val)
 
bool JsonbDeepContains (JsonbIterator **val, JsonbIterator **mContained)
 
void JsonbHashScalarValue (const JsonbValue *scalarVal, uint32 *hash)
 
void JsonbHashScalarValueExtended (const JsonbValue *scalarVal, uint64 *hash, uint64 seed)
 
char * JsonbToCString (StringInfo out, JsonbContainer *in, int estimated_len)
 
char * JsonbToCStringIndent (StringInfo out, JsonbContainer *in, int estimated_len)
 
bool JsonbExtractScalar (JsonbContainer *jbc, JsonbValue *res)
 
const char * JsonbTypeName (JsonbValue *jb)
 

Macro Definition Documentation

◆ DatumGetJsonbP

#define DatumGetJsonbP (   d)    ((Jsonb *) PG_DETOAST_DATUM(d))

Definition at line 71 of file jsonb.h.

Referenced by datum_to_jsonb().

◆ DatumGetJsonbPCopy

#define DatumGetJsonbPCopy (   d)    ((Jsonb *) PG_DETOAST_DATUM_COPY(d))

Definition at line 72 of file jsonb.h.

◆ IsAJsonbScalar

#define IsAJsonbScalar (   jsonbval)

◆ JB_CMASK

#define JB_CMASK   0x0FFFFFFF /* mask for count field */

Definition at line 208 of file jsonb.h.

◆ JB_FARRAY

◆ JB_FOBJECT

◆ JB_FSCALAR

#define JB_FSCALAR   0x10000000 /* flag bits */

Definition at line 209 of file jsonb.h.

Referenced by convertJsonbArray().

◆ JB_OFFSET_STRIDE

#define JB_OFFSET_STRIDE   32

Definition at line 186 of file jsonb.h.

Referenced by convertJsonbArray(), and convertJsonbObject().

◆ JB_ROOT_COUNT

◆ JB_ROOT_IS_ARRAY

#define JB_ROOT_IS_ARRAY (   jbp_)    ((*(uint32 *) VARDATA(jbp_) & JB_FARRAY) != 0)

◆ JB_ROOT_IS_OBJECT

#define JB_ROOT_IS_OBJECT (   jbp_)    ((*(uint32 *) VARDATA(jbp_) & JB_FOBJECT) != 0)

◆ JB_ROOT_IS_SCALAR

◆ JBE_ADVANCE_OFFSET

#define JBE_ADVANCE_OFFSET (   offset,
  je 
)
Value:
do { \
JEntry je_ = (je); \
if (JBE_HAS_OFF(je_)) \
(offset) = JBE_OFFLENFLD(je_); \
else \
(offset) += JBE_OFFLENFLD(je_); \
} while(0)
#define JBE_OFFLENFLD(je_)
Definition: jsonb.h:159
#define JBE_HAS_OFF(je_)
Definition: jsonb.h:160

Definition at line 170 of file jsonb.h.

Referenced by findJsonbValueFromContainer(), and JsonbIteratorNext().

◆ JBE_HAS_OFF

#define JBE_HAS_OFF (   je_)    (((je_) & JENTRY_HAS_OFF) != 0)

Definition at line 160 of file jsonb.h.

Referenced by getJsonbLength(), and getJsonbOffset().

◆ JBE_ISBOOL

#define JBE_ISBOOL (   je_)    (JBE_ISBOOL_TRUE(je_) || JBE_ISBOOL_FALSE(je_))

Definition at line 167 of file jsonb.h.

◆ JBE_ISBOOL_FALSE

#define JBE_ISBOOL_FALSE (   je_)    (((je_) & JENTRY_TYPEMASK) == JENTRY_ISBOOL_FALSE)

Definition at line 166 of file jsonb.h.

Referenced by fillJsonbValue().

◆ JBE_ISBOOL_TRUE

#define JBE_ISBOOL_TRUE (   je_)    (((je_) & JENTRY_TYPEMASK) == JENTRY_ISBOOL_TRUE)

Definition at line 165 of file jsonb.h.

Referenced by fillJsonbValue().

◆ JBE_ISCONTAINER

#define JBE_ISCONTAINER (   je_)    (((je_) & JENTRY_TYPEMASK) == JENTRY_ISCONTAINER)

Definition at line 163 of file jsonb.h.

Referenced by fillJsonbValue().

◆ JBE_ISNULL

#define JBE_ISNULL (   je_)    (((je_) & JENTRY_TYPEMASK) == JENTRY_ISNULL)

Definition at line 164 of file jsonb.h.

Referenced by fillJsonbValue().

◆ JBE_ISNUMERIC

#define JBE_ISNUMERIC (   je_)    (((je_) & JENTRY_TYPEMASK) == JENTRY_ISNUMERIC)

Definition at line 162 of file jsonb.h.

Referenced by fillJsonbValue().

◆ JBE_ISSTRING

#define JBE_ISSTRING (   je_)    (((je_) & JENTRY_TYPEMASK) == JENTRY_ISSTRING)

Definition at line 161 of file jsonb.h.

Referenced by fillJsonbValue().

◆ JBE_OFFLENFLD

#define JBE_OFFLENFLD (   je_)    ((je_) & JENTRY_OFFLENMASK)

Definition at line 159 of file jsonb.h.

Referenced by convertJsonbArray(), convertJsonbObject(), getJsonbLength(), and getJsonbOffset().

◆ JENTRY_HAS_OFF

#define JENTRY_HAS_OFF   0x80000000

Definition at line 148 of file jsonb.h.

Referenced by convertJsonbArray(), and convertJsonbObject().

◆ JENTRY_ISBOOL_FALSE

#define JENTRY_ISBOOL_FALSE   0x20000000

Definition at line 153 of file jsonb.h.

Referenced by convertJsonbScalar().

◆ JENTRY_ISBOOL_TRUE

#define JENTRY_ISBOOL_TRUE   0x30000000

Definition at line 154 of file jsonb.h.

Referenced by convertJsonbScalar().

◆ JENTRY_ISCONTAINER

#define JENTRY_ISCONTAINER   0x50000000 /* array or object */

Definition at line 156 of file jsonb.h.

Referenced by convertJsonbArray(), and convertJsonbObject().

◆ JENTRY_ISNULL

#define JENTRY_ISNULL   0x40000000

Definition at line 155 of file jsonb.h.

Referenced by convertJsonbScalar().

◆ JENTRY_ISNUMERIC

#define JENTRY_ISNUMERIC   0x10000000

Definition at line 152 of file jsonb.h.

Referenced by convertJsonbScalar().

◆ JENTRY_ISSTRING

#define JENTRY_ISSTRING   0x00000000

Definition at line 151 of file jsonb.h.

◆ JENTRY_OFFLENMASK

#define JENTRY_OFFLENMASK   0x0FFFFFFF

Definition at line 146 of file jsonb.h.

Referenced by checkStringLen(), convertJsonbArray(), and convertJsonbObject().

◆ JENTRY_TYPEMASK

#define JENTRY_TYPEMASK   0x70000000

Definition at line 147 of file jsonb.h.

Referenced by convertJsonbArray(), and convertJsonbObject().

◆ JGIN_MAXLENGTH

#define JGIN_MAXLENGTH   125 /* max length of text part before hashing */

Definition at line 68 of file jsonb.h.

Referenced by make_text_key().

◆ JGINFLAG_BOOL

#define JGINFLAG_BOOL   0x03 /* boolean value */

Definition at line 64 of file jsonb.h.

Referenced by make_scalar_key().

◆ JGINFLAG_HASHED

#define JGINFLAG_HASHED   0x10 /* OR'd into flag if value was hashed */

Definition at line 67 of file jsonb.h.

Referenced by make_text_key().

◆ JGINFLAG_KEY

#define JGINFLAG_KEY   0x01 /* key (or string array element) */

Definition at line 62 of file jsonb.h.

Referenced by gin_extract_jsonb_query(), jsonb_ops__add_path_item(), and make_scalar_key().

◆ JGINFLAG_NULL

#define JGINFLAG_NULL   0x02 /* null value */

Definition at line 63 of file jsonb.h.

Referenced by make_scalar_key().

◆ JGINFLAG_NUM

#define JGINFLAG_NUM   0x04 /* numeric value */

Definition at line 65 of file jsonb.h.

Referenced by make_scalar_key().

◆ JGINFLAG_STR

#define JGINFLAG_STR   0x05 /* string value (if not an array element) */

Definition at line 66 of file jsonb.h.

Referenced by make_scalar_key().

◆ JsonbContainsStrategyNumber

◆ JsonbExistsAllStrategyNumber

#define JsonbExistsAllStrategyNumber   11

Definition at line 36 of file jsonb.h.

Referenced by gin_consistent_jsonb(), gin_extract_jsonb_query(), and gin_triconsistent_jsonb().

◆ JsonbExistsAnyStrategyNumber

#define JsonbExistsAnyStrategyNumber   10

Definition at line 35 of file jsonb.h.

Referenced by gin_consistent_jsonb(), gin_extract_jsonb_query(), and gin_triconsistent_jsonb().

◆ JsonbExistsStrategyNumber

#define JsonbExistsStrategyNumber   9

Definition at line 34 of file jsonb.h.

Referenced by gin_consistent_jsonb(), gin_extract_jsonb_query(), and gin_triconsistent_jsonb().

◆ JsonbJsonpathExistsStrategyNumber

◆ JsonbJsonpathPredicateStrategyNumber

#define JsonbJsonpathPredicateStrategyNumber   16

◆ JsonbPGetDatum

#define JsonbPGetDatum (   p)    PointerGetDatum(p)

Definition at line 73 of file jsonb.h.

Referenced by jsonb_path_query(), and populate_scalar().

◆ JsonContainerIsArray

◆ JsonContainerIsObject

◆ JsonContainerIsScalar

#define JsonContainerIsScalar (   jc)    (((jc)->header & JB_FSCALAR) != 0)

◆ JsonContainerSize

◆ PG_GETARG_JSONB_P

◆ PG_GETARG_JSONB_P_COPY

#define PG_GETARG_JSONB_P_COPY (   x)    DatumGetJsonbPCopy(PG_GETARG_DATUM(x))

Definition at line 75 of file jsonb.h.

Referenced by jsonb_path_query().

◆ PG_RETURN_JSONB_P

Typedef Documentation

◆ JEntry

typedef uint32 JEntry

Definition at line 144 of file jsonb.h.

◆ JsonbContainer

◆ JsonbIterator

typedef struct JsonbIterator JsonbIterator

◆ JsonbPair

typedef struct JsonbPair JsonbPair

Definition at line 78 of file jsonb.h.

◆ JsonbParseState

◆ JsonbValue

typedef struct JsonbValue JsonbValue

Definition at line 79 of file jsonb.h.

Enumeration Type Documentation

◆ jbvType

enum jbvType
Enumerator
jbvNull 
jbvString 
jbvNumeric 
jbvBool 
jbvArray 
jbvObject 
jbvBinary 

Definition at line 233 of file jsonb.h.

234 {
235  /* Scalar types */
236  jbvNull = 0x0,
237  jbvString,
238  jbvNumeric,
239  jbvBool,
240  /* Composite types */
241  jbvArray = 0x10,
242  jbvObject,
243  /* Binary (i.e. struct Jsonb) jbvArray/jbvObject */
244  jbvBinary
245 };
Definition: jsonb.h:239
Definition: jsonb.h:236

◆ JsonbIteratorToken

Enumerator
WJB_DONE 
WJB_KEY 
WJB_VALUE 
WJB_ELEM 
WJB_BEGIN_ARRAY 
WJB_END_ARRAY 
WJB_BEGIN_OBJECT 
WJB_END_OBJECT 

Definition at line 20 of file jsonb.h.

21 {
22  WJB_DONE,
23  WJB_KEY,
24  WJB_VALUE,
25  WJB_ELEM,
Definition: jsonb.h:22
Definition: jsonb.h:23
JsonbIteratorToken
Definition: jsonb.h:20
Definition: jsonb.h:25

◆ JsonbIterState

Enumerator
JBI_ARRAY_START 
JBI_ARRAY_ELEM 
JBI_OBJECT_START 
JBI_OBJECT_KEY 
JBI_OBJECT_VALUE 

Definition at line 320 of file jsonb.h.

Function Documentation

◆ compareJsonbContainers()

int compareJsonbContainers ( JsonbContainer a,
JsonbContainer b 
)

Definition at line 180 of file jsonb_util.c.

References Assert, compareJsonbScalarValue(), elog, ERROR, i, jbvArray, jbvBinary, jbvBool, jbvNull, jbvNumeric, jbvObject, jbvString, JsonbIteratorInit(), JsonbIteratorNext(), JsonbIterator::parent, pfree(), JsonbValue::type, JsonbValue::val, WJB_DONE, WJB_END_ARRAY, and WJB_END_OBJECT.

Referenced by jsonb_cmp(), jsonb_eq(), jsonb_ge(), jsonb_gt(), jsonb_le(), jsonb_lt(), and jsonb_ne().

181 {
182  JsonbIterator *ita,
183  *itb;
184  int res = 0;
185 
186  ita = JsonbIteratorInit(a);
187  itb = JsonbIteratorInit(b);
188 
189  do
190  {
191  JsonbValue va,
192  vb;
194  rb;
195 
196  ra = JsonbIteratorNext(&ita, &va, false);
197  rb = JsonbIteratorNext(&itb, &vb, false);
198 
199  if (ra == rb)
200  {
201  if (ra == WJB_DONE)
202  {
203  /* Decisively equal */
204  break;
205  }
206 
207  if (ra == WJB_END_ARRAY || ra == WJB_END_OBJECT)
208  {
209  /*
210  * There is no array or object to compare at this stage of
211  * processing. jbvArray/jbvObject values are compared
212  * initially, at the WJB_BEGIN_ARRAY and WJB_BEGIN_OBJECT
213  * tokens.
214  */
215  continue;
216  }
217 
218  if (va.type == vb.type)
219  {
220  switch (va.type)
221  {
222  case jbvString:
223  case jbvNull:
224  case jbvNumeric:
225  case jbvBool:
226  res = compareJsonbScalarValue(&va, &vb);
227  break;
228  case jbvArray:
229 
230  /*
231  * This could be a "raw scalar" pseudo array. That's
232  * a special case here though, since we still want the
233  * general type-based comparisons to apply, and as far
234  * as we're concerned a pseudo array is just a scalar.
235  */
236  if (va.val.array.rawScalar != vb.val.array.rawScalar)
237  res = (va.val.array.rawScalar) ? -1 : 1;
238  if (va.val.array.nElems != vb.val.array.nElems)
239  res = (va.val.array.nElems > vb.val.array.nElems) ? 1 : -1;
240  break;
241  case jbvObject:
242  if (va.val.object.nPairs != vb.val.object.nPairs)
243  res = (va.val.object.nPairs > vb.val.object.nPairs) ? 1 : -1;
244  break;
245  case jbvBinary:
246  elog(ERROR, "unexpected jbvBinary value");
247  }
248  }
249  else
250  {
251  /* Type-defined order */
252  res = (va.type > vb.type) ? 1 : -1;
253  }
254  }
255  else
256  {
257  /*
258  * It's safe to assume that the types differed, and that the va
259  * and vb values passed were set.
260  *
261  * If the two values were of the same container type, then there'd
262  * have been a chance to observe the variation in the number of
263  * elements/pairs (when processing WJB_BEGIN_OBJECT, say). They're
264  * either two heterogeneously-typed containers, or a container and
265  * some scalar type.
266  *
267  * We don't have to consider the WJB_END_ARRAY and WJB_END_OBJECT
268  * cases here, because we would have seen the corresponding
269  * WJB_BEGIN_ARRAY and WJB_BEGIN_OBJECT tokens first, and
270  * concluded that they don't match.
271  */
272  Assert(ra != WJB_END_ARRAY && ra != WJB_END_OBJECT);
273  Assert(rb != WJB_END_ARRAY && rb != WJB_END_OBJECT);
274 
275  Assert(va.type != vb.type);
276  Assert(va.type != jbvBinary);
277  Assert(vb.type != jbvBinary);
278  /* Type-defined order */
279  res = (va.type > vb.type) ? 1 : -1;
280  }
281  }
282  while (res == 0);
283 
284  while (ita != NULL)
285  {
286  JsonbIterator *i = ita->parent;
287 
288  pfree(ita);
289  ita = i;
290  }
291  while (itb != NULL)
292  {
293  JsonbIterator *i = itb->parent;
294 
295  pfree(itb);
296  itb = i;
297  }
298 
299  return res;
300 }
char * val
Definition: jsonb.h:264
Definition: jsonb.h:239
Definition: jsonb.h:22
Definition: jsonb.h:236
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ERROR
Definition: elog.h:43
JsonbIteratorToken
Definition: jsonb.h:20
static int compareJsonbScalarValue(JsonbValue *a, JsonbValue *b)
Definition: jsonb_util.c:1368
#define Assert(condition)
Definition: c.h:732
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:752
struct JsonbIterator * parent
Definition: jsonb.h:356
enum jbvType type
Definition: jsonb.h:255
#define elog(elevel,...)
Definition: elog.h:226
int i
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:788

◆ findJsonbValueFromContainer()

JsonbValue* findJsonbValueFromContainer ( JsonbContainer sheader,
uint32  flags,
JsonbValue key 
)

Definition at line 329 of file jsonb_util.c.

References Assert, JsonbContainer::children, equalsJsonbScalarValue(), fillJsonbValue(), getKeyJsonValueFromContainer(), i, JB_FARRAY, JB_FOBJECT, JBE_ADVANCE_OFFSET, jbvString, JsonContainerIsArray, JsonContainerIsObject, JsonContainerSize, palloc(), pfree(), JsonbValue::type, and JsonbValue::val.

Referenced by executeItemOptUnwrapTarget(), getJsonPathVariable(), jsonb_exists(), jsonb_exists_all(), jsonb_exists_any(), and JsonbDeepContains().

331 {
332  JEntry *children = container->children;
333  int count = JsonContainerSize(container);
334 
335  Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
336 
337  /* Quick out without a palloc cycle if object/array is empty */
338  if (count <= 0)
339  return NULL;
340 
341  if ((flags & JB_FARRAY) && JsonContainerIsArray(container))
342  {
343  JsonbValue *result = palloc(sizeof(JsonbValue));
344  char *base_addr = (char *) (children + count);
345  uint32 offset = 0;
346  int i;
347 
348  for (i = 0; i < count; i++)
349  {
350  fillJsonbValue(container, i, base_addr, offset, result);
351 
352  if (key->type == result->type)
353  {
354  if (equalsJsonbScalarValue(key, result))
355  return result;
356  }
357 
358  JBE_ADVANCE_OFFSET(offset, children[i]);
359  }
360 
361  pfree(result);
362  }
363  else if ((flags & JB_FOBJECT) && JsonContainerIsObject(container))
364  {
365  /* Object key passed by caller must be a string */
366  Assert(key->type == jbvString);
367 
368  return getKeyJsonValueFromContainer(container, key->val.string.val,
369  key->val.string.len, NULL);
370  }
371 
372  /* Not found */
373  return NULL;
374 }
#define JB_FARRAY
Definition: jsonb.h:211
char * val
Definition: jsonb.h:264
JsonbValue * getKeyJsonValueFromContainer(JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
Definition: jsonb_util.c:383
#define JBE_ADVANCE_OFFSET(offset, je)
Definition: jsonb.h:170
void pfree(void *pointer)
Definition: mcxt.c:1031
#define JsonContainerSize(jc)
Definition: jsonb.h:214
unsigned int uint32
Definition: c.h:358
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition: jsonb_util.c:490
#define JsonContainerIsArray(jc)
Definition: jsonb.h:217
static bool equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b)
Definition: jsonb_util.c:1336
#define JsonContainerIsObject(jc)
Definition: jsonb.h:216
#define Assert(condition)
Definition: c.h:732
#define JB_FOBJECT
Definition: jsonb.h:210
uint32 JEntry
Definition: jsonb.h:144
enum jbvType type
Definition: jsonb.h:255
void * palloc(Size size)
Definition: mcxt.c:924
int i

◆ getIthJsonbValueFromContainer()

JsonbValue* getIthJsonbValueFromContainer ( JsonbContainer sheader,
uint32  i 
)

Definition at line 453 of file jsonb_util.c.

References JsonbContainer::children, elog, ERROR, fillJsonbValue(), getJsonbOffset(), JsonContainerIsArray, JsonContainerSize, and palloc().

Referenced by executeItemOptUnwrapTarget(), get_jsonb_path_all(), jsonb_array_element(), and jsonb_array_element_text().

454 {
455  JsonbValue *result;
456  char *base_addr;
457  uint32 nelements;
458 
459  if (!JsonContainerIsArray(container))
460  elog(ERROR, "not a jsonb array");
461 
462  nelements = JsonContainerSize(container);
463  base_addr = (char *) &container->children[nelements];
464 
465  if (i >= nelements)
466  return NULL;
467 
468  result = palloc(sizeof(JsonbValue));
469 
470  fillJsonbValue(container, i, base_addr,
471  getJsonbOffset(container, i),
472  result);
473 
474  return result;
475 }
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:123
#define ERROR
Definition: elog.h:43
#define JsonContainerSize(jc)
Definition: jsonb.h:214
unsigned int uint32
Definition: c.h:358
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition: jsonb_util.c:490
#define JsonContainerIsArray(jc)
Definition: jsonb.h:217
void * palloc(Size size)
Definition: mcxt.c:924
#define elog(elevel,...)
Definition: elog.h:226
int i

◆ getJsonbLength()

uint32 getJsonbLength ( const JsonbContainer jc,
int  index 
)

Definition at line 148 of file jsonb_util.c.

References JsonbContainer::children, getJsonbOffset(), JBE_HAS_OFF, and JBE_OFFLENFLD.

Referenced by fillJsonbValue(), and getKeyJsonValueFromContainer().

149 {
150  uint32 off;
151  uint32 len;
152 
153  /*
154  * If the length is stored directly in the JEntry, just return it.
155  * Otherwise, get the begin offset of the entry, and subtract that from
156  * the stored end+1 offset.
157  */
158  if (JBE_HAS_OFF(jc->children[index]))
159  {
160  off = getJsonbOffset(jc, index);
161  len = JBE_OFFLENFLD(jc->children[index]) - off;
162  }
163  else
164  len = JBE_OFFLENFLD(jc->children[index]);
165 
166  return len;
167 }
JEntry children[FLEXIBLE_ARRAY_MEMBER]
Definition: jsonb.h:202
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:123
#define JBE_OFFLENFLD(je_)
Definition: jsonb.h:159
Definition: type.h:89
unsigned int uint32
Definition: c.h:358
#define JBE_HAS_OFF(je_)
Definition: jsonb.h:160

◆ getJsonbOffset()

uint32 getJsonbOffset ( const JsonbContainer jc,
int  index 
)

Definition at line 123 of file jsonb_util.c.

References JsonbContainer::children, i, JBE_HAS_OFF, and JBE_OFFLENFLD.

Referenced by getIthJsonbValueFromContainer(), getJsonbLength(), getKeyJsonValueFromContainer(), and JsonbIteratorNext().

124 {
125  uint32 offset = 0;
126  int i;
127 
128  /*
129  * Start offset of this entry is equal to the end offset of the previous
130  * entry. Walk backwards to the most recent entry stored as an end
131  * offset, returning that offset plus any lengths in between.
132  */
133  for (i = index - 1; i >= 0; i--)
134  {
135  offset += JBE_OFFLENFLD(jc->children[i]);
136  if (JBE_HAS_OFF(jc->children[i]))
137  break;
138  }
139 
140  return offset;
141 }
JEntry children[FLEXIBLE_ARRAY_MEMBER]
Definition: jsonb.h:202
#define JBE_OFFLENFLD(je_)
Definition: jsonb.h:159
Definition: type.h:89
unsigned int uint32
Definition: c.h:358
#define JBE_HAS_OFF(je_)
Definition: jsonb.h:160
int i

◆ getKeyJsonValueFromContainer()

JsonbValue* getKeyJsonValueFromContainer ( JsonbContainer container,
const char *  keyVal,
int  keyLen,
JsonbValue res 
)

Definition at line 383 of file jsonb_util.c.

References Assert, JsonbContainer::children, difference(), fillJsonbValue(), getJsonbLength(), getJsonbOffset(), JsonContainerIsObject, JsonContainerSize, lengthCompareJsonbString(), and palloc().

Referenced by findJsonbValueFromContainer(), get_jsonb_path_all(), JsObjectGetField(), jsonb_object_field(), jsonb_object_field_text(), and JsonbDeepContains().

385 {
386  JEntry *children = container->children;
387  int count = JsonContainerSize(container);
388  char *baseAddr;
389  uint32 stopLow,
390  stopHigh;
391 
392  Assert(JsonContainerIsObject(container));
393 
394  /* Quick out without a palloc cycle if object is empty */
395  if (count <= 0)
396  return NULL;
397 
398  /*
399  * Binary search the container. Since we know this is an object, account
400  * for *Pairs* of Jentrys
401  */
402  baseAddr = (char *) (children + count * 2);
403  stopLow = 0;
404  stopHigh = count;
405  while (stopLow < stopHigh)
406  {
407  uint32 stopMiddle;
408  int difference;
409  const char *candidateVal;
410  int candidateLen;
411 
412  stopMiddle = stopLow + (stopHigh - stopLow) / 2;
413 
414  candidateVal = baseAddr + getJsonbOffset(container, stopMiddle);
415  candidateLen = getJsonbLength(container, stopMiddle);
416 
417  difference = lengthCompareJsonbString(candidateVal, candidateLen,
418  keyVal, keyLen);
419 
420  if (difference == 0)
421  {
422  /* Found our key, return corresponding value */
423  int index = stopMiddle + count;
424 
425  if (!res)
426  res = palloc(sizeof(JsonbValue));
427 
428  fillJsonbValue(container, index, baseAddr,
429  getJsonbOffset(container, index),
430  res);
431 
432  return res;
433  }
434  else
435  {
436  if (difference < 0)
437  stopLow = stopMiddle + 1;
438  else
439  stopHigh = stopMiddle;
440  }
441  }
442 
443  /* Not found */
444  return NULL;
445 }
JEntry children[FLEXIBLE_ARRAY_MEMBER]
Definition: jsonb.h:202
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:123
uint32 getJsonbLength(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:148
static int lengthCompareJsonbString(const char *val1, int len1, const char *val2, int len2)
Definition: jsonb_util.c:1826
Definition: type.h:89
#define JsonContainerSize(jc)
Definition: jsonb.h:214
unsigned int uint32
Definition: c.h:358
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition: jsonb_util.c:490
#define JsonContainerIsObject(jc)
Definition: jsonb.h:216
Datum difference(PG_FUNCTION_ARGS)
#define Assert(condition)
Definition: c.h:732
uint32 JEntry
Definition: jsonb.h:144
void * palloc(Size size)
Definition: mcxt.c:924

◆ JsonbDeepContains()

bool JsonbDeepContains ( JsonbIterator **  val,
JsonbIterator **  mContained 
)

Definition at line 997 of file jsonb_util.c.

References Assert, check_stack_depth(), elog, equalsJsonbScalarValue(), ERROR, findJsonbValueFromContainer(), getKeyJsonValueFromContainer(), i, IsAJsonbScalar, JB_FARRAY, jbvArray, jbvBinary, jbvObject, jbvString, JsonbDeepContains(), JsonbIteratorInit(), JsonbIteratorNext(), palloc(), pfree(), JsonbValue::type, JsonbValue::val, WJB_BEGIN_ARRAY, WJB_BEGIN_OBJECT, WJB_ELEM, WJB_END_ARRAY, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

Referenced by jsonb_contained(), jsonb_contains(), and JsonbDeepContains().

998 {
999  JsonbValue vval,
1000  vcontained;
1001  JsonbIteratorToken rval,
1002  rcont;
1003 
1004  /*
1005  * Guard against stack overflow due to overly complex Jsonb.
1006  *
1007  * Functions called here independently take this precaution, but that
1008  * might not be sufficient since this is also a recursive function.
1009  */
1011 
1012  rval = JsonbIteratorNext(val, &vval, false);
1013  rcont = JsonbIteratorNext(mContained, &vcontained, false);
1014 
1015  if (rval != rcont)
1016  {
1017  /*
1018  * The differing return values can immediately be taken as indicating
1019  * two differing container types at this nesting level, which is
1020  * sufficient reason to give up entirely (but it should be the case
1021  * that they're both some container type).
1022  */
1023  Assert(rval == WJB_BEGIN_OBJECT || rval == WJB_BEGIN_ARRAY);
1024  Assert(rcont == WJB_BEGIN_OBJECT || rcont == WJB_BEGIN_ARRAY);
1025  return false;
1026  }
1027  else if (rcont == WJB_BEGIN_OBJECT)
1028  {
1029  Assert(vval.type == jbvObject);
1030  Assert(vcontained.type == jbvObject);
1031 
1032  /*
1033  * If the lhs has fewer pairs than the rhs, it can't possibly contain
1034  * the rhs. (This conclusion is safe only because we de-duplicate
1035  * keys in all Jsonb objects; thus there can be no corresponding
1036  * optimization in the array case.) The case probably won't arise
1037  * often, but since it's such a cheap check we may as well make it.
1038  */
1039  if (vval.val.object.nPairs < vcontained.val.object.nPairs)
1040  return false;
1041 
1042  /* Work through rhs "is it contained within?" object */
1043  for (;;)
1044  {
1045  JsonbValue *lhsVal; /* lhsVal is from pair in lhs object */
1046  JsonbValue lhsValBuf;
1047 
1048  rcont = JsonbIteratorNext(mContained, &vcontained, false);
1049 
1050  /*
1051  * When we get through caller's rhs "is it contained within?"
1052  * object without failing to find one of its values, it's
1053  * contained.
1054  */
1055  if (rcont == WJB_END_OBJECT)
1056  return true;
1057 
1058  Assert(rcont == WJB_KEY);
1059  Assert(vcontained.type == jbvString);
1060 
1061  /* First, find value by key... */
1062  lhsVal =
1063  getKeyJsonValueFromContainer((*val)->container,
1064  vcontained.val.string.val,
1065  vcontained.val.string.len,
1066  &lhsValBuf);
1067  if (!lhsVal)
1068  return false;
1069 
1070  /*
1071  * ...at this stage it is apparent that there is at least a key
1072  * match for this rhs pair.
1073  */
1074  rcont = JsonbIteratorNext(mContained, &vcontained, true);
1075 
1076  Assert(rcont == WJB_VALUE);
1077 
1078  /*
1079  * Compare rhs pair's value with lhs pair's value just found using
1080  * key
1081  */
1082  if (lhsVal->type != vcontained.type)
1083  {
1084  return false;
1085  }
1086  else if (IsAJsonbScalar(lhsVal))
1087  {
1088  if (!equalsJsonbScalarValue(lhsVal, &vcontained))
1089  return false;
1090  }
1091  else
1092  {
1093  /* Nested container value (object or array) */
1094  JsonbIterator *nestval,
1095  *nestContained;
1096 
1097  Assert(lhsVal->type == jbvBinary);
1098  Assert(vcontained.type == jbvBinary);
1099 
1100  nestval = JsonbIteratorInit(lhsVal->val.binary.data);
1101  nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1102 
1103  /*
1104  * Match "value" side of rhs datum object's pair recursively.
1105  * It's a nested structure.
1106  *
1107  * Note that nesting still has to "match up" at the right
1108  * nesting sub-levels. However, there need only be zero or
1109  * more matching pairs (or elements) at each nesting level
1110  * (provided the *rhs* pairs/elements *all* match on each
1111  * level), which enables searching nested structures for a
1112  * single String or other primitive type sub-datum quite
1113  * effectively (provided the user constructed the rhs nested
1114  * structure such that we "know where to look").
1115  *
1116  * In other words, the mapping of container nodes in the rhs
1117  * "vcontained" Jsonb to internal nodes on the lhs is
1118  * injective, and parent-child edges on the rhs must be mapped
1119  * to parent-child edges on the lhs to satisfy the condition
1120  * of containment (plus of course the mapped nodes must be
1121  * equal).
1122  */
1123  if (!JsonbDeepContains(&nestval, &nestContained))
1124  return false;
1125  }
1126  }
1127  }
1128  else if (rcont == WJB_BEGIN_ARRAY)
1129  {
1130  JsonbValue *lhsConts = NULL;
1131  uint32 nLhsElems = vval.val.array.nElems;
1132 
1133  Assert(vval.type == jbvArray);
1134  Assert(vcontained.type == jbvArray);
1135 
1136  /*
1137  * Handle distinction between "raw scalar" pseudo arrays, and real
1138  * arrays.
1139  *
1140  * A raw scalar may contain another raw scalar, and an array may
1141  * contain a raw scalar, but a raw scalar may not contain an array. We
1142  * don't do something like this for the object case, since objects can
1143  * only contain pairs, never raw scalars (a pair is represented by an
1144  * rhs object argument with a single contained pair).
1145  */
1146  if (vval.val.array.rawScalar && !vcontained.val.array.rawScalar)
1147  return false;
1148 
1149  /* Work through rhs "is it contained within?" array */
1150  for (;;)
1151  {
1152  rcont = JsonbIteratorNext(mContained, &vcontained, true);
1153 
1154  /*
1155  * When we get through caller's rhs "is it contained within?"
1156  * array without failing to find one of its values, it's
1157  * contained.
1158  */
1159  if (rcont == WJB_END_ARRAY)
1160  return true;
1161 
1162  Assert(rcont == WJB_ELEM);
1163 
1164  if (IsAJsonbScalar(&vcontained))
1165  {
1166  if (!findJsonbValueFromContainer((*val)->container,
1167  JB_FARRAY,
1168  &vcontained))
1169  return false;
1170  }
1171  else
1172  {
1173  uint32 i;
1174 
1175  /*
1176  * If this is first container found in rhs array (at this
1177  * depth), initialize temp lhs array of containers
1178  */
1179  if (lhsConts == NULL)
1180  {
1181  uint32 j = 0;
1182 
1183  /* Make room for all possible values */
1184  lhsConts = palloc(sizeof(JsonbValue) * nLhsElems);
1185 
1186  for (i = 0; i < nLhsElems; i++)
1187  {
1188  /* Store all lhs elements in temp array */
1189  rcont = JsonbIteratorNext(val, &vval, true);
1190  Assert(rcont == WJB_ELEM);
1191 
1192  if (vval.type == jbvBinary)
1193  lhsConts[j++] = vval;
1194  }
1195 
1196  /* No container elements in temp array, so give up now */
1197  if (j == 0)
1198  return false;
1199 
1200  /* We may have only partially filled array */
1201  nLhsElems = j;
1202  }
1203 
1204  /* XXX: Nested array containment is O(N^2) */
1205  for (i = 0; i < nLhsElems; i++)
1206  {
1207  /* Nested container value (object or array) */
1208  JsonbIterator *nestval,
1209  *nestContained;
1210  bool contains;
1211 
1212  nestval = JsonbIteratorInit(lhsConts[i].val.binary.data);
1213  nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1214 
1215  contains = JsonbDeepContains(&nestval, &nestContained);
1216 
1217  if (nestval)
1218  pfree(nestval);
1219  if (nestContained)
1220  pfree(nestContained);
1221  if (contains)
1222  break;
1223  }
1224 
1225  /*
1226  * Report rhs container value is not contained if couldn't
1227  * match rhs container to *some* lhs cont
1228  */
1229  if (i == nLhsElems)
1230  return false;
1231  }
1232  }
1233  }
1234  else
1235  {
1236  elog(ERROR, "invalid jsonb container type");
1237  }
1238 
1239  elog(ERROR, "unexpectedly fell off end of jsonb container");
1240  return false;
1241 }
#define JB_FARRAY
Definition: jsonb.h:211
bool JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
Definition: jsonb_util.c:997
char * val
Definition: jsonb.h:264
JsonbValue * getKeyJsonValueFromContainer(JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
Definition: jsonb_util.c:383
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ERROR
Definition: elog.h:43
void check_stack_depth(void)
Definition: postgres.c:3262
unsigned int uint32
Definition: c.h:358
Definition: jsonb.h:23
static bool equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b)
Definition: jsonb_util.c:1336
JsonbIteratorToken
Definition: jsonb.h:20
#define Assert(condition)
Definition: c.h:732
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:752
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:288
enum jbvType type
Definition: jsonb.h:255
void * palloc(Size size)
Definition: mcxt.c:924
#define elog(elevel,...)
Definition: elog.h:226
int i
JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)
Definition: jsonb_util.c:329
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:788
Definition: jsonb.h:25

◆ JsonbExtractScalar()

bool JsonbExtractScalar ( JsonbContainer jbc,
JsonbValue res 
)

Definition at line 1874 of file jsonb.c.

References Assert, IsAJsonbScalar, jbvArray, jbvObject, JsonbIteratorInit(), JsonbIteratorNext(), JsonContainerIsArray, JsonContainerIsScalar, PG_USED_FOR_ASSERTS_ONLY, JsonbValue::type, JsonbValue::val, WJB_BEGIN_ARRAY, WJB_DONE, WJB_ELEM, and WJB_END_ARRAY.

Referenced by executeJsonPath(), jsonb_bool(), jsonb_float4(), jsonb_float8(), jsonb_int2(), jsonb_int4(), jsonb_int8(), jsonb_numeric(), and JsonbContainerTypeName().

1875 {
1876  JsonbIterator *it;
1878  JsonbValue tmp;
1879 
1880  if (!JsonContainerIsArray(jbc) || !JsonContainerIsScalar(jbc))
1881  {
1882  /* inform caller about actual type of container */
1883  res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
1884  return false;
1885  }
1886 
1887  /*
1888  * A root scalar is stored as an array of one element, so we get the array
1889  * and then its first (and only) member.
1890  */
1891  it = JsonbIteratorInit(jbc);
1892 
1893  tok = JsonbIteratorNext(&it, &tmp, true);
1894  Assert(tok == WJB_BEGIN_ARRAY);
1895  Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
1896 
1897  tok = JsonbIteratorNext(&it, res, true);
1898  Assert(tok == WJB_ELEM);
1899  Assert(IsAJsonbScalar(res));
1900 
1901  tok = JsonbIteratorNext(&it, &tmp, true);
1902  Assert(tok == WJB_END_ARRAY);
1903 
1904  tok = JsonbIteratorNext(&it, &tmp, true);
1905  Assert(tok == WJB_DONE);
1906 
1907  return true;
1908 }
char * val
Definition: jsonb.h:264
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:215
Definition: jsonb.h:22
#define JsonContainerIsArray(jc)
Definition: jsonb.h:217
JsonbIteratorToken
Definition: jsonb.h:20
#define Assert(condition)
Definition: c.h:732
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:752
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:288
enum jbvType type
Definition: jsonb.h:255
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:123
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:788
Definition: jsonb.h:25

◆ JsonbHashScalarValue()

void JsonbHashScalarValue ( const JsonbValue scalarVal,
uint32 hash 
)

Definition at line 1251 of file jsonb_util.c.

References DatumGetUInt32, DirectFunctionCall1, elog, ERROR, hash_any(), hash_numeric(), jbvBool, jbvNull, jbvNumeric, jbvString, NumericGetDatum, JsonbValue::type, and JsonbValue::val.

Referenced by gin_extract_jsonb_path(), jsonb_hash(), jsonb_path_ops__add_path_item(), and jsonb_path_ops__extract_nodes().

1252 {
1253  uint32 tmp;
1254 
1255  /* Compute hash value for scalarVal */
1256  switch (scalarVal->type)
1257  {
1258  case jbvNull:
1259  tmp = 0x01;
1260  break;
1261  case jbvString:
1262  tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->val.string.val,
1263  scalarVal->val.string.len));
1264  break;
1265  case jbvNumeric:
1266  /* Must hash equal numerics to equal hash codes */
1268  NumericGetDatum(scalarVal->val.numeric)));
1269  break;
1270  case jbvBool:
1271  tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1272 
1273  break;
1274  default:
1275  elog(ERROR, "invalid jsonb scalar type");
1276  tmp = 0; /* keep compiler quiet */
1277  break;
1278  }
1279 
1280  /*
1281  * Combine hash values of successive keys, values and elements by rotating
1282  * the previous value left 1 bit, then XOR'ing in the new
1283  * key/value/element's hash value.
1284  */
1285  *hash = (*hash << 1) | (*hash >> 31);
1286  *hash ^= tmp;
1287 }
#define DatumGetUInt32(X)
Definition: postgres.h:486
Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.c:148
Datum hash_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:2259
char * val
Definition: jsonb.h:264
#define NumericGetDatum(X)
Definition: numeric.h:51
Definition: jsonb.h:239
Definition: jsonb.h:236
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
#define ERROR
Definition: elog.h:43
unsigned int uint32
Definition: c.h:358
enum jbvType type
Definition: jsonb.h:255
#define elog(elevel,...)
Definition: elog.h:226
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:541

◆ JsonbHashScalarValueExtended()

void JsonbHashScalarValueExtended ( const JsonbValue scalarVal,
uint64 *  hash,
uint64  seed 
)

Definition at line 1294 of file jsonb_util.c.

References BoolGetDatum, DatumGetUInt64, DirectFunctionCall2, elog, ERROR, hash_any_extended(), hash_numeric_extended(), hashcharextended(), jbvBool, jbvNull, jbvNumeric, jbvString, NumericGetDatum, ROTATE_HIGH_AND_LOW_32BITS, JsonbValue::type, UInt64GetDatum, and JsonbValue::val.

Referenced by jsonb_hash_extended().

1296 {
1297  uint64 tmp;
1298 
1299  switch (scalarVal->type)
1300  {
1301  case jbvNull:
1302  tmp = seed + 0x01;
1303  break;
1304  case jbvString:
1305  tmp = DatumGetUInt64(hash_any_extended((const unsigned char *) scalarVal->val.string.val,
1306  scalarVal->val.string.len,
1307  seed));
1308  break;
1309  case jbvNumeric:
1311  NumericGetDatum(scalarVal->val.numeric),
1312  UInt64GetDatum(seed)));
1313  break;
1314  case jbvBool:
1315  if (seed)
1317  BoolGetDatum(scalarVal->val.boolean),
1318  UInt64GetDatum(seed)));
1319  else
1320  tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1321 
1322  break;
1323  default:
1324  elog(ERROR, "invalid jsonb scalar type");
1325  break;
1326  }
1327 
1329  *hash ^= tmp;
1330 }
Datum hash_numeric_extended(PG_FUNCTION_ARGS)
Definition: numeric.c:2339
#define UInt64GetDatum(X)
Definition: postgres.h:648
char * val
Definition: jsonb.h:264
#define NumericGetDatum(X)
Definition: numeric.h:51
Definition: jsonb.h:239
Definition: jsonb.h:236
Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Definition: hashfn.c:374
#define ERROR
Definition: elog.h:43
#define ROTATE_HIGH_AND_LOW_32BITS(v)
Definition: hashutils.h:18
#define BoolGetDatum(X)
Definition: postgres.h:402
#define DatumGetUInt64(X)
Definition: postgres.h:634
enum jbvType type
Definition: jsonb.h:255
Datum hashcharextended(PG_FUNCTION_ARGS)
Definition: hashfunc.c:53
#define elog(elevel,...)
Definition: elog.h:226
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:541
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:619

◆ JsonbIteratorInit()

◆ JsonbIteratorNext()

JsonbIteratorToken JsonbIteratorNext ( JsonbIterator **  it,
JsonbValue val,
bool  skipNested 
)

Definition at line 788 of file jsonb_util.c.

References elog, ERROR, fillJsonbValue(), freeAndGetParent(), getJsonbOffset(), IsAJsonbScalar, iteratorFromContainer(), JBE_ADVANCE_OFFSET, JBI_ARRAY_ELEM, JBI_ARRAY_START, JBI_OBJECT_KEY, JBI_OBJECT_START, JBI_OBJECT_VALUE, jbvArray, jbvObject, jbvString, JsonbValue::type, JsonbValue::val, WJB_BEGIN_ARRAY, WJB_BEGIN_OBJECT, WJB_DONE, WJB_ELEM, WJB_END_ARRAY, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

Referenced by addJsonbToParseState(), compareJsonbContainers(), datum_to_jsonb(), each_worker_jsonb(), elements_worker_jsonb(), executeAnyItem(), executeKeyValueMethod(), gin_extract_jsonb(), gin_extract_jsonb_path(), iterate_jsonb_values(), IteratorConcat(), jsonb_agg_transfn(), jsonb_delete(), jsonb_delete_array(), jsonb_delete_idx(), jsonb_hash(), jsonb_hash_extended(), jsonb_object_agg_transfn(), jsonb_object_keys(), jsonb_strip_nulls(), Jsonb_to_SV(), JsonbDeepContains(), JsonbExtractScalar(), JsonbToCStringWorker(), parse_jsonb_index_flags(), PLyObject_FromJsonbContainer(), populate_array_dim_jsonb(), populate_recordset_worker(), pushJsonbValue(), setPath(), setPathArray(), setPathObject(), and transform_jsonb_string_values().

789 {
790  if (*it == NULL)
791  return WJB_DONE;
792 
793  /*
794  * When stepping into a nested container, we jump back here to start
795  * processing the child. We will not recurse further in one call, because
796  * processing the child will always begin in JBI_ARRAY_START or
797  * JBI_OBJECT_START state.
798  */
799 recurse:
800  switch ((*it)->state)
801  {
802  case JBI_ARRAY_START:
803  /* Set v to array on first array call */
804  val->type = jbvArray;
805  val->val.array.nElems = (*it)->nElems;
806 
807  /*
808  * v->val.array.elems is not actually set, because we aren't doing
809  * a full conversion
810  */
811  val->val.array.rawScalar = (*it)->isScalar;
812  (*it)->curIndex = 0;
813  (*it)->curDataOffset = 0;
814  (*it)->curValueOffset = 0; /* not actually used */
815  /* Set state for next call */
816  (*it)->state = JBI_ARRAY_ELEM;
817  return WJB_BEGIN_ARRAY;
818 
819  case JBI_ARRAY_ELEM:
820  if ((*it)->curIndex >= (*it)->nElems)
821  {
822  /*
823  * All elements within array already processed. Report this
824  * to caller, and give it back original parent iterator (which
825  * independently tracks iteration progress at its level of
826  * nesting).
827  */
828  *it = freeAndGetParent(*it);
829  return WJB_END_ARRAY;
830  }
831 
832  fillJsonbValue((*it)->container, (*it)->curIndex,
833  (*it)->dataProper, (*it)->curDataOffset,
834  val);
835 
836  JBE_ADVANCE_OFFSET((*it)->curDataOffset,
837  (*it)->children[(*it)->curIndex]);
838  (*it)->curIndex++;
839 
840  if (!IsAJsonbScalar(val) && !skipNested)
841  {
842  /* Recurse into container. */
843  *it = iteratorFromContainer(val->val.binary.data, *it);
844  goto recurse;
845  }
846  else
847  {
848  /*
849  * Scalar item in array, or a container and caller didn't want
850  * us to recurse into it.
851  */
852  return WJB_ELEM;
853  }
854 
855  case JBI_OBJECT_START:
856  /* Set v to object on first object call */
857  val->type = jbvObject;
858  val->val.object.nPairs = (*it)->nElems;
859 
860  /*
861  * v->val.object.pairs is not actually set, because we aren't
862  * doing a full conversion
863  */
864  (*it)->curIndex = 0;
865  (*it)->curDataOffset = 0;
866  (*it)->curValueOffset = getJsonbOffset((*it)->container,
867  (*it)->nElems);
868  /* Set state for next call */
869  (*it)->state = JBI_OBJECT_KEY;
870  return WJB_BEGIN_OBJECT;
871 
872  case JBI_OBJECT_KEY:
873  if ((*it)->curIndex >= (*it)->nElems)
874  {
875  /*
876  * All pairs within object already processed. Report this to
877  * caller, and give it back original containing iterator
878  * (which independently tracks iteration progress at its level
879  * of nesting).
880  */
881  *it = freeAndGetParent(*it);
882  return WJB_END_OBJECT;
883  }
884  else
885  {
886  /* Return key of a key/value pair. */
887  fillJsonbValue((*it)->container, (*it)->curIndex,
888  (*it)->dataProper, (*it)->curDataOffset,
889  val);
890  if (val->type != jbvString)
891  elog(ERROR, "unexpected jsonb type as object key");
892 
893  /* Set state for next call */
894  (*it)->state = JBI_OBJECT_VALUE;
895  return WJB_KEY;
896  }
897 
898  case JBI_OBJECT_VALUE:
899  /* Set state for next call */
900  (*it)->state = JBI_OBJECT_KEY;
901 
902  fillJsonbValue((*it)->container, (*it)->curIndex + (*it)->nElems,
903  (*it)->dataProper, (*it)->curValueOffset,
904  val);
905 
906  JBE_ADVANCE_OFFSET((*it)->curDataOffset,
907  (*it)->children[(*it)->curIndex]);
908  JBE_ADVANCE_OFFSET((*it)->curValueOffset,
909  (*it)->children[(*it)->curIndex + (*it)->nElems]);
910  (*it)->curIndex++;
911 
912  /*
913  * Value may be a container, in which case we recurse with new,
914  * child iterator (unless the caller asked not to, by passing
915  * skipNested).
916  */
917  if (!IsAJsonbScalar(val) && !skipNested)
918  {
919  *it = iteratorFromContainer(val->val.binary.data, *it);
920  goto recurse;
921  }
922  else
923  return WJB_VALUE;
924  }
925 
926  elog(ERROR, "invalid iterator state");
927  return -1;
928 }
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:123
char * val
Definition: jsonb.h:264
Definition: jsonb.h:22
static JsonbIterator * freeAndGetParent(JsonbIterator *it)
Definition: jsonb_util.c:976
#define JBE_ADVANCE_OFFSET(offset, je)
Definition: jsonb.h:170
#define ERROR
Definition: elog.h:43
Definition: jsonb.h:23
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition: jsonb_util.c:490
static JsonbIterator * iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent)
Definition: jsonb_util.c:934
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:288
enum jbvType type
Definition: jsonb.h:255
#define elog(elevel,...)
Definition: elog.h:226
Definition: jsonb.h:25

◆ JsonbToCString()

char* JsonbToCString ( StringInfo  out,
JsonbContainer in,
int  estimated_len 
)

Definition at line 442 of file jsonb.c.

References JsonbToCStringWorker().

Referenced by get_jsonb_path_all(), jsonb_out(), jsonb_send(), JsonbValueAsText(), and populate_scalar().

443 {
444  return JsonbToCStringWorker(out, in, estimated_len, false);
445 }
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition: jsonb.c:460

◆ JsonbToCStringIndent()

char* JsonbToCStringIndent ( StringInfo  out,
JsonbContainer in,
int  estimated_len 
)

Definition at line 451 of file jsonb.c.

References JsonbToCStringWorker().

Referenced by jsonb_pretty().

452 {
453  return JsonbToCStringWorker(out, in, estimated_len, true);
454 }
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition: jsonb.c:460

◆ JsonbTypeName()

const char* JsonbTypeName ( JsonbValue jb)

Definition at line 191 of file jsonb.c.

References elog, ERROR, jbvArray, jbvBinary, jbvBool, jbvNull, jbvNumeric, jbvObject, jbvString, JsonbContainerTypeName(), JsonbValue::type, and JsonbValue::val.

Referenced by executeItemOptUnwrapTarget(), and JsonbContainerTypeName().

192 {
193  switch (jbv->type)
194  {
195  case jbvBinary:
196  return JsonbContainerTypeName(jbv->val.binary.data);
197  case jbvObject:
198  return "object";
199  case jbvArray:
200  return "array";
201  case jbvNumeric:
202  return "number";
203  case jbvString:
204  return "string";
205  case jbvBool:
206  return "boolean";
207  case jbvNull:
208  return "null";
209  default:
210  elog(ERROR, "unrecognized jsonb value type: %d", jbv->type);
211  return "unknown";
212  }
213 }
Definition: jsonb.h:239
Definition: jsonb.h:236
#define ERROR
Definition: elog.h:43
static const char * JsonbContainerTypeName(JsonbContainer *jbc)
Definition: jsonb.c:170
#define elog(elevel,...)
Definition: elog.h:226

◆ JsonbValueToJsonb()

Jsonb* JsonbValueToJsonb ( JsonbValue val)

Definition at line 81 of file jsonb_util.c.

References Assert, convertToJsonb(), IsAJsonbScalar, jbvArray, jbvBinary, jbvObject, palloc(), pushJsonbValue(), SET_VARSIZE, JsonbValue::type, JsonbValue::val, VARDATA, VARHDRSZ, WJB_BEGIN_ARRAY, WJB_ELEM, and WJB_END_ARRAY.

Referenced by each_worker_jsonb(), elements_worker_jsonb(), executeKeyValueMethod(), get_jsonb_path_all(), hstore_to_jsonb(), hstore_to_jsonb_loose(), jsonb_agg_finalfn(), jsonb_agg_transfn(), jsonb_array_element(), jsonb_build_array(), jsonb_build_array_noargs(), jsonb_build_object(), jsonb_build_object_noargs(), jsonb_concat(), jsonb_delete(), jsonb_delete_array(), jsonb_delete_idx(), jsonb_delete_path(), jsonb_from_cstring(), jsonb_insert(), jsonb_object(), jsonb_object_agg_finalfn(), jsonb_object_agg_transfn(), jsonb_object_field(), jsonb_object_two_arg(), jsonb_path_query(), jsonb_path_query_array(), jsonb_path_query_first(), jsonb_set(), jsonb_strip_nulls(), plperl_to_jsonb(), plpython_to_jsonb(), populate_scalar(), to_jsonb(), and transform_jsonb_string_values().

82 {
83  Jsonb *out;
84 
85  if (IsAJsonbScalar(val))
86  {
87  /* Scalar value */
88  JsonbParseState *pstate = NULL;
89  JsonbValue *res;
90  JsonbValue scalarArray;
91 
92  scalarArray.type = jbvArray;
93  scalarArray.val.array.rawScalar = true;
94  scalarArray.val.array.nElems = 1;
95 
96  pushJsonbValue(&pstate, WJB_BEGIN_ARRAY, &scalarArray);
97  pushJsonbValue(&pstate, WJB_ELEM, val);
98  res = pushJsonbValue(&pstate, WJB_END_ARRAY, NULL);
99 
100  out = convertToJsonb(res);
101  }
102  else if (val->type == jbvObject || val->type == jbvArray)
103  {
104  out = convertToJsonb(val);
105  }
106  else
107  {
108  Assert(val->type == jbvBinary);
109  out = palloc(VARHDRSZ + val->val.binary.len);
110  SET_VARSIZE(out, VARHDRSZ + val->val.binary.len);
111  memcpy(VARDATA(out), val->val.binary.data, val->val.binary.len);
112  }
113 
114  return out;
115 }
#define VARDATA(PTR)
Definition: postgres.h:302
Definition: jsonb.h:220
#define VARHDRSZ
Definition: c.h:555
char * val
Definition: jsonb.h:264
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:551
#define Assert(condition)
Definition: c.h:732
static Jsonb * convertToJsonb(JsonbValue *val)
Definition: jsonb_util.c:1483
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:288
enum jbvType type
Definition: jsonb.h:255
void * palloc(Size size)
Definition: mcxt.c:924
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
Definition: jsonb.h:25

◆ pushJsonbValue()

JsonbValue* pushJsonbValue ( JsonbParseState **  pstate,
JsonbIteratorToken  seq,
JsonbValue jbval 
)

Definition at line 551 of file jsonb_util.c.

References jbvBinary, JsonbIteratorInit(), JsonbIteratorNext(), pushJsonbValueScalar(), JsonbValue::type, JsonbValue::val, WJB_BEGIN_ARRAY, WJB_DONE, WJB_ELEM, and WJB_VALUE.

Referenced by addJsonbToParseState(), array_dim_to_jsonb(), array_to_jsonb_internal(), AV_to_JsonbValue(), composite_to_jsonb(), datum_to_jsonb(), executeKeyValueMethod(), hstore_to_jsonb(), hstore_to_jsonb_loose(), HV_to_JsonbValue(), IteratorConcat(), jsonb_agg_finalfn(), jsonb_agg_transfn(), jsonb_build_array(), jsonb_build_array_noargs(), jsonb_build_object(), jsonb_build_object_noargs(), jsonb_delete(), jsonb_delete_array(), jsonb_delete_idx(), jsonb_in_array_end(), jsonb_in_array_start(), jsonb_in_object_end(), jsonb_in_object_field_start(), jsonb_in_object_start(), jsonb_in_scalar(), jsonb_object(), jsonb_object_agg_finalfn(), jsonb_object_agg_transfn(), jsonb_object_two_arg(), jsonb_strip_nulls(), JsonbValueToJsonb(), PLyMapping_ToJsonbValue(), PLyObject_ToJsonbValue(), PLySequence_ToJsonbValue(), setPath(), setPathArray(), setPathObject(), SV_to_JsonbValue(), transform_jsonb_string_values(), and wrapItemsInArray().

553 {
554  JsonbIterator *it;
555  JsonbValue *res = NULL;
556  JsonbValue v;
557  JsonbIteratorToken tok;
558 
559  if (!jbval || (seq != WJB_ELEM && seq != WJB_VALUE) ||
560  jbval->type != jbvBinary)
561  {
562  /* drop through */
563  return pushJsonbValueScalar(pstate, seq, jbval);
564  }
565 
566  /* unpack the binary and add each piece to the pstate */
567  it = JsonbIteratorInit(jbval->val.binary.data);
568  while ((tok = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
569  res = pushJsonbValueScalar(pstate, tok,
570  tok < WJB_BEGIN_ARRAY ? &v : NULL);
571 
572  return res;
573 }
char * val
Definition: jsonb.h:264
Definition: jsonb.h:22
static JsonbValue * pushJsonbValueScalar(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *scalarVal)
Definition: jsonb_util.c:580
JsonbIteratorToken
Definition: jsonb.h:20
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:752
enum jbvType type
Definition: jsonb.h:255
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:788
Definition: jsonb.h:25