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, jbvDatetime = 0x20
}
 
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)
 
void JsonbToJsonbValue (Jsonb *jsonb, JsonbValue *val)
 
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)
 
Datum jsonb_set_element (Jsonb *jb, Datum *path, int path_len, JsonbValue *newval)
 
Datum jsonb_get_element (Jsonb *jb, Datum *path, int npath, bool *isnull, bool as_text)
 

Macro Definition Documentation

◆ DatumGetJsonbP

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

◆ 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(), and pushJsonbValue().

◆ 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_internal(), 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_internal().

◆ 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 
jbvDatetime 

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 
246  /*
247  * Virtual types.
248  *
249  * These types are used only for in-memory JSON processing and serialized
250  * into JSON strings when outputted to json/jsonb.
251  */
252  jbvDatetime = 0x20,
253 };
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 338 of file jsonb.h.

Function Documentation

◆ compareJsonbContainers()

int compareJsonbContainers ( JsonbContainer a,
JsonbContainer b 
)

Definition at line 191 of file jsonb_util.c.

References Assert, compareJsonbScalarValue(), elog, ERROR, i, jbvArray, jbvBinary, jbvBool, jbvDatetime, 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().

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

◆ findJsonbValueFromContainer()

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

Definition at line 344 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().

346 {
347  JEntry *children = container->children;
348  int count = JsonContainerSize(container);
349 
350  Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
351 
352  /* Quick out without a palloc cycle if object/array is empty */
353  if (count <= 0)
354  return NULL;
355 
356  if ((flags & JB_FARRAY) && JsonContainerIsArray(container))
357  {
358  JsonbValue *result = palloc(sizeof(JsonbValue));
359  char *base_addr = (char *) (children + count);
360  uint32 offset = 0;
361  int i;
362 
363  for (i = 0; i < count; i++)
364  {
365  fillJsonbValue(container, i, base_addr, offset, result);
366 
367  if (key->type == result->type)
368  {
369  if (equalsJsonbScalarValue(key, result))
370  return result;
371  }
372 
373  JBE_ADVANCE_OFFSET(offset, children[i]);
374  }
375 
376  pfree(result);
377  }
378  else if ((flags & JB_FOBJECT) && JsonContainerIsObject(container))
379  {
380  /* Object key passed by caller must be a string */
381  Assert(key->type == jbvString);
382 
383  return getKeyJsonValueFromContainer(container, key->val.string.val,
384  key->val.string.len, NULL);
385  }
386 
387  /* Not found */
388  return NULL;
389 }
#define JB_FARRAY
Definition: jsonb.h:211
char * val
Definition: jsonb.h:272
JsonbValue * getKeyJsonValueFromContainer(JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
Definition: jsonb_util.c:398
#define JBE_ADVANCE_OFFSET(offset, je)
Definition: jsonb.h:170
void pfree(void *pointer)
Definition: mcxt.c:1057
#define JsonContainerSize(jc)
Definition: jsonb.h:214
unsigned int uint32
Definition: c.h:441
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition: jsonb_util.c:505
#define JsonContainerIsArray(jc)
Definition: jsonb.h:217
static bool equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b)
Definition: jsonb_util.c:1396
#define JsonContainerIsObject(jc)
Definition: jsonb.h:216
#define Assert(condition)
Definition: c.h:804
#define JB_FOBJECT
Definition: jsonb.h:210
uint32 JEntry
Definition: jsonb.h:144
enum jbvType type
Definition: jsonb.h:263
void * palloc(Size size)
Definition: mcxt.c:950
int i

◆ getIthJsonbValueFromContainer()

JsonbValue* getIthJsonbValueFromContainer ( JsonbContainer sheader,
uint32  i 
)

Definition at line 468 of file jsonb_util.c.

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

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

469 {
470  JsonbValue *result;
471  char *base_addr;
472  uint32 nelements;
473 
474  if (!JsonContainerIsArray(container))
475  elog(ERROR, "not a jsonb array");
476 
477  nelements = JsonContainerSize(container);
478  base_addr = (char *) &container->children[nelements];
479 
480  if (i >= nelements)
481  return NULL;
482 
483  result = palloc(sizeof(JsonbValue));
484 
485  fillJsonbValue(container, i, base_addr,
486  getJsonbOffset(container, i),
487  result);
488 
489  return result;
490 }
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:134
#define ERROR
Definition: elog.h:45
#define JsonContainerSize(jc)
Definition: jsonb.h:214
unsigned int uint32
Definition: c.h:441
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition: jsonb_util.c:505
#define JsonContainerIsArray(jc)
Definition: jsonb.h:217
void * palloc(Size size)
Definition: mcxt.c:950
#define elog(elevel,...)
Definition: elog.h:227
int i

◆ getJsonbLength()

uint32 getJsonbLength ( const JsonbContainer jc,
int  index 
)

Definition at line 159 of file jsonb_util.c.

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

Referenced by fillJsonbValue(), and getKeyJsonValueFromContainer().

160 {
161  uint32 off;
162  uint32 len;
163 
164  /*
165  * If the length is stored directly in the JEntry, just return it.
166  * Otherwise, get the begin offset of the entry, and subtract that from
167  * the stored end+1 offset.
168  */
169  if (JBE_HAS_OFF(jc->children[index]))
170  {
171  off = getJsonbOffset(jc, index);
172  len = JBE_OFFLENFLD(jc->children[index]) - off;
173  }
174  else
175  len = JBE_OFFLENFLD(jc->children[index]);
176 
177  return len;
178 }
JEntry children[FLEXIBLE_ARRAY_MEMBER]
Definition: jsonb.h:202
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:134
#define JBE_OFFLENFLD(je_)
Definition: jsonb.h:159
Definition: type.h:89
unsigned int uint32
Definition: c.h:441
#define JBE_HAS_OFF(je_)
Definition: jsonb.h:160

◆ getJsonbOffset()

uint32 getJsonbOffset ( const JsonbContainer jc,
int  index 
)

Definition at line 134 of file jsonb_util.c.

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

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

135 {
136  uint32 offset = 0;
137  int i;
138 
139  /*
140  * Start offset of this entry is equal to the end offset of the previous
141  * entry. Walk backwards to the most recent entry stored as an end
142  * offset, returning that offset plus any lengths in between.
143  */
144  for (i = index - 1; i >= 0; i--)
145  {
146  offset += JBE_OFFLENFLD(jc->children[i]);
147  if (JBE_HAS_OFF(jc->children[i]))
148  break;
149  }
150 
151  return offset;
152 }
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:441
#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 398 of file jsonb_util.c.

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

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

400 {
401  JEntry *children = container->children;
402  int count = JsonContainerSize(container);
403  char *baseAddr;
404  uint32 stopLow,
405  stopHigh;
406 
407  Assert(JsonContainerIsObject(container));
408 
409  /* Quick out without a palloc cycle if object is empty */
410  if (count <= 0)
411  return NULL;
412 
413  /*
414  * Binary search the container. Since we know this is an object, account
415  * for *Pairs* of Jentrys
416  */
417  baseAddr = (char *) (children + count * 2);
418  stopLow = 0;
419  stopHigh = count;
420  while (stopLow < stopHigh)
421  {
422  uint32 stopMiddle;
423  int difference;
424  const char *candidateVal;
425  int candidateLen;
426 
427  stopMiddle = stopLow + (stopHigh - stopLow) / 2;
428 
429  candidateVal = baseAddr + getJsonbOffset(container, stopMiddle);
430  candidateLen = getJsonbLength(container, stopMiddle);
431 
432  difference = lengthCompareJsonbString(candidateVal, candidateLen,
433  keyVal, keyLen);
434 
435  if (difference == 0)
436  {
437  /* Found our key, return corresponding value */
438  int index = stopMiddle + count;
439 
440  if (!res)
441  res = palloc(sizeof(JsonbValue));
442 
443  fillJsonbValue(container, index, baseAddr,
444  getJsonbOffset(container, index),
445  res);
446 
447  return res;
448  }
449  else
450  {
451  if (difference < 0)
452  stopLow = stopMiddle + 1;
453  else
454  stopHigh = stopMiddle;
455  }
456  }
457 
458  /* Not found */
459  return NULL;
460 }
JEntry children[FLEXIBLE_ARRAY_MEMBER]
Definition: jsonb.h:202
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:134
uint32 getJsonbLength(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:159
static int lengthCompareJsonbString(const char *val1, int len1, const char *val2, int len2)
Definition: jsonb_util.c:1894
Definition: type.h:89
#define JsonContainerSize(jc)
Definition: jsonb.h:214
unsigned int uint32
Definition: c.h:441
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition: jsonb_util.c:505
#define JsonContainerIsObject(jc)
Definition: jsonb.h:216
Datum difference(PG_FUNCTION_ARGS)
#define Assert(condition)
Definition: c.h:804
uint32 JEntry
Definition: jsonb.h:144
void * palloc(Size size)
Definition: mcxt.c:950

◆ jsonb_get_element()

Datum jsonb_get_element ( Jsonb jb,
Datum path,
int  npath,
bool isnull,
bool  as_text 
)

Definition at line 1469 of file jsonfuncs.c.

References Assert, cstring_to_text(), elog, ERROR, getIthJsonbValueFromContainer(), getKeyJsonValueFromContainer(), i, IsAJsonbScalar, JB_ROOT_IS_ARRAY, JB_ROOT_IS_OBJECT, JB_ROOT_IS_SCALAR, jbvBinary, jbvNull, JsonbToCString(), JsonbValueAsText(), JsonbValueToJsonb(), JsonContainerIsArray, JsonContainerIsObject, JsonContainerIsScalar, JsonContainerSize, PG_RETURN_JSONB_P, PointerGetDatum, Jsonb::root, strtoint(), TextDatumGetCString, JsonbValue::type, JsonbValue::val, VARDATA, VARHDRSZ, and VARSIZE.

Referenced by get_jsonb_path_all(), jsonb_subscript_fetch(), and jsonb_subscript_fetch_old().

1470 {
1471  JsonbContainer *container = &jb->root;
1472  JsonbValue *jbvp = NULL;
1473  int i;
1474  bool have_object = false,
1475  have_array = false;
1476 
1477  *isnull = false;
1478 
1479  /* Identify whether we have object, array, or scalar at top-level */
1480  if (JB_ROOT_IS_OBJECT(jb))
1481  have_object = true;
1482  else if (JB_ROOT_IS_ARRAY(jb) && !JB_ROOT_IS_SCALAR(jb))
1483  have_array = true;
1484  else
1485  {
1487  /* Extract the scalar value, if it is what we'll return */
1488  if (npath <= 0)
1489  jbvp = getIthJsonbValueFromContainer(container, 0);
1490  }
1491 
1492  /*
1493  * If the array is empty, return the entire LHS object, on the grounds
1494  * that we should do zero field or element extractions. For the
1495  * non-scalar case we can just hand back the object without much work. For
1496  * the scalar case, fall through and deal with the value below the loop.
1497  * (This inconsistency arises because there's no easy way to generate a
1498  * JsonbValue directly for root-level containers.)
1499  */
1500  if (npath <= 0 && jbvp == NULL)
1501  {
1502  if (as_text)
1503  {
1505  container,
1506  VARSIZE(jb))));
1507  }
1508  else
1509  {
1510  /* not text mode - just hand back the jsonb */
1511  PG_RETURN_JSONB_P(jb);
1512  }
1513  }
1514 
1515  for (i = 0; i < npath; i++)
1516  {
1517  if (have_object)
1518  {
1519  jbvp = getKeyJsonValueFromContainer(container,
1520  VARDATA(path[i]),
1521  VARSIZE(path[i]) - VARHDRSZ,
1522  NULL);
1523  }
1524  else if (have_array)
1525  {
1526  int lindex;
1527  uint32 index;
1528  char *indextext = TextDatumGetCString(path[i]);
1529  char *endptr;
1530 
1531  errno = 0;
1532  lindex = strtoint(indextext, &endptr, 10);
1533  if (endptr == indextext || *endptr != '\0' || errno != 0)
1534  {
1535  *isnull = true;
1536  return PointerGetDatum(NULL);
1537  }
1538 
1539  if (lindex >= 0)
1540  {
1541  index = (uint32) lindex;
1542  }
1543  else
1544  {
1545  /* Handle negative subscript */
1546  uint32 nelements;
1547 
1548  /* Container must be array, but make sure */
1549  if (!JsonContainerIsArray(container))
1550  elog(ERROR, "not a jsonb array");
1551 
1552  nelements = JsonContainerSize(container);
1553 
1554  if (lindex == INT_MIN || -lindex > nelements)
1555  {
1556  *isnull = true;
1557  return PointerGetDatum(NULL);
1558  }
1559  else
1560  index = nelements + lindex;
1561  }
1562 
1563  jbvp = getIthJsonbValueFromContainer(container, index);
1564  }
1565  else
1566  {
1567  /* scalar, extraction yields a null */
1568  *isnull = true;
1569  return PointerGetDatum(NULL);
1570  }
1571 
1572  if (jbvp == NULL)
1573  {
1574  *isnull = true;
1575  return PointerGetDatum(NULL);
1576  }
1577  else if (i == npath - 1)
1578  break;
1579 
1580  if (jbvp->type == jbvBinary)
1581  {
1582  container = jbvp->val.binary.data;
1583  have_object = JsonContainerIsObject(container);
1584  have_array = JsonContainerIsArray(container);
1585  Assert(!JsonContainerIsScalar(container));
1586  }
1587  else
1588  {
1589  Assert(IsAJsonbScalar(jbvp));
1590  have_object = false;
1591  have_array = false;
1592  }
1593  }
1594 
1595  if (as_text)
1596  {
1597  if (jbvp->type == jbvNull)
1598  {
1599  *isnull = true;
1600  return PointerGetDatum(NULL);
1601  }
1602 
1603  return PointerGetDatum(JsonbValueAsText(jbvp));
1604  }
1605  else
1606  {
1607  Jsonb *res = JsonbValueToJsonb(jbvp);
1608 
1609  /* not text mode - just hand back the jsonb */
1610  PG_RETURN_JSONB_P(res);
1611  }
1612 }
#define JB_ROOT_IS_OBJECT(jbp_)
Definition: jsonb.h:229
#define VARDATA(PTR)
Definition: postgres.h:302
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:92
Definition: jsonb.h:220
#define VARSIZE(PTR)
Definition: postgres.h:303
#define PointerGetDatum(X)
Definition: postgres.h:556
#define VARHDRSZ
Definition: c.h:627
char * val
Definition: jsonb.h:272
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:215
JsonbValue * getKeyJsonValueFromContainer(JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
Definition: jsonb_util.c:398
Definition: jsonb.h:236
static text * JsonbValueAsText(JsonbValue *v)
Definition: jsonfuncs.c:1741
#define JB_ROOT_IS_SCALAR(jbp_)
Definition: jsonb.h:228
Definition: type.h:89
#define ERROR
Definition: elog.h:45
#define JB_ROOT_IS_ARRAY(jbp_)
Definition: jsonb.h:230
#define JsonContainerSize(jc)
Definition: jsonb.h:214
unsigned int uint32
Definition: c.h:441
int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
Definition: string.c:50
#define JsonContainerIsArray(jc)
Definition: jsonb.h:217
JsonbContainer root
Definition: jsonb.h:223
#define TextDatumGetCString(d)
Definition: builtins.h:83
#define JsonContainerIsObject(jc)
Definition: jsonb.h:216
text * cstring_to_text(const char *s)
Definition: varlena.c:189
JsonbValue * getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)
Definition: jsonb_util.c:468
#define Assert(condition)
Definition: c.h:804
char * JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
Definition: jsonb.c:460
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:305
enum jbvType type
Definition: jsonb.h:263
#define elog(elevel,...)
Definition: elog.h:227
int i
#define PG_RETURN_JSONB_P(x)
Definition: jsonb.h:76

◆ jsonb_set_element()

Datum jsonb_set_element ( Jsonb jb,
Datum path,
int  path_len,
JsonbValue newval 
)

Definition at line 1615 of file jsonfuncs.c.

References JB_PATH_CONSISTENT_POSITION, JB_PATH_CREATE, JB_PATH_FILL_GAPS, jbvArray, JsonbIteratorInit(), JsonbValueToJsonb(), palloc0(), pfree(), PG_RETURN_JSONB_P, Jsonb::root, setPath(), JsonbValue::type, and JsonbValue::val.

Referenced by jsonb_subscript_assign().

1617 {
1618  JsonbValue *res;
1619  JsonbParseState *state = NULL;
1620  JsonbIterator *it;
1621  bool *path_nulls = palloc0(path_len * sizeof(bool));
1622 
1623  if (newval->type == jbvArray && newval->val.array.rawScalar)
1624  *newval = newval->val.array.elems[0];
1625 
1626  it = JsonbIteratorInit(&jb->root);
1627 
1628  res = setPath(&it, path, path_nulls, path_len, &state, 0, newval,
1631 
1632  pfree(path_nulls);
1633 
1635 }
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:92
char * val
Definition: jsonb.h:272
#define JB_PATH_CREATE
Definition: jsonfuncs.c:41
void pfree(void *pointer)
Definition: mcxt.c:1057
#define JB_PATH_CONSISTENT_POSITION
Definition: jsonfuncs.c:49
JsonbContainer root
Definition: jsonb.h:223
void * palloc0(Size size)
Definition: mcxt.c:981
#define JB_PATH_FILL_GAPS
Definition: jsonfuncs.c:48
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:812
Definition: regguts.h:317
enum jbvType type
Definition: jsonb.h:263
static JsonbValue * setPath(JsonbIterator **it, Datum *path_elems, bool *path_nulls, int path_len, JsonbParseState **st, int level, JsonbValue *newval, int op_type)
Definition: jsonfuncs.c:4900
#define PG_RETURN_JSONB_P(x)
Definition: jsonb.h:76

◆ JsonbDeepContains()

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

Definition at line 1057 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().

1058 {
1059  JsonbValue vval,
1060  vcontained;
1061  JsonbIteratorToken rval,
1062  rcont;
1063 
1064  /*
1065  * Guard against stack overflow due to overly complex Jsonb.
1066  *
1067  * Functions called here independently take this precaution, but that
1068  * might not be sufficient since this is also a recursive function.
1069  */
1071 
1072  rval = JsonbIteratorNext(val, &vval, false);
1073  rcont = JsonbIteratorNext(mContained, &vcontained, false);
1074 
1075  if (rval != rcont)
1076  {
1077  /*
1078  * The differing return values can immediately be taken as indicating
1079  * two differing container types at this nesting level, which is
1080  * sufficient reason to give up entirely (but it should be the case
1081  * that they're both some container type).
1082  */
1083  Assert(rval == WJB_BEGIN_OBJECT || rval == WJB_BEGIN_ARRAY);
1084  Assert(rcont == WJB_BEGIN_OBJECT || rcont == WJB_BEGIN_ARRAY);
1085  return false;
1086  }
1087  else if (rcont == WJB_BEGIN_OBJECT)
1088  {
1089  Assert(vval.type == jbvObject);
1090  Assert(vcontained.type == jbvObject);
1091 
1092  /*
1093  * If the lhs has fewer pairs than the rhs, it can't possibly contain
1094  * the rhs. (This conclusion is safe only because we de-duplicate
1095  * keys in all Jsonb objects; thus there can be no corresponding
1096  * optimization in the array case.) The case probably won't arise
1097  * often, but since it's such a cheap check we may as well make it.
1098  */
1099  if (vval.val.object.nPairs < vcontained.val.object.nPairs)
1100  return false;
1101 
1102  /* Work through rhs "is it contained within?" object */
1103  for (;;)
1104  {
1105  JsonbValue *lhsVal; /* lhsVal is from pair in lhs object */
1106  JsonbValue lhsValBuf;
1107 
1108  rcont = JsonbIteratorNext(mContained, &vcontained, false);
1109 
1110  /*
1111  * When we get through caller's rhs "is it contained within?"
1112  * object without failing to find one of its values, it's
1113  * contained.
1114  */
1115  if (rcont == WJB_END_OBJECT)
1116  return true;
1117 
1118  Assert(rcont == WJB_KEY);
1119  Assert(vcontained.type == jbvString);
1120 
1121  /* First, find value by key... */
1122  lhsVal =
1123  getKeyJsonValueFromContainer((*val)->container,
1124  vcontained.val.string.val,
1125  vcontained.val.string.len,
1126  &lhsValBuf);
1127  if (!lhsVal)
1128  return false;
1129 
1130  /*
1131  * ...at this stage it is apparent that there is at least a key
1132  * match for this rhs pair.
1133  */
1134  rcont = JsonbIteratorNext(mContained, &vcontained, true);
1135 
1136  Assert(rcont == WJB_VALUE);
1137 
1138  /*
1139  * Compare rhs pair's value with lhs pair's value just found using
1140  * key
1141  */
1142  if (lhsVal->type != vcontained.type)
1143  {
1144  return false;
1145  }
1146  else if (IsAJsonbScalar(lhsVal))
1147  {
1148  if (!equalsJsonbScalarValue(lhsVal, &vcontained))
1149  return false;
1150  }
1151  else
1152  {
1153  /* Nested container value (object or array) */
1154  JsonbIterator *nestval,
1155  *nestContained;
1156 
1157  Assert(lhsVal->type == jbvBinary);
1158  Assert(vcontained.type == jbvBinary);
1159 
1160  nestval = JsonbIteratorInit(lhsVal->val.binary.data);
1161  nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1162 
1163  /*
1164  * Match "value" side of rhs datum object's pair recursively.
1165  * It's a nested structure.
1166  *
1167  * Note that nesting still has to "match up" at the right
1168  * nesting sub-levels. However, there need only be zero or
1169  * more matching pairs (or elements) at each nesting level
1170  * (provided the *rhs* pairs/elements *all* match on each
1171  * level), which enables searching nested structures for a
1172  * single String or other primitive type sub-datum quite
1173  * effectively (provided the user constructed the rhs nested
1174  * structure such that we "know where to look").
1175  *
1176  * In other words, the mapping of container nodes in the rhs
1177  * "vcontained" Jsonb to internal nodes on the lhs is
1178  * injective, and parent-child edges on the rhs must be mapped
1179  * to parent-child edges on the lhs to satisfy the condition
1180  * of containment (plus of course the mapped nodes must be
1181  * equal).
1182  */
1183  if (!JsonbDeepContains(&nestval, &nestContained))
1184  return false;
1185  }
1186  }
1187  }
1188  else if (rcont == WJB_BEGIN_ARRAY)
1189  {
1190  JsonbValue *lhsConts = NULL;
1191  uint32 nLhsElems = vval.val.array.nElems;
1192 
1193  Assert(vval.type == jbvArray);
1194  Assert(vcontained.type == jbvArray);
1195 
1196  /*
1197  * Handle distinction between "raw scalar" pseudo arrays, and real
1198  * arrays.
1199  *
1200  * A raw scalar may contain another raw scalar, and an array may
1201  * contain a raw scalar, but a raw scalar may not contain an array. We
1202  * don't do something like this for the object case, since objects can
1203  * only contain pairs, never raw scalars (a pair is represented by an
1204  * rhs object argument with a single contained pair).
1205  */
1206  if (vval.val.array.rawScalar && !vcontained.val.array.rawScalar)
1207  return false;
1208 
1209  /* Work through rhs "is it contained within?" array */
1210  for (;;)
1211  {
1212  rcont = JsonbIteratorNext(mContained, &vcontained, true);
1213 
1214  /*
1215  * When we get through caller's rhs "is it contained within?"
1216  * array without failing to find one of its values, it's
1217  * contained.
1218  */
1219  if (rcont == WJB_END_ARRAY)
1220  return true;
1221 
1222  Assert(rcont == WJB_ELEM);
1223 
1224  if (IsAJsonbScalar(&vcontained))
1225  {
1226  if (!findJsonbValueFromContainer((*val)->container,
1227  JB_FARRAY,
1228  &vcontained))
1229  return false;
1230  }
1231  else
1232  {
1233  uint32 i;
1234 
1235  /*
1236  * If this is first container found in rhs array (at this
1237  * depth), initialize temp lhs array of containers
1238  */
1239  if (lhsConts == NULL)
1240  {
1241  uint32 j = 0;
1242 
1243  /* Make room for all possible values */
1244  lhsConts = palloc(sizeof(JsonbValue) * nLhsElems);
1245 
1246  for (i = 0; i < nLhsElems; i++)
1247  {
1248  /* Store all lhs elements in temp array */
1249  rcont = JsonbIteratorNext(val, &vval, true);
1250  Assert(rcont == WJB_ELEM);
1251 
1252  if (vval.type == jbvBinary)
1253  lhsConts[j++] = vval;
1254  }
1255 
1256  /* No container elements in temp array, so give up now */
1257  if (j == 0)
1258  return false;
1259 
1260  /* We may have only partially filled array */
1261  nLhsElems = j;
1262  }
1263 
1264  /* XXX: Nested array containment is O(N^2) */
1265  for (i = 0; i < nLhsElems; i++)
1266  {
1267  /* Nested container value (object or array) */
1268  JsonbIterator *nestval,
1269  *nestContained;
1270  bool contains;
1271 
1272  nestval = JsonbIteratorInit(lhsConts[i].val.binary.data);
1273  nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1274 
1275  contains = JsonbDeepContains(&nestval, &nestContained);
1276 
1277  if (nestval)
1278  pfree(nestval);
1279  if (nestContained)
1280  pfree(nestContained);
1281  if (contains)
1282  break;
1283  }
1284 
1285  /*
1286  * Report rhs container value is not contained if couldn't
1287  * match rhs container to *some* lhs cont
1288  */
1289  if (i == nLhsElems)
1290  return false;
1291  }
1292  }
1293  }
1294  else
1295  {
1296  elog(ERROR, "invalid jsonb container type");
1297  }
1298 
1299  elog(ERROR, "unexpectedly fell off end of jsonb container");
1300  return false;
1301 }
#define JB_FARRAY
Definition: jsonb.h:211
bool JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
Definition: jsonb_util.c:1057
char * val
Definition: jsonb.h:272
JsonbValue * getKeyJsonValueFromContainer(JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
Definition: jsonb_util.c:398
void pfree(void *pointer)
Definition: mcxt.c:1057
#define ERROR
Definition: elog.h:45
void check_stack_depth(void)
Definition: postgres.c:3310
unsigned int uint32
Definition: c.h:441
Definition: jsonb.h:23
static bool equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b)
Definition: jsonb_util.c:1396
JsonbIteratorToken
Definition: jsonb.h:20
#define Assert(condition)
Definition: c.h:804
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:812
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:305
enum jbvType type
Definition: jsonb.h:263
void * palloc(Size size)
Definition: mcxt.c:950
#define elog(elevel,...)
Definition: elog.h:227
int i
JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)
Definition: jsonb_util.c:344
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:848
Definition: jsonb.h:25

◆ JsonbExtractScalar()

bool JsonbExtractScalar ( JsonbContainer jbc,
JsonbValue res 
)

Definition at line 1895 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().

1896 {
1897  JsonbIterator *it;
1899  JsonbValue tmp;
1900 
1901  if (!JsonContainerIsArray(jbc) || !JsonContainerIsScalar(jbc))
1902  {
1903  /* inform caller about actual type of container */
1904  res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
1905  return false;
1906  }
1907 
1908  /*
1909  * A root scalar is stored as an array of one element, so we get the array
1910  * and then its first (and only) member.
1911  */
1912  it = JsonbIteratorInit(jbc);
1913 
1914  tok = JsonbIteratorNext(&it, &tmp, true);
1915  Assert(tok == WJB_BEGIN_ARRAY);
1916  Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
1917 
1918  tok = JsonbIteratorNext(&it, res, true);
1919  Assert(tok == WJB_ELEM);
1920  Assert(IsAJsonbScalar(res));
1921 
1922  tok = JsonbIteratorNext(&it, &tmp, true);
1923  Assert(tok == WJB_END_ARRAY);
1924 
1925  tok = JsonbIteratorNext(&it, &tmp, true);
1926  Assert(tok == WJB_DONE);
1927 
1928  return true;
1929 }
char * val
Definition: jsonb.h:272
#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:804
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:812
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:305
enum jbvType type
Definition: jsonb.h:263
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:848
Definition: jsonb.h:25
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:155

◆ JsonbHashScalarValue()

void JsonbHashScalarValue ( const JsonbValue scalarVal,
uint32 hash 
)

Definition at line 1311 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().

1312 {
1313  uint32 tmp;
1314 
1315  /* Compute hash value for scalarVal */
1316  switch (scalarVal->type)
1317  {
1318  case jbvNull:
1319  tmp = 0x01;
1320  break;
1321  case jbvString:
1322  tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->val.string.val,
1323  scalarVal->val.string.len));
1324  break;
1325  case jbvNumeric:
1326  /* Must hash equal numerics to equal hash codes */
1328  NumericGetDatum(scalarVal->val.numeric)));
1329  break;
1330  case jbvBool:
1331  tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1332 
1333  break;
1334  default:
1335  elog(ERROR, "invalid jsonb scalar type");
1336  tmp = 0; /* keep compiler quiet */
1337  break;
1338  }
1339 
1340  /*
1341  * Combine hash values of successive keys, values and elements by rotating
1342  * the previous value left 1 bit, then XOR'ing in the new
1343  * key/value/element's hash value.
1344  */
1345  *hash = (*hash << 1) | (*hash >> 31);
1346  *hash ^= tmp;
1347 }
#define DatumGetUInt32(X)
Definition: postgres.h:486
Datum hash_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:2560
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
Definition: jsonb.h:239
Definition: jsonb.h:236
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:626
#define ERROR
Definition: elog.h:45
unsigned int uint32
Definition: c.h:441
static Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.h:31
enum jbvType type
Definition: jsonb.h:263
#define elog(elevel,...)
Definition: elog.h:227
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:717

◆ JsonbHashScalarValueExtended()

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

Definition at line 1354 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().

1356 {
1357  uint64 tmp;
1358 
1359  switch (scalarVal->type)
1360  {
1361  case jbvNull:
1362  tmp = seed + 0x01;
1363  break;
1364  case jbvString:
1365  tmp = DatumGetUInt64(hash_any_extended((const unsigned char *) scalarVal->val.string.val,
1366  scalarVal->val.string.len,
1367  seed));
1368  break;
1369  case jbvNumeric:
1371  NumericGetDatum(scalarVal->val.numeric),
1372  UInt64GetDatum(seed)));
1373  break;
1374  case jbvBool:
1375  if (seed)
1377  BoolGetDatum(scalarVal->val.boolean),
1378  UInt64GetDatum(seed)));
1379  else
1380  tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1381 
1382  break;
1383  default:
1384  elog(ERROR, "invalid jsonb scalar type");
1385  break;
1386  }
1387 
1389  *hash ^= tmp;
1390 }
Datum hash_numeric_extended(PG_FUNCTION_ARGS)
Definition: numeric.c:2640
#define UInt64GetDatum(X)
Definition: postgres.h:648
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
Definition: jsonb.h:239
Definition: jsonb.h:236
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Definition: hashfn.h:37
#define ERROR
Definition: elog.h:45
#define ROTATE_HIGH_AND_LOW_32BITS(v)
Definition: hashfn.h:18
#define BoolGetDatum(X)
Definition: postgres.h:402
#define DatumGetUInt64(X)
Definition: postgres.h:634
enum jbvType type
Definition: jsonb.h:263
Datum hashcharextended(PG_FUNCTION_ARGS)
Definition: hashfunc.c:53
#define elog(elevel,...)
Definition: elog.h:227
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:717
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628

◆ JsonbIteratorInit()

◆ JsonbIteratorNext()

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

Definition at line 848 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 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().

849 {
850  if (*it == NULL)
851  return WJB_DONE;
852 
853  /*
854  * When stepping into a nested container, we jump back here to start
855  * processing the child. We will not recurse further in one call, because
856  * processing the child will always begin in JBI_ARRAY_START or
857  * JBI_OBJECT_START state.
858  */
859 recurse:
860  switch ((*it)->state)
861  {
862  case JBI_ARRAY_START:
863  /* Set v to array on first array call */
864  val->type = jbvArray;
865  val->val.array.nElems = (*it)->nElems;
866 
867  /*
868  * v->val.array.elems is not actually set, because we aren't doing
869  * a full conversion
870  */
871  val->val.array.rawScalar = (*it)->isScalar;
872  (*it)->curIndex = 0;
873  (*it)->curDataOffset = 0;
874  (*it)->curValueOffset = 0; /* not actually used */
875  /* Set state for next call */
876  (*it)->state = JBI_ARRAY_ELEM;
877  return WJB_BEGIN_ARRAY;
878 
879  case JBI_ARRAY_ELEM:
880  if ((*it)->curIndex >= (*it)->nElems)
881  {
882  /*
883  * All elements within array already processed. Report this
884  * to caller, and give it back original parent iterator (which
885  * independently tracks iteration progress at its level of
886  * nesting).
887  */
888  *it = freeAndGetParent(*it);
889  return WJB_END_ARRAY;
890  }
891 
892  fillJsonbValue((*it)->container, (*it)->curIndex,
893  (*it)->dataProper, (*it)->curDataOffset,
894  val);
895 
896  JBE_ADVANCE_OFFSET((*it)->curDataOffset,
897  (*it)->children[(*it)->curIndex]);
898  (*it)->curIndex++;
899 
900  if (!IsAJsonbScalar(val) && !skipNested)
901  {
902  /* Recurse into container. */
903  *it = iteratorFromContainer(val->val.binary.data, *it);
904  goto recurse;
905  }
906  else
907  {
908  /*
909  * Scalar item in array, or a container and caller didn't want
910  * us to recurse into it.
911  */
912  return WJB_ELEM;
913  }
914 
915  case JBI_OBJECT_START:
916  /* Set v to object on first object call */
917  val->type = jbvObject;
918  val->val.object.nPairs = (*it)->nElems;
919 
920  /*
921  * v->val.object.pairs is not actually set, because we aren't
922  * doing a full conversion
923  */
924  (*it)->curIndex = 0;
925  (*it)->curDataOffset = 0;
926  (*it)->curValueOffset = getJsonbOffset((*it)->container,
927  (*it)->nElems);
928  /* Set state for next call */
929  (*it)->state = JBI_OBJECT_KEY;
930  return WJB_BEGIN_OBJECT;
931 
932  case JBI_OBJECT_KEY:
933  if ((*it)->curIndex >= (*it)->nElems)
934  {
935  /*
936  * All pairs within object already processed. Report this to
937  * caller, and give it back original containing iterator
938  * (which independently tracks iteration progress at its level
939  * of nesting).
940  */
941  *it = freeAndGetParent(*it);
942  return WJB_END_OBJECT;
943  }
944  else
945  {
946  /* Return key of a key/value pair. */
947  fillJsonbValue((*it)->container, (*it)->curIndex,
948  (*it)->dataProper, (*it)->curDataOffset,
949  val);
950  if (val->type != jbvString)
951  elog(ERROR, "unexpected jsonb type as object key");
952 
953  /* Set state for next call */
954  (*it)->state = JBI_OBJECT_VALUE;
955  return WJB_KEY;
956  }
957 
958  case JBI_OBJECT_VALUE:
959  /* Set state for next call */
960  (*it)->state = JBI_OBJECT_KEY;
961 
962  fillJsonbValue((*it)->container, (*it)->curIndex + (*it)->nElems,
963  (*it)->dataProper, (*it)->curValueOffset,
964  val);
965 
966  JBE_ADVANCE_OFFSET((*it)->curDataOffset,
967  (*it)->children[(*it)->curIndex]);
968  JBE_ADVANCE_OFFSET((*it)->curValueOffset,
969  (*it)->children[(*it)->curIndex + (*it)->nElems]);
970  (*it)->curIndex++;
971 
972  /*
973  * Value may be a container, in which case we recurse with new,
974  * child iterator (unless the caller asked not to, by passing
975  * skipNested).
976  */
977  if (!IsAJsonbScalar(val) && !skipNested)
978  {
979  *it = iteratorFromContainer(val->val.binary.data, *it);
980  goto recurse;
981  }
982  else
983  return WJB_VALUE;
984  }
985 
986  elog(ERROR, "invalid iterator state");
987  return -1;
988 }
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:134
char * val
Definition: jsonb.h:272
Definition: jsonb.h:22
static JsonbIterator * freeAndGetParent(JsonbIterator *it)
Definition: jsonb_util.c:1036
#define JBE_ADVANCE_OFFSET(offset, je)
Definition: jsonb.h:170
#define ERROR
Definition: elog.h:45
Definition: jsonb.h:23
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition: jsonb_util.c:505
static JsonbIterator * iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent)
Definition: jsonb_util.c:994
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:305
enum jbvType type
Definition: jsonb.h:263
#define elog(elevel,...)
Definition: elog.h:227
Definition: jsonb.h:25

◆ JsonbToCString()

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

Definition at line 460 of file jsonb.c.

References JsonbToCStringWorker().

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

461 {
462  return JsonbToCStringWorker(out, in, estimated_len, false);
463 }
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition: jsonb.c:478

◆ JsonbToCStringIndent()

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

Definition at line 469 of file jsonb.c.

References JsonbToCStringWorker().

Referenced by jsonb_pretty().

470 {
471  return JsonbToCStringWorker(out, in, estimated_len, true);
472 }
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition: jsonb.c:478

◆ JsonbToJsonbValue()

void JsonbToJsonbValue ( Jsonb jsonb,
JsonbValue val 
)

Definition at line 72 of file jsonb_util.c.

References jbvBinary, Jsonb::root, JsonbValue::type, JsonbValue::val, VARHDRSZ, and VARSIZE.

Referenced by jsonb_insert(), jsonb_set(), and jsonb_subscript_assign().

73 {
74  val->type = jbvBinary;
75  val->val.binary.data = &jsonb->root;
76  val->val.binary.len = VARSIZE(jsonb) - VARHDRSZ;
77 }
#define VARSIZE(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:627
char * val
Definition: jsonb.h:272
JsonbContainer root
Definition: jsonb.h:223
enum jbvType type
Definition: jsonb.h:263

◆ JsonbTypeName()

const char* JsonbTypeName ( JsonbValue jb)

Definition at line 191 of file jsonb.c.

References elog, ERROR, jbvArray, jbvBinary, jbvBool, jbvDatetime, 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  case jbvDatetime:
210  switch (jbv->val.datetime.typid)
211  {
212  case DATEOID:
213  return "date";
214  case TIMEOID:
215  return "time without time zone";
216  case TIMETZOID:
217  return "time with time zone";
218  case TIMESTAMPOID:
219  return "timestamp without time zone";
220  case TIMESTAMPTZOID:
221  return "timestamp with time zone";
222  default:
223  elog(ERROR, "unrecognized jsonb value datetime type: %d",
224  jbv->val.datetime.typid);
225  }
226  return "unknown";
227  default:
228  elog(ERROR, "unrecognized jsonb value type: %d", jbv->type);
229  return "unknown";
230  }
231 }
Definition: jsonb.h:239
Definition: jsonb.h:236
#define ERROR
Definition: elog.h:45
static const char * JsonbContainerTypeName(JsonbContainer *jbc)
Definition: jsonb.c:170
#define elog(elevel,...)
Definition: elog.h:227

◆ JsonbValueToJsonb()

Jsonb* JsonbValueToJsonb ( JsonbValue val)

Definition at line 92 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(), 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_get_element(), jsonb_insert(), jsonb_object(), jsonb_object_agg_finalfn(), jsonb_object_agg_transfn(), jsonb_object_field(), jsonb_object_two_arg(), jsonb_path_query_array_internal(), jsonb_path_query_first_internal(), jsonb_path_query_internal(), jsonb_set(), jsonb_set_element(), jsonb_strip_nulls(), jsonb_subscript_assign(), plperl_to_jsonb(), plpython_to_jsonb(), populate_scalar(), to_jsonb(), and transform_jsonb_string_values().

93 {
94  Jsonb *out;
95 
96  if (IsAJsonbScalar(val))
97  {
98  /* Scalar value */
99  JsonbParseState *pstate = NULL;
100  JsonbValue *res;
101  JsonbValue scalarArray;
102 
103  scalarArray.type = jbvArray;
104  scalarArray.val.array.rawScalar = true;
105  scalarArray.val.array.nElems = 1;
106 
107  pushJsonbValue(&pstate, WJB_BEGIN_ARRAY, &scalarArray);
108  pushJsonbValue(&pstate, WJB_ELEM, val);
109  res = pushJsonbValue(&pstate, WJB_END_ARRAY, NULL);
110 
111  out = convertToJsonb(res);
112  }
113  else if (val->type == jbvObject || val->type == jbvArray)
114  {
115  out = convertToJsonb(val);
116  }
117  else
118  {
119  Assert(val->type == jbvBinary);
120  out = palloc(VARHDRSZ + val->val.binary.len);
121  SET_VARSIZE(out, VARHDRSZ + val->val.binary.len);
122  memcpy(VARDATA(out), val->val.binary.data, val->val.binary.len);
123  }
124 
125  return out;
126 }
#define VARDATA(PTR)
Definition: postgres.h:302
Definition: jsonb.h:220
#define VARHDRSZ
Definition: c.h:627
char * val
Definition: jsonb.h:272
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:566
#define Assert(condition)
Definition: c.h:804
static Jsonb * convertToJsonb(JsonbValue *val)
Definition: jsonb_util.c:1543
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:305
enum jbvType type
Definition: jsonb.h:263
void * palloc(Size size)
Definition: mcxt.c:950
#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 566 of file jsonb_util.c.

References Assert, i, JB_FSCALAR, jbvArray, jbvBinary, jbvObject, JsonbIteratorInit(), JsonbIteratorNext(), pushJsonbValue(), pushJsonbValueScalar(), 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 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(), push_null_elements(), push_path(), pushJsonbValue(), setPath(), setPathArray(), setPathObject(), SV_to_JsonbValue(), transform_jsonb_string_values(), and wrapItemsInArray().

568 {
569  JsonbIterator *it;
570  JsonbValue *res = NULL;
571  JsonbValue v;
572  JsonbIteratorToken tok;
573  int i;
574 
575  if (jbval && (seq == WJB_ELEM || seq == WJB_VALUE) && jbval->type == jbvObject)
576  {
577  pushJsonbValue(pstate, WJB_BEGIN_OBJECT, NULL);
578  for (i = 0; i < jbval->val.object.nPairs; i++)
579  {
580  pushJsonbValue(pstate, WJB_KEY, &jbval->val.object.pairs[i].key);
581  pushJsonbValue(pstate, WJB_VALUE, &jbval->val.object.pairs[i].value);
582  }
583 
584  return pushJsonbValue(pstate, WJB_END_OBJECT, NULL);
585  }
586 
587  if (jbval && (seq == WJB_ELEM || seq == WJB_VALUE) && jbval->type == jbvArray)
588  {
589  pushJsonbValue(pstate, WJB_BEGIN_ARRAY, NULL);
590  for (i = 0; i < jbval->val.array.nElems; i++)
591  {
592  pushJsonbValue(pstate, WJB_ELEM, &jbval->val.array.elems[i]);
593  }
594 
595  return pushJsonbValue(pstate, WJB_END_ARRAY, NULL);
596  }
597 
598  if (!jbval || (seq != WJB_ELEM && seq != WJB_VALUE) ||
599  jbval->type != jbvBinary)
600  {
601  /* drop through */
602  return pushJsonbValueScalar(pstate, seq, jbval);
603  }
604 
605  /* unpack the binary and add each piece to the pstate */
606  it = JsonbIteratorInit(jbval->val.binary.data);
607 
608  if ((jbval->val.binary.data->header & JB_FSCALAR) && *pstate)
609  {
610  tok = JsonbIteratorNext(&it, &v, true);
611  Assert(tok == WJB_BEGIN_ARRAY);
612  Assert(v.type == jbvArray && v.val.array.rawScalar);
613 
614  tok = JsonbIteratorNext(&it, &v, true);
615  Assert(tok == WJB_ELEM);
616 
617  res = pushJsonbValueScalar(pstate, seq, &v);
618 
619  tok = JsonbIteratorNext(&it, &v, true);
620  Assert(tok == WJB_END_ARRAY);
621  Assert(it == NULL);
622 
623  return res;
624  }
625 
626  while ((tok = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
627  res = pushJsonbValueScalar(pstate, tok,
628  tok < WJB_BEGIN_ARRAY ||
629  (tok == WJB_BEGIN_ARRAY &&
630  v.val.array.rawScalar) ? &v : NULL);
631 
632  return res;
633 }
char * val
Definition: jsonb.h:272
Definition: jsonb.h:22
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:566
#define JB_FSCALAR
Definition: jsonb.h:209
Definition: jsonb.h:23
static JsonbValue * pushJsonbValueScalar(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *scalarVal)
Definition: jsonb_util.c:640
JsonbIteratorToken
Definition: jsonb.h:20
#define Assert(condition)
Definition: c.h:804
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:812
enum jbvType type
Definition: jsonb.h:263
int i
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:848
Definition: jsonb.h:25