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 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)
 
#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)
 

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

static JsonbDatumGetJsonbP (Datum d)
 
static JsonbDatumGetJsonbPCopy (Datum d)
 
static Datum JsonbPGetDatum (const Jsonb *p)
 
uint32 getJsonbOffset (const JsonbContainer *jc, int index)
 
uint32 getJsonbLength (const JsonbContainer *jc, int index)
 
int compareJsonbContainers (JsonbContainer *a, JsonbContainer *b)
 
JsonbValuefindJsonbValueFromContainer (JsonbContainer *container, uint32 flags, JsonbValue *key)
 
JsonbValuegetKeyJsonValueFromContainer (JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
 
JsonbValuegetIthJsonbValueFromContainer (JsonbContainer *container, 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 *val)
 
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

◆ IsAJsonbScalar

#define IsAJsonbScalar (   jsonbval)
Value:
(((jsonbval)->type >= jbvNull && \
(jsonbval)->type <= jbvBool) || \
(jsonbval)->type == jbvDatetime)
@ jbvBool
Definition: jsonb.h:231
@ jbvNull
Definition: jsonb.h:228
@ jbvDatetime
Definition: jsonb.h:244

Definition at line 297 of file jsonb.h.

◆ JB_CMASK

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

Definition at line 200 of file jsonb.h.

◆ JB_FARRAY

#define JB_FARRAY   0x40000000

Definition at line 203 of file jsonb.h.

◆ JB_FOBJECT

#define JB_FOBJECT   0x20000000

Definition at line 202 of file jsonb.h.

◆ JB_FSCALAR

#define JB_FSCALAR   0x10000000 /* flag bits */

Definition at line 201 of file jsonb.h.

◆ JB_OFFSET_STRIDE

#define JB_OFFSET_STRIDE   32

Definition at line 178 of file jsonb.h.

◆ JB_ROOT_COUNT

#define JB_ROOT_COUNT (   jbp_)    (*(uint32 *) VARDATA(jbp_) & JB_CMASK)

Definition at line 219 of file jsonb.h.

◆ JB_ROOT_IS_ARRAY

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

Definition at line 222 of file jsonb.h.

◆ JB_ROOT_IS_OBJECT

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

Definition at line 221 of file jsonb.h.

◆ JB_ROOT_IS_SCALAR

#define JB_ROOT_IS_SCALAR (   jbp_)    ((*(uint32 *) VARDATA(jbp_) & JB_FSCALAR) != 0)

Definition at line 220 of file jsonb.h.

◆ 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_HAS_OFF(je_)
Definition: jsonb.h:152
#define JBE_OFFLENFLD(je_)
Definition: jsonb.h:151

Definition at line 162 of file jsonb.h.

◆ JBE_HAS_OFF

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

Definition at line 152 of file jsonb.h.

◆ JBE_ISBOOL

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

Definition at line 159 of file jsonb.h.

◆ JBE_ISBOOL_FALSE

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

Definition at line 158 of file jsonb.h.

◆ JBE_ISBOOL_TRUE

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

Definition at line 157 of file jsonb.h.

◆ JBE_ISCONTAINER

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

Definition at line 155 of file jsonb.h.

◆ JBE_ISNULL

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

Definition at line 156 of file jsonb.h.

◆ JBE_ISNUMERIC

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

Definition at line 154 of file jsonb.h.

◆ JBE_ISSTRING

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

Definition at line 153 of file jsonb.h.

◆ JBE_OFFLENFLD

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

Definition at line 151 of file jsonb.h.

◆ JENTRY_HAS_OFF

#define JENTRY_HAS_OFF   0x80000000

Definition at line 140 of file jsonb.h.

◆ JENTRY_ISBOOL_FALSE

#define JENTRY_ISBOOL_FALSE   0x20000000

Definition at line 145 of file jsonb.h.

◆ JENTRY_ISBOOL_TRUE

#define JENTRY_ISBOOL_TRUE   0x30000000

Definition at line 146 of file jsonb.h.

◆ JENTRY_ISCONTAINER

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

Definition at line 148 of file jsonb.h.

◆ JENTRY_ISNULL

#define JENTRY_ISNULL   0x40000000

Definition at line 147 of file jsonb.h.

◆ JENTRY_ISNUMERIC

#define JENTRY_ISNUMERIC   0x10000000

Definition at line 144 of file jsonb.h.

◆ JENTRY_ISSTRING

#define JENTRY_ISSTRING   0x00000000

Definition at line 143 of file jsonb.h.

◆ JENTRY_OFFLENMASK

#define JENTRY_OFFLENMASK   0x0FFFFFFF

Definition at line 138 of file jsonb.h.

◆ JENTRY_TYPEMASK

#define JENTRY_TYPEMASK   0x70000000

Definition at line 139 of file jsonb.h.

◆ JGIN_MAXLENGTH

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

Definition at line 68 of file jsonb.h.

◆ JGINFLAG_BOOL

#define JGINFLAG_BOOL   0x03 /* boolean value */

Definition at line 64 of file jsonb.h.

◆ JGINFLAG_HASHED

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

Definition at line 67 of file jsonb.h.

◆ JGINFLAG_KEY

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

Definition at line 62 of file jsonb.h.

◆ JGINFLAG_NULL

#define JGINFLAG_NULL   0x02 /* null value */

Definition at line 63 of file jsonb.h.

◆ JGINFLAG_NUM

#define JGINFLAG_NUM   0x04 /* numeric value */

Definition at line 65 of file jsonb.h.

◆ JGINFLAG_STR

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

Definition at line 66 of file jsonb.h.

◆ JsonbContainsStrategyNumber

#define JsonbContainsStrategyNumber   7

Definition at line 33 of file jsonb.h.

◆ JsonbExistsAllStrategyNumber

#define JsonbExistsAllStrategyNumber   11

Definition at line 36 of file jsonb.h.

◆ JsonbExistsAnyStrategyNumber

#define JsonbExistsAnyStrategyNumber   10

Definition at line 35 of file jsonb.h.

◆ JsonbExistsStrategyNumber

#define JsonbExistsStrategyNumber   9

Definition at line 34 of file jsonb.h.

◆ JsonbJsonpathExistsStrategyNumber

#define JsonbJsonpathExistsStrategyNumber   15

Definition at line 37 of file jsonb.h.

◆ JsonbJsonpathPredicateStrategyNumber

#define JsonbJsonpathPredicateStrategyNumber   16

Definition at line 38 of file jsonb.h.

◆ JsonContainerIsArray

#define JsonContainerIsArray (   jc)    (((jc)->header & JB_FARRAY) != 0)

Definition at line 209 of file jsonb.h.

◆ JsonContainerIsObject

#define JsonContainerIsObject (   jc)    (((jc)->header & JB_FOBJECT) != 0)

Definition at line 208 of file jsonb.h.

◆ JsonContainerIsScalar

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

Definition at line 207 of file jsonb.h.

◆ JsonContainerSize

#define JsonContainerSize (   jc)    ((jc)->header & JB_CMASK)

Definition at line 206 of file jsonb.h.

◆ PG_GETARG_JSONB_P

#define PG_GETARG_JSONB_P (   x)    DatumGetJsonbP(PG_GETARG_DATUM(x))

Definition at line 389 of file jsonb.h.

◆ PG_GETARG_JSONB_P_COPY

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

Definition at line 390 of file jsonb.h.

◆ PG_RETURN_JSONB_P

#define PG_RETURN_JSONB_P (   x)    PG_RETURN_POINTER(x)

Definition at line 391 of file jsonb.h.

Typedef Documentation

◆ JEntry

typedef uint32 JEntry

Definition at line 136 of file jsonb.h.

◆ JsonbContainer

◆ JsonbIterator

typedef struct JsonbIterator JsonbIterator

◆ JsonbPair

typedef struct JsonbPair JsonbPair

Definition at line 1 of file jsonb.h.

◆ JsonbParseState

◆ JsonbValue

typedef struct JsonbValue JsonbValue

Definition at line 1 of file jsonb.h.

Enumeration Type Documentation

◆ jbvType

enum jbvType
Enumerator
jbvNull 
jbvString 
jbvNumeric 
jbvBool 
jbvArray 
jbvObject 
jbvBinary 
jbvDatetime 

Definition at line 225 of file jsonb.h.

226 {
227  /* Scalar types */
228  jbvNull = 0x0,
229  jbvString,
230  jbvNumeric,
231  jbvBool,
232  /* Composite types */
233  jbvArray = 0x10,
234  jbvObject,
235  /* Binary (i.e. struct Jsonb) jbvArray/jbvObject */
236  jbvBinary,
237 
238  /*
239  * Virtual types.
240  *
241  * These types are used only for in-memory JSON processing and serialized
242  * into JSON strings when outputted to json/jsonb.
243  */
244  jbvDatetime = 0x20,
245 };
@ jbvObject
Definition: jsonb.h:234
@ jbvNumeric
Definition: jsonb.h:230
@ jbvArray
Definition: jsonb.h:233
@ jbvBinary
Definition: jsonb.h:236
@ jbvString
Definition: jsonb.h:229

◆ 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,
JsonbIteratorToken
Definition: jsonb.h:21
@ WJB_KEY
Definition: jsonb.h:23
@ WJB_DONE
Definition: jsonb.h:22
@ WJB_END_ARRAY
Definition: jsonb.h:27
@ WJB_VALUE
Definition: jsonb.h:24
@ WJB_END_OBJECT
Definition: jsonb.h:29
@ WJB_ELEM
Definition: jsonb.h:25
@ WJB_BEGIN_OBJECT
Definition: jsonb.h:28
@ WJB_BEGIN_ARRAY
Definition: jsonb.h:26

◆ JsonbIterState

Enumerator
JBI_ARRAY_START 
JBI_ARRAY_ELEM 
JBI_OBJECT_START 
JBI_OBJECT_KEY 
JBI_OBJECT_VALUE 

Definition at line 330 of file jsonb.h.

331 {
JsonbIterState
Definition: jsonb.h:331
@ JBI_OBJECT_VALUE
Definition: jsonb.h:336
@ JBI_ARRAY_START
Definition: jsonb.h:332
@ JBI_ARRAY_ELEM
Definition: jsonb.h:333
@ JBI_OBJECT_START
Definition: jsonb.h:334
@ JBI_OBJECT_KEY
Definition: jsonb.h:335

Function Documentation

◆ compareJsonbContainers()

int compareJsonbContainers ( JsonbContainer a,
JsonbContainer b 
)

Definition at line 192 of file jsonb_util.c.

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

References a, Assert(), b, compareJsonbScalarValue(), elog(), ERROR, i, jbvArray, jbvBinary, jbvBool, jbvDatetime, jbvNull, jbvNumeric, jbvObject, jbvString, JsonbIteratorInit(), JsonbIteratorNext(), JsonbIterator::parent, pfree(), res, 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().

◆ DatumGetJsonbP()

static Jsonb* DatumGetJsonbP ( Datum  d)
inlinestatic

Definition at line 372 of file jsonb.h.

373 {
374  return (Jsonb *) PG_DETOAST_DATUM(d);
375 }
#define PG_DETOAST_DATUM(datum)
Definition: fmgr.h:240
Definition: jsonb.h:213

References PG_DETOAST_DATUM.

Referenced by datum_to_jsonb(), jsonb_subscript_assign(), jsonb_subscript_fetch(), and jsonb_subscript_fetch_old().

◆ DatumGetJsonbPCopy()

static Jsonb* DatumGetJsonbPCopy ( Datum  d)
inlinestatic

Definition at line 378 of file jsonb.h.

379 {
380  return (Jsonb *) PG_DETOAST_DATUM_COPY(d);
381 }
#define PG_DETOAST_DATUM_COPY(datum)
Definition: fmgr.h:242

References PG_DETOAST_DATUM_COPY.

◆ findJsonbValueFromContainer()

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

Definition at line 345 of file jsonb_util.c.

347 {
348  JEntry *children = container->children;
349  int count = JsonContainerSize(container);
350 
351  Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
352 
353  /* Quick out without a palloc cycle if object/array is empty */
354  if (count <= 0)
355  return NULL;
356 
357  if ((flags & JB_FARRAY) && JsonContainerIsArray(container))
358  {
359  JsonbValue *result = palloc(sizeof(JsonbValue));
360  char *base_addr = (char *) (children + count);
361  uint32 offset = 0;
362  int i;
363 
364  for (i = 0; i < count; i++)
365  {
366  fillJsonbValue(container, i, base_addr, offset, result);
367 
368  if (key->type == result->type)
369  {
370  if (equalsJsonbScalarValue(key, result))
371  return result;
372  }
373 
374  JBE_ADVANCE_OFFSET(offset, children[i]);
375  }
376 
377  pfree(result);
378  }
379  else if ((flags & JB_FOBJECT) && JsonContainerIsObject(container))
380  {
381  /* Object key passed by caller must be a string */
382  Assert(key->type == jbvString);
383 
384  return getKeyJsonValueFromContainer(container, key->val.string.val,
385  key->val.string.len, NULL);
386  }
387 
388  /* Not found */
389  return NULL;
390 }
unsigned int uint32
Definition: c.h:490
#define JsonContainerIsArray(jc)
Definition: jsonb.h:209
#define JsonContainerSize(jc)
Definition: jsonb.h:206
#define JsonContainerIsObject(jc)
Definition: jsonb.h:208
#define JB_FARRAY
Definition: jsonb.h:203
uint32 JEntry
Definition: jsonb.h:136
#define JB_FOBJECT
Definition: jsonb.h:202
#define JBE_ADVANCE_OFFSET(offset, je)
Definition: jsonb.h:162
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition: jsonb_util.c:506
JsonbValue * getKeyJsonValueFromContainer(JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
Definition: jsonb_util.c:399
static bool equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b)
Definition: jsonb_util.c:1397
void * palloc(Size size)
Definition: mcxt.c:1210
JEntry children[FLEXIBLE_ARRAY_MEMBER]
Definition: jsonb.h:194

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

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

◆ getIthJsonbValueFromContainer()

JsonbValue* getIthJsonbValueFromContainer ( JsonbContainer container,
uint32  i 
)

Definition at line 469 of file jsonb_util.c.

470 {
471  JsonbValue *result;
472  char *base_addr;
473  uint32 nelements;
474 
475  if (!JsonContainerIsArray(container))
476  elog(ERROR, "not a jsonb array");
477 
478  nelements = JsonContainerSize(container);
479  base_addr = (char *) &container->children[nelements];
480 
481  if (i >= nelements)
482  return NULL;
483 
484  result = palloc(sizeof(JsonbValue));
485 
486  fillJsonbValue(container, i, base_addr,
487  getJsonbOffset(container, i),
488  result);
489 
490  return result;
491 }
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:135

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

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

◆ getJsonbLength()

uint32 getJsonbLength ( const JsonbContainer jc,
int  index 
)

Definition at line 160 of file jsonb_util.c.

161 {
162  uint32 off;
163  uint32 len;
164 
165  /*
166  * If the length is stored directly in the JEntry, just return it.
167  * Otherwise, get the begin offset of the entry, and subtract that from
168  * the stored end+1 offset.
169  */
170  if (JBE_HAS_OFF(jc->children[index]))
171  {
172  off = getJsonbOffset(jc, index);
173  len = JBE_OFFLENFLD(jc->children[index]) - off;
174  }
175  else
177 
178  return len;
179 }
const void size_t len
Definition: type.h:95

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

Referenced by fillJsonbValue(), and getKeyJsonValueFromContainer().

◆ getJsonbOffset()

uint32 getJsonbOffset ( const JsonbContainer jc,
int  index 
)

Definition at line 135 of file jsonb_util.c.

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

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

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

◆ getKeyJsonValueFromContainer()

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

Definition at line 399 of file jsonb_util.c.

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

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

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

◆ jsonb_get_element()

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

Definition at line 1518 of file jsonfuncs.c.

1519 {
1520  JsonbContainer *container = &jb->root;
1521  JsonbValue *jbvp = NULL;
1522  int i;
1523  bool have_object = false,
1524  have_array = false;
1525 
1526  *isnull = false;
1527 
1528  /* Identify whether we have object, array, or scalar at top-level */
1529  if (JB_ROOT_IS_OBJECT(jb))
1530  have_object = true;
1531  else if (JB_ROOT_IS_ARRAY(jb) && !JB_ROOT_IS_SCALAR(jb))
1532  have_array = true;
1533  else
1534  {
1536  /* Extract the scalar value, if it is what we'll return */
1537  if (npath <= 0)
1538  jbvp = getIthJsonbValueFromContainer(container, 0);
1539  }
1540 
1541  /*
1542  * If the array is empty, return the entire LHS object, on the grounds
1543  * that we should do zero field or element extractions. For the
1544  * non-scalar case we can just hand back the object without much work. For
1545  * the scalar case, fall through and deal with the value below the loop.
1546  * (This inconsistency arises because there's no easy way to generate a
1547  * JsonbValue directly for root-level containers.)
1548  */
1549  if (npath <= 0 && jbvp == NULL)
1550  {
1551  if (as_text)
1552  {
1554  container,
1555  VARSIZE(jb))));
1556  }
1557  else
1558  {
1559  /* not text mode - just hand back the jsonb */
1560  PG_RETURN_JSONB_P(jb);
1561  }
1562  }
1563 
1564  for (i = 0; i < npath; i++)
1565  {
1566  if (have_object)
1567  {
1568  text *subscr = DatumGetTextPP(path[i]);
1569 
1570  jbvp = getKeyJsonValueFromContainer(container,
1571  VARDATA_ANY(subscr),
1572  VARSIZE_ANY_EXHDR(subscr),
1573  NULL);
1574  }
1575  else if (have_array)
1576  {
1577  int lindex;
1578  uint32 index;
1579  char *indextext = TextDatumGetCString(path[i]);
1580  char *endptr;
1581 
1582  errno = 0;
1583  lindex = strtoint(indextext, &endptr, 10);
1584  if (endptr == indextext || *endptr != '\0' || errno != 0)
1585  {
1586  *isnull = true;
1587  return PointerGetDatum(NULL);
1588  }
1589 
1590  if (lindex >= 0)
1591  {
1592  index = (uint32) lindex;
1593  }
1594  else
1595  {
1596  /* Handle negative subscript */
1597  uint32 nelements;
1598 
1599  /* Container must be array, but make sure */
1600  if (!JsonContainerIsArray(container))
1601  elog(ERROR, "not a jsonb array");
1602 
1603  nelements = JsonContainerSize(container);
1604 
1605  if (lindex == INT_MIN || -lindex > nelements)
1606  {
1607  *isnull = true;
1608  return PointerGetDatum(NULL);
1609  }
1610  else
1611  index = nelements + lindex;
1612  }
1613 
1614  jbvp = getIthJsonbValueFromContainer(container, index);
1615  }
1616  else
1617  {
1618  /* scalar, extraction yields a null */
1619  *isnull = true;
1620  return PointerGetDatum(NULL);
1621  }
1622 
1623  if (jbvp == NULL)
1624  {
1625  *isnull = true;
1626  return PointerGetDatum(NULL);
1627  }
1628  else if (i == npath - 1)
1629  break;
1630 
1631  if (jbvp->type == jbvBinary)
1632  {
1633  container = jbvp->val.binary.data;
1634  have_object = JsonContainerIsObject(container);
1635  have_array = JsonContainerIsArray(container);
1636  Assert(!JsonContainerIsScalar(container));
1637  }
1638  else
1639  {
1640  Assert(IsAJsonbScalar(jbvp));
1641  have_object = false;
1642  have_array = false;
1643  }
1644  }
1645 
1646  if (as_text)
1647  {
1648  if (jbvp->type == jbvNull)
1649  {
1650  *isnull = true;
1651  return PointerGetDatum(NULL);
1652  }
1653 
1654  return PointerGetDatum(JsonbValueAsText(jbvp));
1655  }
1656  else
1657  {
1658  Jsonb *res = JsonbValueToJsonb(jbvp);
1659 
1660  /* not text mode - just hand back the jsonb */
1662  }
1663 }
#define TextDatumGetCString(d)
Definition: builtins.h:95
#define DatumGetTextPP(X)
Definition: fmgr.h:292
char * JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
Definition: jsonb.c:483
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:207
#define JB_ROOT_IS_OBJECT(jbp_)
Definition: jsonb.h:221
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:297
#define PG_RETURN_JSONB_P(x)
Definition: jsonb.h:391
#define JB_ROOT_IS_ARRAY(jbp_)
Definition: jsonb.h:222
#define JB_ROOT_IS_SCALAR(jbp_)
Definition: jsonb.h:220
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:93
JsonbValue * getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)
Definition: jsonb_util.c:469
static text * JsonbValueAsText(JsonbValue *v)
Definition: jsonfuncs.c:1792
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
Definition: string.c:51
JsonbContainer root
Definition: jsonb.h:215
Definition: c.h:671
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE(PTR)
Definition: varatt.h:279
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317
text * cstring_to_text(const char *s)
Definition: varlena.c:189

References Assert(), cstring_to_text(), DatumGetTextPP, 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(), res, Jsonb::root, strtoint(), TextDatumGetCString, JsonbValue::type, JsonbValue::val, VARDATA_ANY, VARSIZE, and VARSIZE_ANY_EXHDR.

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

◆ jsonb_set_element()

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

Definition at line 1666 of file jsonfuncs.c.

1668 {
1669  JsonbValue *res;
1670  JsonbParseState *state = NULL;
1671  JsonbIterator *it;
1672  bool *path_nulls = palloc0(path_len * sizeof(bool));
1673 
1674  if (newval->type == jbvArray && newval->val.array.rawScalar)
1675  *newval = newval->val.array.elems[0];
1676 
1677  it = JsonbIteratorInit(&jb->root);
1678 
1679  res = setPath(&it, path, path_nulls, path_len, &state, 0, newval,
1682 
1683  pfree(path_nulls);
1684 
1686 }
#define newval
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:4903
#define JB_PATH_CREATE
Definition: jsonfuncs.c:42
#define JB_PATH_CONSISTENT_POSITION
Definition: jsonfuncs.c:50
#define JB_PATH_FILL_GAPS
Definition: jsonfuncs.c:49
void * palloc0(Size size)
Definition: mcxt.c:1241
Definition: regguts.h:318

References JB_PATH_CONSISTENT_POSITION, JB_PATH_CREATE, JB_PATH_FILL_GAPS, jbvArray, JsonbIteratorInit(), JsonbValueToJsonb(), newval, palloc0(), pfree(), PG_RETURN_JSONB_P, res, Jsonb::root, and setPath().

Referenced by jsonb_subscript_assign().

◆ JsonbDeepContains()

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

Definition at line 1058 of file jsonb_util.c.

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

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

Referenced by jsonb_contained(), and jsonb_contains().

◆ JsonbExtractScalar()

bool JsonbExtractScalar ( JsonbContainer jbc,
JsonbValue res 
)

Definition at line 1913 of file jsonb.c.

1914 {
1915  JsonbIterator *it;
1917  JsonbValue tmp;
1918 
1919  if (!JsonContainerIsArray(jbc) || !JsonContainerIsScalar(jbc))
1920  {
1921  /* inform caller about actual type of container */
1922  res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
1923  return false;
1924  }
1925 
1926  /*
1927  * A root scalar is stored as an array of one element, so we get the array
1928  * and then its first (and only) member.
1929  */
1930  it = JsonbIteratorInit(jbc);
1931 
1932  tok = JsonbIteratorNext(&it, &tmp, true);
1933  Assert(tok == WJB_BEGIN_ARRAY);
1934  Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
1935 
1936  tok = JsonbIteratorNext(&it, res, true);
1937  Assert(tok == WJB_ELEM);
1939 
1940  tok = JsonbIteratorNext(&it, &tmp, true);
1941  Assert(tok == WJB_END_ARRAY);
1942 
1943  tok = JsonbIteratorNext(&it, &tmp, true);
1944  Assert(tok == WJB_DONE);
1945 
1946  return true;
1947 }
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:166

References Assert(), IsAJsonbScalar, jbvArray, jbvObject, JsonbIteratorInit(), JsonbIteratorNext(), JsonContainerIsArray, JsonContainerIsScalar, PG_USED_FOR_ASSERTS_ONLY, res, 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().

◆ JsonbHashScalarValue()

void JsonbHashScalarValue ( const JsonbValue scalarVal,
uint32 hash 
)

Definition at line 1312 of file jsonb_util.c.

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

References DatumGetUInt32(), DirectFunctionCall1, elog(), ERROR, hash(), hash_any(), hash_numeric(), jbvBool, jbvNull, jbvNumeric, jbvString, NumericGetDatum(), pg_rotate_left32(), 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().

◆ JsonbHashScalarValueExtended()

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

Definition at line 1355 of file jsonb_util.c.

1357 {
1358  uint64 tmp;
1359 
1360  switch (scalarVal->type)
1361  {
1362  case jbvNull:
1363  tmp = seed + 0x01;
1364  break;
1365  case jbvString:
1366  tmp = DatumGetUInt64(hash_any_extended((const unsigned char *) scalarVal->val.string.val,
1367  scalarVal->val.string.len,
1368  seed));
1369  break;
1370  case jbvNumeric:
1372  NumericGetDatum(scalarVal->val.numeric),
1373  UInt64GetDatum(seed)));
1374  break;
1375  case jbvBool:
1376  if (seed)
1378  BoolGetDatum(scalarVal->val.boolean),
1379  UInt64GetDatum(seed)));
1380  else
1381  tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1382 
1383  break;
1384  default:
1385  elog(ERROR, "invalid jsonb scalar type");
1386  break;
1387  }
1388 
1390  *hash ^= tmp;
1391 }
Datum hash_numeric_extended(PG_FUNCTION_ARGS)
Definition: numeric.c:2765
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:644
#define ROTATE_HIGH_AND_LOW_32BITS(v)
Definition: hashfn.h:18
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Definition: hashfn.h:37
Datum hashcharextended(PG_FUNCTION_ARGS)
Definition: hashfunc.c:55
static uint64 DatumGetUInt64(Datum X)
Definition: postgres.h:419
static Datum UInt64GetDatum(uint64 X)
Definition: postgres.h:436
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102

References BoolGetDatum(), DatumGetUInt64(), DirectFunctionCall2, elog(), ERROR, hash(), 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().

◆ JsonbIteratorInit()

◆ JsonbIteratorNext()

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

Definition at line 849 of file jsonb_util.c.

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

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

◆ JsonbPGetDatum()

static Datum JsonbPGetDatum ( const Jsonb p)
inlinestatic

Definition at line 384 of file jsonb.h.

385 {
386  return PointerGetDatum(p);
387 }

References PointerGetDatum().

Referenced by jsonb_path_query_internal(), and populate_scalar().

◆ JsonbToCString()

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

Definition at line 483 of file jsonb.c.

484 {
485  return JsonbToCStringWorker(out, in, estimated_len, false);
486 }
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition: jsonb.c:501

References JsonbToCStringWorker().

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

◆ JsonbToCStringIndent()

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

Definition at line 492 of file jsonb.c.

493 {
494  return JsonbToCStringWorker(out, in, estimated_len, true);
495 }

References JsonbToCStringWorker().

Referenced by jsonb_pretty().

◆ JsonbToJsonbValue()

void JsonbToJsonbValue ( Jsonb jsonb,
JsonbValue val 
)

Definition at line 73 of file jsonb_util.c.

74 {
75  val->type = jbvBinary;
76  val->val.binary.data = &jsonb->root;
77  val->val.binary.len = VARSIZE(jsonb) - VARHDRSZ;
78 }
#define VARHDRSZ
Definition: c.h:676

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

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

◆ JsonbTypeName()

const char* JsonbTypeName ( JsonbValue val)

Definition at line 192 of file jsonb.c.

193 {
194  switch (val->type)
195  {
196  case jbvBinary:
197  return JsonbContainerTypeName(val->val.binary.data);
198  case jbvObject:
199  return "object";
200  case jbvArray:
201  return "array";
202  case jbvNumeric:
203  return "number";
204  case jbvString:
205  return "string";
206  case jbvBool:
207  return "boolean";
208  case jbvNull:
209  return "null";
210  case jbvDatetime:
211  switch (val->val.datetime.typid)
212  {
213  case DATEOID:
214  return "date";
215  case TIMEOID:
216  return "time without time zone";
217  case TIMETZOID:
218  return "time with time zone";
219  case TIMESTAMPOID:
220  return "timestamp without time zone";
221  case TIMESTAMPTZOID:
222  return "timestamp with time zone";
223  default:
224  elog(ERROR, "unrecognized jsonb value datetime type: %d",
225  val->val.datetime.typid);
226  }
227  return "unknown";
228  default:
229  elog(ERROR, "unrecognized jsonb value type: %d", val->type);
230  return "unknown";
231  }
232 }
static const char * JsonbContainerTypeName(JsonbContainer *jbc)
Definition: jsonb.c:171

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

Referenced by executeItemOptUnwrapTarget(), and JsonbContainerTypeName().

◆ JsonbValueToJsonb()

Jsonb* JsonbValueToJsonb ( JsonbValue val)

Definition at line 93 of file jsonb_util.c.

94 {
95  Jsonb *out;
96 
97  if (IsAJsonbScalar(val))
98  {
99  /* Scalar value */
100  JsonbParseState *pstate = NULL;
101  JsonbValue *res;
102  JsonbValue scalarArray;
103 
104  scalarArray.type = jbvArray;
105  scalarArray.val.array.rawScalar = true;
106  scalarArray.val.array.nElems = 1;
107 
108  pushJsonbValue(&pstate, WJB_BEGIN_ARRAY, &scalarArray);
109  pushJsonbValue(&pstate, WJB_ELEM, val);
110  res = pushJsonbValue(&pstate, WJB_END_ARRAY, NULL);
111 
112  out = convertToJsonb(res);
113  }
114  else if (val->type == jbvObject || val->type == jbvArray)
115  {
116  out = convertToJsonb(val);
117  }
118  else
119  {
120  Assert(val->type == jbvBinary);
121  out = palloc(VARHDRSZ + val->val.binary.len);
122  SET_VARSIZE(out, VARHDRSZ + val->val.binary.len);
123  memcpy(VARDATA(out), val->val.binary.data, val->val.binary.len);
124  }
125 
126  return out;
127 }
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:567
static Jsonb * convertToJsonb(JsonbValue *val)
Definition: jsonb_util.c:1544
#define VARDATA(PTR)
Definition: varatt.h:278
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

References Assert(), convertToJsonb(), IsAJsonbScalar, jbvArray, jbvBinary, jbvObject, palloc(), pushJsonbValue(), res, SET_VARSIZE, JsonbValue::type, JsonbValue::val, 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().

◆ pushJsonbValue()

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

Definition at line 567 of file jsonb_util.c.

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

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