PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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  JsonbInState
 
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 struct JsonbParseState JsonbParseState
 
typedef uint32 JEntry
 
typedef struct JsonbContainer JsonbContainer
 
typedef struct JsonbInState JsonbInState
 
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)
 
void pushJsonbValue (JsonbInState *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)
 
charJsonbToCString (StringInfo out, JsonbContainer *in, int estimated_len)
 
charJsonbToCStringIndent (StringInfo out, JsonbContainer *in, int estimated_len)
 
charJsonbUnquote (Jsonb *jb)
 
bool JsonbExtractScalar (JsonbContainer *jbc, JsonbValue *res)
 
const charJsonbTypeName (JsonbValue *val)
 
Datum jsonb_set_element (Jsonb *jb, const Datum *path, int path_len, JsonbValue *newval)
 
Datum jsonb_get_element (Jsonb *jb, const Datum *path, int npath, bool *isnull, bool as_text)
 
bool to_jsonb_is_immutable (Oid typoid)
 
Datum jsonb_build_object_worker (int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null, bool unique_keys)
 
Datum jsonb_build_array_worker (int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
 

Macro Definition Documentation

◆ IsAJsonbScalar

#define IsAJsonbScalar (   jsonbval)
Value:
(((jsonbval)->type >= jbvNull && \
(jsonbval)->type <= jbvBool) || \
(jsonbval)->type == jbvDatetime)
@ jbvBool
Definition jsonb.h:233
@ jbvNull
Definition jsonb.h:230
@ jbvDatetime
Definition jsonb.h:246
static int fb(int x)
const char * type

Definition at line 299 of file jsonb.h.

313{
314 JsonbValue key; /* Must be a jbvString */
315 JsonbValue value; /* May be of any type */
316 uint32 order; /* Pair's index in original sequence */
317};
318
319/*
320 * State used while constructing or manipulating a JsonbValue.
321 * For example, when parsing Jsonb from text, we construct a JsonbValue
322 * data structure and then flatten that into the Jsonb on-disk format.
323 * JsonbValues are also useful in aggregation and type coercion.
324 *
325 * Callers providing a JsonbInState must initialize it to zeroes/nulls,
326 * except for optionally setting outcontext (if that's left NULL,
327 * CurrentMemoryContext is used) and escontext (if that's left NULL,
328 * parsing errors are thrown via ereport).
329 */
330typedef struct JsonbInState
331{
332 JsonbValue *result; /* The completed value; NULL until complete */
333 MemoryContext outcontext; /* The context to build it in, or NULL */
334 struct Node *escontext; /* Optional soft-error-reporting context */
335 /* Remaining fields should be treated as private to jsonb.c/jsonb_util.c */
336 JsonbParseState *parseState; /* Stack of parsing contexts */
337 bool unique_keys; /* Check object key uniqueness */
339
340/*
341 * Parsing context for one level of Jsonb array or object nesting.
342 * The contVal will be part of the constructed JsonbValue tree,
343 * but the other fields are just transient state.
344 */
345struct JsonbParseState
346{
347 JsonbValue contVal; /* An array or object JsonbValue */
348 Size size; /* Allocated length of array or object */
349 JsonbParseState *next; /* Link to next outer level, if any */
350 bool unique_keys; /* Check object key uniqueness */
351 bool skip_nulls; /* Skip null object fields */
352};
353
354/*
355 * JsonbIterator holds details of the type for each iteration. It also stores a
356 * Jsonb varlena buffer, which can be directly accessed in some contexts.
357 */
358typedef enum
359{
366
367typedef struct JsonbIterator
368{
369 /* Container being iterated */
371 uint32 nElems; /* Number of elements in children array (will
372 * be nPairs for objects) */
373 bool isScalar; /* Pseudo-array scalar value? */
374 JEntry *children; /* JEntrys for child nodes */
375 /* Data proper. This points to the beginning of the variable-length data */
376 char *dataProper;
377
378 /* Current item in buffer (up to nElems) */
379 int curIndex;
380
381 /* Data offset corresponding to current item */
383
384 /*
385 * If the container is an object, we want to return keys and values
386 * alternately; so curDataOffset points to the current key, and
387 * curValueOffset points to the current value.
388 */
390
391 /* Private state */
393
394 struct JsonbIterator *parent;
396
397
398/* Convenience macros */
399static inline Jsonb *
401{
402 return (Jsonb *) PG_DETOAST_DATUM(d);
403}
404
405static inline Jsonb *
407{
408 return (Jsonb *) PG_DETOAST_DATUM_COPY(d);
409}
410
411static inline Datum
412JsonbPGetDatum(const Jsonb *p)
413{
414 return PointerGetDatum(p);
415}
416
417#define PG_GETARG_JSONB_P(x) DatumGetJsonbP(PG_GETARG_DATUM(x))
418#define PG_GETARG_JSONB_P_COPY(x) DatumGetJsonbPCopy(PG_GETARG_DATUM(x))
419#define PG_RETURN_JSONB_P(x) PG_RETURN_POINTER(x)
420
421/* Support functions */
422extern uint32 getJsonbOffset(const JsonbContainer *jc, int index);
423extern uint32 getJsonbLength(const JsonbContainer *jc, int index);
426 uint32 flags,
427 JsonbValue *key);
429 const char *keyVal, int keyLen,
430 JsonbValue *res);
432 uint32 i);
433extern void pushJsonbValue(JsonbInState *pstate,
437 bool skipNested);
438extern void JsonbToJsonbValue(Jsonb *jsonb, JsonbValue *val);
444 uint64 *hash, uint64 seed);
445
446/* jsonb.c support functions */
447extern char *JsonbToCString(StringInfo out, JsonbContainer *in,
448 int estimated_len);
450 int estimated_len);
451extern char *JsonbUnquote(Jsonb *jb);
452extern bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res);
453extern const char *JsonbTypeName(JsonbValue *val);
454
455extern Datum jsonb_set_element(Jsonb *jb, const Datum *path, int path_len,
457extern Datum jsonb_get_element(Jsonb *jb, const Datum *path, int npath,
458 bool *isnull, bool as_text);
459extern bool to_jsonb_is_immutable(Oid typoid);
460extern Datum jsonb_build_object_worker(int nargs, const Datum *args, const bool *nulls,
461 const Oid *types, bool absent_on_null,
462 bool unique_keys);
463extern Datum jsonb_build_array_worker(int nargs, const Datum *args, const bool *nulls,
464 const Oid *types, bool absent_on_null);
465
466#endif /* __JSONB_H__ */
uint64_t uint64
Definition c.h:619
uint32_t uint32
Definition c.h:618
size_t Size
Definition c.h:691
struct typedefs * types
Definition ecpg.c:30
#define PG_DETOAST_DATUM_COPY(datum)
Definition fmgr.h:242
#define PG_DETOAST_DATUM(datum)
Definition fmgr.h:240
#define newval
long val
Definition informix.c:689
static struct @174 value
int b
Definition isn.c:74
int a
Definition isn.c:73
int i
Definition isn.c:77
JsonbIterState
Definition jsonb.h:360
@ JBI_OBJECT_VALUE
Definition jsonb.h:365
@ JBI_ARRAY_START
Definition jsonb.h:361
@ JBI_ARRAY_ELEM
Definition jsonb.h:362
@ JBI_OBJECT_START
Definition jsonb.h:363
@ JBI_OBJECT_KEY
Definition jsonb.h:364
static Jsonb * DatumGetJsonbPCopy(Datum d)
Definition jsonb.h:407
void pushJsonbValue(JsonbInState *pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition jsonb_util.c:583
char * JsonbUnquote(Jsonb *jb)
Definition jsonb.c:2010
Datum jsonb_build_array_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
Definition jsonb.c:1215
static Datum JsonbPGetDatum(const Jsonb *p)
Definition jsonb.h:413
JsonbValue * getKeyJsonValueFromContainer(JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
Definition jsonb_util.c:402
Datum jsonb_set_element(Jsonb *jb, const Datum *path, int path_len, JsonbValue *newval)
Definition jsonfuncs.c:1682
int compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
Definition jsonb_util.c:194
uint32 getJsonbLength(const JsonbContainer *jc, int index)
Definition jsonb_util.c:162
char * JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
Definition jsonb.c:465
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition jsonb_util.c:935
Datum jsonb_get_element(Jsonb *jb, const Datum *path, int npath, bool *isnull, bool as_text)
Definition jsonfuncs.c:1534
const char * JsonbTypeName(JsonbValue *val)
Definition jsonb.c:172
static Jsonb * DatumGetJsonbP(Datum d)
Definition jsonb.h:401
void JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash)
Datum jsonb_build_object_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null, bool unique_keys)
Definition jsonb.c:1130
void JsonbToJsonbValue(Jsonb *jsonb, JsonbValue *val)
Definition jsonb_util.c:76
uint32 JEntry
Definition jsonb.h:138
JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)
Definition jsonb_util.c:348
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition jsonb_util.c:973
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition jsonb_util.c:137
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition jsonb.c:1749
void JsonbHashScalarValueExtended(const JsonbValue *scalarVal, uint64 *hash, uint64 seed)
JsonbValue * getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)
Definition jsonb_util.c:472
JsonbIteratorToken
Definition jsonb.h:21
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition jsonb_util.c:96
char * JsonbToCStringIndent(StringInfo out, JsonbContainer *in, int estimated_len)
Definition jsonb.c:474
bool JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
bool to_jsonb_is_immutable(Oid typoid)
Definition jsonb.c:1081
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
uint64_t Datum
Definition postgres.h:70
unsigned int Oid
static unsigned hash(unsigned *uv, int n)
Definition rege_dfa.c:715
MemoryContext outcontext
Definition jsonb.h:334
JsonbValue * result
Definition jsonb.h:333
JsonbParseState * parseState
Definition jsonb.h:337
struct Node * escontext
Definition jsonb.h:335
bool unique_keys
Definition jsonb.h:338
uint32 curDataOffset
Definition jsonb.h:383
JsonbIterState state
Definition jsonb.h:393
JEntry * children
Definition jsonb.h:375
uint32 nElems
Definition jsonb.h:372
struct JsonbIterator * parent
Definition jsonb.h:395
JsonbContainer * container
Definition jsonb.h:371
bool isScalar
Definition jsonb.h:374
uint32 curValueOffset
Definition jsonb.h:390
char * dataProper
Definition jsonb.h:377
int curIndex
Definition jsonb.h:380
bool unique_keys
Definition jsonb.h:351
JsonbParseState * next
Definition jsonb.h:350
bool skip_nulls
Definition jsonb.h:352
JsonbValue contVal
Definition jsonb.h:348
Definition jsonb.h:215
Definition nodes.h:135
Definition type.h:96

◆ JB_CMASK

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

Definition at line 202 of file jsonb.h.

◆ JB_FARRAY

#define JB_FARRAY   0x40000000

Definition at line 205 of file jsonb.h.

◆ JB_FOBJECT

#define JB_FOBJECT   0x20000000

Definition at line 204 of file jsonb.h.

◆ JB_FSCALAR

#define JB_FSCALAR   0x10000000 /* flag bits */

Definition at line 203 of file jsonb.h.

◆ JB_OFFSET_STRIDE

#define JB_OFFSET_STRIDE   32

Definition at line 180 of file jsonb.h.

◆ JB_ROOT_COUNT

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

Definition at line 221 of file jsonb.h.

◆ JB_ROOT_IS_ARRAY

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

Definition at line 224 of file jsonb.h.

◆ JB_ROOT_IS_OBJECT

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

Definition at line 223 of file jsonb.h.

◆ JB_ROOT_IS_SCALAR

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

Definition at line 222 of file jsonb.h.

◆ JBE_ADVANCE_OFFSET

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

Definition at line 164 of file jsonb.h.

165 { \
166 JEntry je_ = (je); \
168 (offset) = JBE_OFFLENFLD(je_); \
169 else \
170 (offset) += JBE_OFFLENFLD(je_); \
171 } while(0)

◆ JBE_HAS_OFF

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

Definition at line 154 of file jsonb.h.

◆ JBE_ISBOOL

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

Definition at line 161 of file jsonb.h.

◆ JBE_ISBOOL_FALSE

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

Definition at line 160 of file jsonb.h.

◆ JBE_ISBOOL_TRUE

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

Definition at line 159 of file jsonb.h.

◆ JBE_ISCONTAINER

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

Definition at line 157 of file jsonb.h.

◆ JBE_ISNULL

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

Definition at line 158 of file jsonb.h.

◆ JBE_ISNUMERIC

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

Definition at line 156 of file jsonb.h.

◆ JBE_ISSTRING

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

Definition at line 155 of file jsonb.h.

◆ JBE_OFFLENFLD

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

Definition at line 153 of file jsonb.h.

◆ JENTRY_HAS_OFF

#define JENTRY_HAS_OFF   0x80000000

Definition at line 142 of file jsonb.h.

◆ JENTRY_ISBOOL_FALSE

#define JENTRY_ISBOOL_FALSE   0x20000000

Definition at line 147 of file jsonb.h.

◆ JENTRY_ISBOOL_TRUE

#define JENTRY_ISBOOL_TRUE   0x30000000

Definition at line 148 of file jsonb.h.

◆ JENTRY_ISCONTAINER

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

Definition at line 150 of file jsonb.h.

◆ JENTRY_ISNULL

#define JENTRY_ISNULL   0x40000000

Definition at line 149 of file jsonb.h.

◆ JENTRY_ISNUMERIC

#define JENTRY_ISNUMERIC   0x10000000

Definition at line 146 of file jsonb.h.

◆ JENTRY_ISSTRING

#define JENTRY_ISSTRING   0x00000000

Definition at line 145 of file jsonb.h.

◆ JENTRY_OFFLENMASK

#define JENTRY_OFFLENMASK   0x0FFFFFFF

Definition at line 140 of file jsonb.h.

◆ JENTRY_TYPEMASK

#define JENTRY_TYPEMASK   0x70000000

Definition at line 141 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 211 of file jsonb.h.

◆ JsonContainerIsObject

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

Definition at line 210 of file jsonb.h.

◆ JsonContainerIsScalar

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

Definition at line 209 of file jsonb.h.

◆ JsonContainerSize

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

Definition at line 208 of file jsonb.h.

◆ PG_GETARG_JSONB_P

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

Definition at line 418 of file jsonb.h.

◆ PG_GETARG_JSONB_P_COPY

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

Definition at line 419 of file jsonb.h.

◆ PG_RETURN_JSONB_P

#define PG_RETURN_JSONB_P (   x)    PG_RETURN_POINTER(x)

Definition at line 420 of file jsonb.h.

Typedef Documentation

◆ JEntry

Definition at line 138 of file jsonb.h.

◆ JsonbContainer

◆ JsonbInState

◆ JsonbIterator

◆ JsonbPair

Definition at line 71 of file jsonb.h.

◆ JsonbParseState

Definition at line 73 of file jsonb.h.

◆ JsonbValue

Definition at line 72 of file jsonb.h.

Enumeration Type Documentation

◆ jbvType

Enumerator
jbvNull 
jbvString 
jbvNumeric 
jbvBool 
jbvArray 
jbvObject 
jbvBinary 
jbvDatetime 

Definition at line 227 of file jsonb.h.

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

◆ 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{
23 WJB_KEY,
@ 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 359 of file jsonb.h.

Function Documentation

◆ compareJsonbContainers()

int compareJsonbContainers ( JsonbContainer a,
JsonbContainer b 
)
extern

Definition at line 194 of file jsonb_util.c.

195{
197 *itb;
198 int res = 0;
199
202
203 do
204 {
206 vb;
208 rb;
209
210 ra = JsonbIteratorNext(&ita, &va, false);
211 rb = JsonbIteratorNext(&itb, &vb, false);
212
213 if (ra == rb)
214 {
215 if (ra == WJB_DONE)
216 {
217 /* Decisively equal */
218 break;
219 }
220
221 if (ra == WJB_END_ARRAY || ra == WJB_END_OBJECT)
222 {
223 /*
224 * There is no array or object to compare at this stage of
225 * processing. jbvArray/jbvObject values are compared
226 * initially, at the WJB_BEGIN_ARRAY and WJB_BEGIN_OBJECT
227 * tokens.
228 */
229 continue;
230 }
231
232 if (va.type == vb.type)
233 {
234 switch (va.type)
235 {
236 case jbvString:
237 case jbvNull:
238 case jbvNumeric:
239 case jbvBool:
240 res = compareJsonbScalarValue(&va, &vb);
241 break;
242 case jbvArray:
243
244 /*
245 * This could be a "raw scalar" pseudo array. That's
246 * a special case here though, since we still want the
247 * general type-based comparisons to apply, and as far
248 * as we're concerned a pseudo array is just a scalar.
249 */
250 if (va.val.array.rawScalar != vb.val.array.rawScalar)
251 res = (va.val.array.rawScalar) ? -1 : 1;
252
253 /*
254 * There should be an "else" here, to prevent us from
255 * overriding the above, but we can't change the sort
256 * order now, so there is a mild anomaly that an empty
257 * top level array sorts less than null.
258 */
259 if (va.val.array.nElems != vb.val.array.nElems)
260 res = (va.val.array.nElems > vb.val.array.nElems) ? 1 : -1;
261 break;
262 case jbvObject:
263 if (va.val.object.nPairs != vb.val.object.nPairs)
264 res = (va.val.object.nPairs > vb.val.object.nPairs) ? 1 : -1;
265 break;
266 case jbvBinary:
267 elog(ERROR, "unexpected jbvBinary value");
268 break;
269 case jbvDatetime:
270 elog(ERROR, "unexpected jbvDatetime value");
271 break;
272 }
273 }
274 else
275 {
276 /* Type-defined order */
277 res = (va.type > vb.type) ? 1 : -1;
278 }
279 }
280 else
281 {
282 /*
283 * It's not possible for one iterator to report end of array or
284 * object while the other one reports something else, because we
285 * would have detected a length mismatch when we processed the
286 * container-start tokens above. Likewise we can't see WJB_DONE
287 * from one but not the other. So we have two different-type
288 * containers, or a container and some scalar type, or two
289 * different scalar types. Sort on the basis of the type code.
290 */
293
294 Assert(va.type != vb.type);
295 Assert(va.type != jbvBinary);
296 Assert(vb.type != jbvBinary);
297 /* Type-defined order */
298 res = (va.type > vb.type) ? 1 : -1;
299 }
300 }
301 while (res == 0);
302
303 while (ita != NULL)
304 {
306
307 pfree(ita);
308 ita = i;
309 }
310 while (itb != NULL)
311 {
313
314 pfree(itb);
315 itb = i;
316 }
317
318 return res;
319}
#define Assert(condition)
Definition c.h:945
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition jsonb_util.c:935
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition jsonb_util.c:973
static int compareJsonbScalarValue(JsonbValue *a, JsonbValue *b)
void pfree(void *pointer)
Definition mcxt.c:1616

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

◆ DatumGetJsonbPCopy()

static Jsonb * DatumGetJsonbPCopy ( Datum  d)
inlinestatic

Definition at line 407 of file jsonb.h.

408{
409 return (Jsonb *) PG_DETOAST_DATUM_COPY(d);
410}

References PG_DETOAST_DATUM_COPY.

◆ findJsonbValueFromContainer()

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

Definition at line 348 of file jsonb_util.c.

350{
351 JEntry *children = container->children;
352 int count = JsonContainerSize(container);
353
354 Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
355
356 /* Quick out without a palloc cycle if object/array is empty */
357 if (count <= 0)
358 return NULL;
359
360 if ((flags & JB_FARRAY) && JsonContainerIsArray(container))
361 {
363 char *base_addr = (char *) (children + count);
364 uint32 offset = 0;
365 int i;
366
367 for (i = 0; i < count; i++)
368 {
369 fillJsonbValue(container, i, base_addr, offset, result);
370
371 if (key->type == result->type)
372 {
373 if (equalsJsonbScalarValue(key, result))
374 return result;
375 }
376
377 JBE_ADVANCE_OFFSET(offset, children[i]);
378 }
379
380 pfree(result);
381 }
382 else if ((flags & JB_FOBJECT) && JsonContainerIsObject(container))
383 {
384 /* Object key passed by caller must be a string */
385 Assert(key->type == jbvString);
386
387 return getKeyJsonValueFromContainer(container, key->val.string.val,
388 key->val.string.len, NULL);
389 }
390
391 /* Not found */
392 return NULL;
393}
#define palloc_object(type)
Definition fe_memutils.h:74
#define JsonContainerIsArray(jc)
Definition jsonb.h:211
#define JsonContainerSize(jc)
Definition jsonb.h:208
#define JsonContainerIsObject(jc)
Definition jsonb.h:210
#define JB_FARRAY
Definition jsonb.h:205
#define JB_FOBJECT
Definition jsonb.h:204
#define JBE_ADVANCE_OFFSET(offset, je)
Definition jsonb.h:164
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition jsonb_util.c:509
JsonbValue * getKeyJsonValueFromContainer(JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
Definition jsonb_util.c:402
static bool equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b)
JEntry children[FLEXIBLE_ARRAY_MEMBER]
Definition jsonb.h:196
enum jbvType type
Definition jsonb.h:257

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

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

◆ getIthJsonbValueFromContainer()

JsonbValue * getIthJsonbValueFromContainer ( JsonbContainer container,
uint32  i 
)
extern

Definition at line 472 of file jsonb_util.c.

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

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

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

◆ getJsonbLength()

uint32 getJsonbLength ( const JsonbContainer jc,
int  index 
)
extern

Definition at line 162 of file jsonb_util.c.

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

References fb(), getJsonbOffset(), JBE_HAS_OFF, JBE_OFFLENFLD, and len.

Referenced by fillJsonbValue(), and getKeyJsonValueFromContainer().

◆ getJsonbOffset()

uint32 getJsonbOffset ( const JsonbContainer jc,
int  index 
)
extern

Definition at line 137 of file jsonb_util.c.

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

References fb(), 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 
)
extern

Definition at line 402 of file jsonb_util.c.

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

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

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

◆ jsonb_build_array_worker()

Datum jsonb_build_array_worker ( int  nargs,
const Datum args,
const bool nulls,
const Oid types,
bool  absent_on_null 
)
extern

Definition at line 1215 of file jsonb.c.

1217{
1218 int i;
1219 JsonbInState result;
1220
1221 memset(&result, 0, sizeof(JsonbInState));
1222
1224
1225 for (i = 0; i < nargs; i++)
1226 {
1227 if (absent_on_null && nulls[i])
1228 continue;
1229
1230 add_jsonb(args[i], nulls[i], &result, types[i], false);
1231 }
1232
1234
1235 return JsonbPGetDatum(JsonbValueToJsonb(result.result));
1236}
static void add_jsonb(Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
Definition jsonb.c:1052
void pushJsonbValue(JsonbInState *pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition jsonb_util.c:583
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition jsonb_util.c:96

References add_jsonb(), fb(), i, JsonbPGetDatum(), JsonbValueToJsonb(), pushJsonbValue(), JsonbInState::result, types, WJB_BEGIN_ARRAY, and WJB_END_ARRAY.

Referenced by ExecEvalJsonConstructor(), and jsonb_build_array().

◆ jsonb_build_object_worker()

Datum jsonb_build_object_worker ( int  nargs,
const Datum args,
const bool nulls,
const Oid types,
bool  absent_on_null,
bool  unique_keys 
)
extern

Definition at line 1130 of file jsonb.c.

1132{
1133 int i;
1134 JsonbInState result;
1135
1136 if (nargs % 2 != 0)
1137 ereport(ERROR,
1139 errmsg("argument list must have even number of elements"),
1140 /* translator: %s is a SQL function name */
1141 errhint("The arguments of %s must consist of alternating keys and values.",
1142 "jsonb_build_object()")));
1143
1144 memset(&result, 0, sizeof(JsonbInState));
1145
1147 result.parseState->unique_keys = unique_keys;
1148 result.parseState->skip_nulls = absent_on_null;
1149
1150 for (i = 0; i < nargs; i += 2)
1151 {
1152 /* process key */
1153 bool skip;
1154
1155 if (nulls[i])
1156 ereport(ERROR,
1158 errmsg("argument %d: key must not be null", i + 1)));
1159
1160 /* skip null values if absent_on_null */
1161 skip = absent_on_null && nulls[i + 1];
1162
1163 /* we need to save skipped keys for the key uniqueness check */
1164 if (skip && !unique_keys)
1165 continue;
1166
1167 add_jsonb(args[i], false, &result, types[i], true);
1168
1169 /* process value */
1170 add_jsonb(args[i + 1], nulls[i + 1], &result, types[i + 1], false);
1171 }
1172
1174
1175 return JsonbPGetDatum(JsonbValueToJsonb(result.result));
1176}
int errcode(int sqlerrcode)
Definition elog.c:874
int errhint(const char *fmt,...) pg_attribute_printf(1
#define ereport(elevel,...)
Definition elog.h:150
static char * errmsg
static const struct exclude_list_item skip[]

References add_jsonb(), ereport, errcode(), errhint(), errmsg, ERROR, fb(), i, JsonbPGetDatum(), JsonbValueToJsonb(), JsonbInState::parseState, pushJsonbValue(), JsonbInState::result, skip, JsonbParseState::skip_nulls, types, JsonbParseState::unique_keys, WJB_BEGIN_OBJECT, and WJB_END_OBJECT.

Referenced by ExecEvalJsonConstructor(), and jsonb_build_object().

◆ jsonb_get_element()

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

Definition at line 1534 of file jsonfuncs.c.

1535{
1536 JsonbContainer *container = &jb->root;
1537 JsonbValue *jbvp = NULL;
1538 int i;
1539 bool have_object = false,
1540 have_array = false;
1541
1542 *isnull = false;
1543
1544 /* Identify whether we have object, array, or scalar at top-level */
1545 if (JB_ROOT_IS_OBJECT(jb))
1546 have_object = true;
1547 else if (JB_ROOT_IS_ARRAY(jb) && !JB_ROOT_IS_SCALAR(jb))
1548 have_array = true;
1549 else
1550 {
1552 /* Extract the scalar value, if it is what we'll return */
1553 if (npath <= 0)
1554 jbvp = getIthJsonbValueFromContainer(container, 0);
1555 }
1556
1557 /*
1558 * If the array is empty, return the entire LHS object, on the grounds
1559 * that we should do zero field or element extractions. For the
1560 * non-scalar case we can just hand back the object without much work. For
1561 * the scalar case, fall through and deal with the value below the loop.
1562 * (This inconsistency arises because there's no easy way to generate a
1563 * JsonbValue directly for root-level containers.)
1564 */
1565 if (npath <= 0 && jbvp == NULL)
1566 {
1567 if (as_text)
1568 {
1570 container,
1571 VARSIZE(jb))));
1572 }
1573 else
1574 {
1575 /* not text mode - just hand back the jsonb */
1577 }
1578 }
1579
1580 for (i = 0; i < npath; i++)
1581 {
1582 if (have_object)
1583 {
1584 text *subscr = DatumGetTextPP(path[i]);
1585
1589 NULL);
1590 }
1591 else if (have_array)
1592 {
1593 int lindex;
1594 uint32 index;
1595 char *indextext = TextDatumGetCString(path[i]);
1596 char *endptr;
1597
1598 errno = 0;
1599 lindex = strtoint(indextext, &endptr, 10);
1600 if (endptr == indextext || *endptr != '\0' || errno != 0)
1601 {
1602 *isnull = true;
1603 return PointerGetDatum(NULL);
1604 }
1605
1606 if (lindex >= 0)
1607 {
1608 index = (uint32) lindex;
1609 }
1610 else
1611 {
1612 /* Handle negative subscript */
1613 uint32 nelements;
1614
1615 /* Container must be array, but make sure */
1616 if (!JsonContainerIsArray(container))
1617 elog(ERROR, "not a jsonb array");
1618
1619 nelements = JsonContainerSize(container);
1620
1621 if (lindex == INT_MIN || -lindex > nelements)
1622 {
1623 *isnull = true;
1624 return PointerGetDatum(NULL);
1625 }
1626 else
1627 index = nelements + lindex;
1628 }
1629
1631 }
1632 else
1633 {
1634 /* scalar, extraction yields a null */
1635 *isnull = true;
1636 return PointerGetDatum(NULL);
1637 }
1638
1639 if (jbvp == NULL)
1640 {
1641 *isnull = true;
1642 return PointerGetDatum(NULL);
1643 }
1644 else if (i == npath - 1)
1645 break;
1646
1647 if (jbvp->type == jbvBinary)
1648 {
1649 container = jbvp->val.binary.data;
1651 have_array = JsonContainerIsArray(container);
1652 Assert(!JsonContainerIsScalar(container));
1653 }
1654 else
1655 {
1657 have_object = false;
1658 have_array = false;
1659 }
1660 }
1661
1662 if (as_text)
1663 {
1664 if (jbvp->type == jbvNull)
1665 {
1666 *isnull = true;
1667 return PointerGetDatum(NULL);
1668 }
1669
1671 }
1672 else
1673 {
1675
1676 /* not text mode - just hand back the jsonb */
1677 PG_RETURN_JSONB_P(res);
1678 }
1679}
#define TextDatumGetCString(d)
Definition builtins.h:99
#define DatumGetTextPP(X)
Definition fmgr.h:293
char * JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
Definition jsonb.c:465
#define JsonContainerIsScalar(jc)
Definition jsonb.h:209
#define JB_ROOT_IS_OBJECT(jbp_)
Definition jsonb.h:223
#define IsAJsonbScalar(jsonbval)
Definition jsonb.h:299
#define PG_RETURN_JSONB_P(x)
Definition jsonb.h:420
#define JB_ROOT_IS_ARRAY(jbp_)
Definition jsonb.h:224
#define JB_ROOT_IS_SCALAR(jbp_)
Definition jsonb.h:222
JsonbValue * getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)
Definition jsonb_util.c:472
static text * JsonbValueAsText(JsonbValue *v)
Definition jsonfuncs.c:1805
int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
Definition string.c:50
Definition c.h:778
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition varatt.h:472
static Size VARSIZE(const void *PTR)
Definition varatt.h:298
static char * VARDATA_ANY(const void *PTR)
Definition varatt.h:486
text * cstring_to_text(const char *s)
Definition varlena.c:184

References Assert, cstring_to_text(), DatumGetTextPP, elog, ERROR, fb(), 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(), strtoint(), TextDatumGetCString, 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,
const Datum path,
int  path_len,
JsonbValue newval 
)
extern

Definition at line 1682 of file jsonfuncs.c.

1684{
1685 JsonbInState state = {0};
1687 bool *path_nulls = palloc0_array(bool, path_len);
1688
1689 if (newval->type == jbvArray && newval->val.array.rawScalar)
1690 *newval = newval->val.array.elems[0];
1691
1692 it = JsonbIteratorInit(&jb->root);
1693
1694 setPath(&it, path, path_nulls, path_len, &state, 0, newval,
1697
1699
1701}
#define palloc0_array(type, count)
Definition fe_memutils.h:77
#define JB_PATH_CREATE
Definition jsonfuncs.c:47
#define JB_PATH_CONSISTENT_POSITION
Definition jsonfuncs.c:55
#define JB_PATH_FILL_GAPS
Definition jsonfuncs.c:54
static void setPath(JsonbIterator **it, const Datum *path_elems, const bool *path_nulls, int path_len, JsonbInState *st, int level, JsonbValue *newval, int op_type)
Definition jsonfuncs.c:5176

References fb(), JB_PATH_CONSISTENT_POSITION, JB_PATH_CREATE, JB_PATH_FILL_GAPS, jbvArray, JsonbIteratorInit(), JsonbValueToJsonb(), newval, palloc0_array, pfree(), PG_RETURN_JSONB_P, and setPath().

Referenced by jsonb_subscript_assign().

◆ JsonbDeepContains()

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

Definition at line 1189 of file jsonb_util.c.

1190{
1192 vcontained;
1194 rcont;
1195
1196 /*
1197 * Guard against stack overflow due to overly complex Jsonb.
1198 *
1199 * Functions called here independently take this precaution, but that
1200 * might not be sufficient since this is also a recursive function.
1201 */
1203
1204 rval = JsonbIteratorNext(val, &vval, false);
1206
1207 if (rval != rcont)
1208 {
1209 /*
1210 * The differing return values can immediately be taken as indicating
1211 * two differing container types at this nesting level, which is
1212 * sufficient reason to give up entirely (but it should be the case
1213 * that they're both some container type).
1214 */
1217 return false;
1218 }
1219 else if (rcont == WJB_BEGIN_OBJECT)
1220 {
1221 Assert(vval.type == jbvObject);
1222 Assert(vcontained.type == jbvObject);
1223
1224 /*
1225 * If the lhs has fewer pairs than the rhs, it can't possibly contain
1226 * the rhs. (This conclusion is safe only because we de-duplicate
1227 * keys in all Jsonb objects; thus there can be no corresponding
1228 * optimization in the array case.) The case probably won't arise
1229 * often, but since it's such a cheap check we may as well make it.
1230 */
1231 if (vval.val.object.nPairs < vcontained.val.object.nPairs)
1232 return false;
1233
1234 /* Work through rhs "is it contained within?" object */
1235 for (;;)
1236 {
1237 JsonbValue *lhsVal; /* lhsVal is from pair in lhs object */
1239
1241
1242 /*
1243 * When we get through caller's rhs "is it contained within?"
1244 * object without failing to find one of its values, it's
1245 * contained.
1246 */
1247 if (rcont == WJB_END_OBJECT)
1248 return true;
1249
1250 Assert(rcont == WJB_KEY);
1251 Assert(vcontained.type == jbvString);
1252
1253 /* First, find value by key... */
1254 lhsVal =
1255 getKeyJsonValueFromContainer((*val)->container,
1256 vcontained.val.string.val,
1257 vcontained.val.string.len,
1258 &lhsValBuf);
1259 if (!lhsVal)
1260 return false;
1261
1262 /*
1263 * ...at this stage it is apparent that there is at least a key
1264 * match for this rhs pair.
1265 */
1267
1269
1270 /*
1271 * Compare rhs pair's value with lhs pair's value just found using
1272 * key
1273 */
1274 if (lhsVal->type != vcontained.type)
1275 {
1276 return false;
1277 }
1278 else if (IsAJsonbScalar(lhsVal))
1279 {
1281 return false;
1282 }
1283 else
1284 {
1285 /* Nested container value (object or array) */
1288
1289 Assert(lhsVal->type == jbvBinary);
1290 Assert(vcontained.type == jbvBinary);
1291
1292 nestval = JsonbIteratorInit(lhsVal->val.binary.data);
1293 nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1294
1295 /*
1296 * Match "value" side of rhs datum object's pair recursively.
1297 * It's a nested structure.
1298 *
1299 * Note that nesting still has to "match up" at the right
1300 * nesting sub-levels. However, there need only be zero or
1301 * more matching pairs (or elements) at each nesting level
1302 * (provided the *rhs* pairs/elements *all* match on each
1303 * level), which enables searching nested structures for a
1304 * single String or other primitive type sub-datum quite
1305 * effectively (provided the user constructed the rhs nested
1306 * structure such that we "know where to look").
1307 *
1308 * In other words, the mapping of container nodes in the rhs
1309 * "vcontained" Jsonb to internal nodes on the lhs is
1310 * injective, and parent-child edges on the rhs must be mapped
1311 * to parent-child edges on the lhs to satisfy the condition
1312 * of containment (plus of course the mapped nodes must be
1313 * equal).
1314 */
1316 return false;
1317 }
1318 }
1319 }
1320 else if (rcont == WJB_BEGIN_ARRAY)
1321 {
1323 uint32 nLhsElems = vval.val.array.nElems;
1324
1325 Assert(vval.type == jbvArray);
1326 Assert(vcontained.type == jbvArray);
1327
1328 /*
1329 * Handle distinction between "raw scalar" pseudo arrays, and real
1330 * arrays.
1331 *
1332 * A raw scalar may contain another raw scalar, and an array may
1333 * contain a raw scalar, but a raw scalar may not contain an array. We
1334 * don't do something like this for the object case, since objects can
1335 * only contain pairs, never raw scalars (a pair is represented by an
1336 * rhs object argument with a single contained pair).
1337 */
1338 if (vval.val.array.rawScalar && !vcontained.val.array.rawScalar)
1339 return false;
1340
1341 /* Work through rhs "is it contained within?" array */
1342 for (;;)
1343 {
1345
1346 /*
1347 * When we get through caller's rhs "is it contained within?"
1348 * array without failing to find one of its values, it's
1349 * contained.
1350 */
1351 if (rcont == WJB_END_ARRAY)
1352 return true;
1353
1354 Assert(rcont == WJB_ELEM);
1355
1357 {
1358 if (!findJsonbValueFromContainer((*val)->container,
1359 JB_FARRAY,
1360 &vcontained))
1361 return false;
1362 }
1363 else
1364 {
1365 uint32 i;
1366
1367 /*
1368 * If this is first container found in rhs array (at this
1369 * depth), initialize temp lhs array of containers
1370 */
1371 if (lhsConts == NULL)
1372 {
1373 uint32 j = 0;
1374
1375 /* Make room for all possible values */
1377
1378 for (i = 0; i < nLhsElems; i++)
1379 {
1380 /* Store all lhs elements in temp array */
1381 rcont = JsonbIteratorNext(val, &vval, true);
1382 Assert(rcont == WJB_ELEM);
1383
1384 if (vval.type == jbvBinary)
1385 lhsConts[j++] = vval;
1386 }
1387
1388 /* No container elements in temp array, so give up now */
1389 if (j == 0)
1390 return false;
1391
1392 /* We may have only partially filled array */
1393 nLhsElems = j;
1394 }
1395
1396 /* XXX: Nested array containment is O(N^2) */
1397 for (i = 0; i < nLhsElems; i++)
1398 {
1399 /* Nested container value (object or array) */
1402 bool contains;
1403
1404 nestval = JsonbIteratorInit(lhsConts[i].val.binary.data);
1405 nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1406
1408
1409 if (nestval)
1410 pfree(nestval);
1411 if (nestContained)
1413 if (contains)
1414 break;
1415 }
1416
1417 /*
1418 * Report rhs container value is not contained if couldn't
1419 * match rhs container to *some* lhs cont
1420 */
1421 if (i == nLhsElems)
1422 return false;
1423 }
1424 }
1425 }
1426 else
1427 {
1428 elog(ERROR, "invalid jsonb container type");
1429 }
1430
1431 elog(ERROR, "unexpectedly fell off end of jsonb container");
1432 return false;
1433}
#define palloc_array(type, count)
Definition fe_memutils.h:76
int j
Definition isn.c:78
JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)
Definition jsonb_util.c:348
bool JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
void check_stack_depth(void)
Definition stack_depth.c:95
char * val
Definition jsonb.h:266

References Assert, check_stack_depth(), elog, equalsJsonbScalarValue(), ERROR, fb(), findJsonbValueFromContainer(), getKeyJsonValueFromContainer(), i, IsAJsonbScalar, j, JB_FARRAY, jbvArray, jbvBinary, jbvObject, jbvString, JsonbDeepContains(), JsonbIteratorInit(), JsonbIteratorNext(), palloc_array, pfree(), 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(), jsonb_contains(), and JsonbDeepContains().

◆ JsonbExtractScalar()

bool JsonbExtractScalar ( JsonbContainer jbc,
JsonbValue res 
)
extern

Definition at line 1749 of file jsonb.c.

1750{
1753 JsonbValue tmp;
1754
1756 {
1757 /* inform caller about actual type of container */
1758 res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
1759 return false;
1760 }
1761
1762 /*
1763 * A root scalar is stored as an array of one element, so we get the array
1764 * and then its first (and only) member.
1765 */
1766 it = JsonbIteratorInit(jbc);
1767
1768 tok = JsonbIteratorNext(&it, &tmp, true);
1770 Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
1771
1772 tok = JsonbIteratorNext(&it, res, true);
1773 Assert(tok == WJB_ELEM);
1774 Assert(IsAJsonbScalar(res));
1775
1776 tok = JsonbIteratorNext(&it, &tmp, true);
1778
1779 tok = JsonbIteratorNext(&it, &tmp, true);
1780 Assert(tok == WJB_DONE);
1781
1782 return true;
1783}
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:243

References Assert, fb(), 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(), JsonbContainerTypeName(), JsonbUnquote(), JsonItemFromDatum(), and JsonPathValue().

◆ JsonbHashScalarValue()

void JsonbHashScalarValue ( const JsonbValue scalarVal,
uint32 hash 
)
extern

Definition at line 1443 of file jsonb_util.c.

1444{
1445 uint32 tmp;
1446
1447 /* Compute hash value for scalarVal */
1448 switch (scalarVal->type)
1449 {
1450 case jbvNull:
1451 tmp = 0x01;
1452 break;
1453 case jbvString:
1454 tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->val.string.val,
1455 scalarVal->val.string.len));
1456 break;
1457 case jbvNumeric:
1458 /* Must hash equal numerics to equal hash codes */
1460 NumericGetDatum(scalarVal->val.numeric)));
1461 break;
1462 case jbvBool:
1463 tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1464
1465 break;
1466 default:
1467 elog(ERROR, "invalid jsonb scalar type");
1468 tmp = 0; /* keep compiler quiet */
1469 break;
1470 }
1471
1472 /*
1473 * Combine hash values of successive keys, values and elements by rotating
1474 * the previous value left 1 bit, then XOR'ing in the new
1475 * key/value/element's hash value.
1476 */
1477 *hash = pg_rotate_left32(*hash, 1);
1478 *hash ^= tmp;
1479}
Datum hash_numeric(PG_FUNCTION_ARGS)
Definition numeric.c:2713
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:684
static Datum hash_any(const unsigned char *k, int keylen)
Definition hashfn.h:31
static Datum NumericGetDatum(Numeric X)
Definition numeric.h:76
static uint32 pg_rotate_left32(uint32 word, int n)
static uint32 DatumGetUInt32(Datum X)
Definition postgres.h:222

References DatumGetUInt32(), DirectFunctionCall1, elog, ERROR, fb(), hash(), hash_any(), hash_numeric(), jbvBool, jbvNull, jbvNumeric, jbvString, NumericGetDatum(), and pg_rotate_left32().

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

Definition at line 1486 of file jsonb_util.c.

1488{
1489 uint64 tmp;
1490
1491 switch (scalarVal->type)
1492 {
1493 case jbvNull:
1494 tmp = seed + 0x01;
1495 break;
1496 case jbvString:
1497 tmp = DatumGetUInt64(hash_any_extended((const unsigned char *) scalarVal->val.string.val,
1498 scalarVal->val.string.len,
1499 seed));
1500 break;
1501 case jbvNumeric:
1503 NumericGetDatum(scalarVal->val.numeric),
1504 UInt64GetDatum(seed)));
1505 break;
1506 case jbvBool:
1507 if (seed)
1509 BoolGetDatum(scalarVal->val.boolean),
1510 UInt64GetDatum(seed)));
1511 else
1512 tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1513
1514 break;
1515 default:
1516 elog(ERROR, "invalid jsonb scalar type");
1517 break;
1518 }
1519
1521 *hash ^= tmp;
1522}
Datum hash_numeric_extended(PG_FUNCTION_ARGS)
Definition numeric.c:2793
#define DirectFunctionCall2(func, arg1, arg2)
Definition fmgr.h:686
#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:54
static uint64 DatumGetUInt64(Datum X)
Definition postgres.h:423
static Datum UInt64GetDatum(uint64 X)
Definition postgres.h:433
static Datum BoolGetDatum(bool X)
Definition postgres.h:112

References BoolGetDatum(), DatumGetUInt64(), DirectFunctionCall2, elog, ERROR, fb(), hash(), hash_any_extended(), hash_numeric_extended(), hashcharextended(), jbvBool, jbvNull, jbvNumeric, jbvString, NumericGetDatum(), ROTATE_HIGH_AND_LOW_32BITS, and UInt64GetDatum().

Referenced by jsonb_hash_extended().

◆ JsonbIteratorInit()

◆ JsonbIteratorNext()

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

Definition at line 973 of file jsonb_util.c.

974{
975 if (*it == NULL)
976 {
977 val->type = jbvNull;
978 return WJB_DONE;
979 }
980
981 /*
982 * When stepping into a nested container, we jump back here to start
983 * processing the child. We will not recurse further in one call, because
984 * processing the child will always begin in JBI_ARRAY_START or
985 * JBI_OBJECT_START state.
986 */
987recurse:
988 switch ((*it)->state)
989 {
990 case JBI_ARRAY_START:
991 /* Set v to array on first array call */
992 val->type = jbvArray;
993 val->val.array.nElems = (*it)->nElems;
994
995 /*
996 * v->val.array.elems is not actually set, because we aren't doing
997 * a full conversion
998 */
999 val->val.array.rawScalar = (*it)->isScalar;
1000 (*it)->curIndex = 0;
1001 (*it)->curDataOffset = 0;
1002 (*it)->curValueOffset = 0; /* not actually used */
1003 /* Set state for next call */
1004 (*it)->state = JBI_ARRAY_ELEM;
1005 return WJB_BEGIN_ARRAY;
1006
1007 case JBI_ARRAY_ELEM:
1008 if ((*it)->curIndex >= (*it)->nElems)
1009 {
1010 /*
1011 * All elements within array already processed. Report this
1012 * to caller, and give it back original parent iterator (which
1013 * independently tracks iteration progress at its level of
1014 * nesting).
1015 */
1016 *it = freeAndGetParent(*it);
1017 val->type = jbvNull;
1018 return WJB_END_ARRAY;
1019 }
1020
1021 fillJsonbValue((*it)->container, (*it)->curIndex,
1022 (*it)->dataProper, (*it)->curDataOffset,
1023 val);
1024
1025 JBE_ADVANCE_OFFSET((*it)->curDataOffset,
1026 (*it)->children[(*it)->curIndex]);
1027 (*it)->curIndex++;
1028
1029 if (!IsAJsonbScalar(val) && !skipNested)
1030 {
1031 /* Recurse into container. */
1032 *it = iteratorFromContainer(val->val.binary.data, *it);
1033 goto recurse;
1034 }
1035 else
1036 {
1037 /*
1038 * Scalar item in array, or a container and caller didn't want
1039 * us to recurse into it.
1040 */
1041 return WJB_ELEM;
1042 }
1043
1044 case JBI_OBJECT_START:
1045 /* Set v to object on first object call */
1046 val->type = jbvObject;
1047 val->val.object.nPairs = (*it)->nElems;
1048
1049 /*
1050 * v->val.object.pairs is not actually set, because we aren't
1051 * doing a full conversion
1052 */
1053 (*it)->curIndex = 0;
1054 (*it)->curDataOffset = 0;
1055 (*it)->curValueOffset = getJsonbOffset((*it)->container,
1056 (*it)->nElems);
1057 /* Set state for next call */
1058 (*it)->state = JBI_OBJECT_KEY;
1059 return WJB_BEGIN_OBJECT;
1060
1061 case JBI_OBJECT_KEY:
1062 if ((*it)->curIndex >= (*it)->nElems)
1063 {
1064 /*
1065 * All pairs within object already processed. Report this to
1066 * caller, and give it back original containing iterator
1067 * (which independently tracks iteration progress at its level
1068 * of nesting).
1069 */
1070 *it = freeAndGetParent(*it);
1071 val->type = jbvNull;
1072 return WJB_END_OBJECT;
1073 }
1074 else
1075 {
1076 /* Return key of a key/value pair. */
1077 fillJsonbValue((*it)->container, (*it)->curIndex,
1078 (*it)->dataProper, (*it)->curDataOffset,
1079 val);
1080 if (val->type != jbvString)
1081 elog(ERROR, "unexpected jsonb type as object key");
1082
1083 /* Set state for next call */
1084 (*it)->state = JBI_OBJECT_VALUE;
1085 return WJB_KEY;
1086 }
1087
1088 case JBI_OBJECT_VALUE:
1089 /* Set state for next call */
1090 (*it)->state = JBI_OBJECT_KEY;
1091
1092 fillJsonbValue((*it)->container, (*it)->curIndex + (*it)->nElems,
1093 (*it)->dataProper, (*it)->curValueOffset,
1094 val);
1095
1096 JBE_ADVANCE_OFFSET((*it)->curDataOffset,
1097 (*it)->children[(*it)->curIndex]);
1098 JBE_ADVANCE_OFFSET((*it)->curValueOffset,
1099 (*it)->children[(*it)->curIndex + (*it)->nElems]);
1100 (*it)->curIndex++;
1101
1102 /*
1103 * Value may be a container, in which case we recurse with new,
1104 * child iterator (unless the caller asked not to, by passing
1105 * skipNested).
1106 */
1107 if (!IsAJsonbScalar(val) && !skipNested)
1108 {
1109 *it = iteratorFromContainer(val->val.binary.data, *it);
1110 goto recurse;
1111 }
1112 else
1113 return WJB_VALUE;
1114 }
1115
1116 elog(ERROR, "invalid jsonb iterator state");
1117 /* satisfy compilers that don't know that elog(ERROR) doesn't return */
1118 val->type = jbvNull;
1119 return WJB_DONE;
1120}
static JsonbIterator * freeAndGetParent(JsonbIterator *it)

References elog, ERROR, fb(), fillJsonbValue(), freeAndGetParent(), getJsonbOffset(), IsAJsonbScalar, iteratorFromContainer(), JBE_ADVANCE_OFFSET, JBI_ARRAY_ELEM, JBI_ARRAY_START, JBI_OBJECT_KEY, JBI_OBJECT_START, JBI_OBJECT_VALUE, jbvArray, jbvNull, 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 check_all_expr_argnames_valid(), compareJsonbContainers(), datum_to_jsonb_internal(), each_worker_jsonb(), elements_worker_jsonb(), executeAnyItem(), executeKeyValueMethod(), gin_extract_jsonb(), gin_extract_jsonb_path(), iterate_jsonb_values(), IteratorConcat(), jsonb_delete(), jsonb_delete_array(), jsonb_delete_idx(), jsonb_hash(), jsonb_hash_extended(), 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()

◆ JsonbToCString()

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

Definition at line 465 of file jsonb.c.

466{
467 return JsonbToCStringWorker(out, in, estimated_len, false);
468}
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition jsonb.c:483

References fb(), and JsonbToCStringWorker().

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

◆ JsonbToCStringIndent()

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

Definition at line 474 of file jsonb.c.

475{
476 return JsonbToCStringWorker(out, in, estimated_len, true);
477}

References fb(), and JsonbToCStringWorker().

Referenced by jsonb_pretty().

◆ JsonbToJsonbValue()

void JsonbToJsonbValue ( Jsonb jsonb,
JsonbValue val 
)
extern

Definition at line 76 of file jsonb_util.c.

77{
78 val->type = jbvBinary;
79 val->val.binary.data = &jsonb->root;
80 val->val.binary.len = VARSIZE(jsonb) - VARHDRSZ;
81}
#define VARHDRSZ
Definition c.h:783
JsonbContainer root
Definition jsonb.h:217

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

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

◆ JsonbTypeName()

const char * JsonbTypeName ( JsonbValue val)
extern

Definition at line 172 of file jsonb.c.

173{
174 switch (val->type)
175 {
176 case jbvBinary:
177 return JsonbContainerTypeName(val->val.binary.data);
178 case jbvObject:
179 return "object";
180 case jbvArray:
181 return "array";
182 case jbvNumeric:
183 return "number";
184 case jbvString:
185 return "string";
186 case jbvBool:
187 return "boolean";
188 case jbvNull:
189 return "null";
190 case jbvDatetime:
191 switch (val->val.datetime.typid)
192 {
193 case DATEOID:
194 return "date";
195 case TIMEOID:
196 return "time without time zone";
197 case TIMETZOID:
198 return "time with time zone";
199 case TIMESTAMPOID:
200 return "timestamp without time zone";
201 case TIMESTAMPTZOID:
202 return "timestamp with time zone";
203 default:
204 elog(ERROR, "unrecognized jsonb value datetime type: %d",
205 val->val.datetime.typid);
206 }
207 return "unknown";
208 default:
209 elog(ERROR, "unrecognized jsonb value type: %d", val->type);
210 return "unknown";
211 }
212}
static const char * JsonbContainerTypeName(JsonbContainer *jbc)
Definition jsonb.c:151

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

Referenced by executeItemOptUnwrapTarget(), and JsonbContainerTypeName().

◆ JsonbUnquote()

char * JsonbUnquote ( Jsonb jb)
extern

Definition at line 2010 of file jsonb.c.

2011{
2012 if (JB_ROOT_IS_SCALAR(jb))
2013 {
2014 JsonbValue v;
2015
2016 (void) JsonbExtractScalar(&jb->root, &v);
2017
2018 if (v.type == jbvString)
2019 return pnstrdup(v.val.string.val, v.val.string.len);
2020 else if (v.type == jbvBool)
2021 return pstrdup(v.val.boolean ? "true" : "false");
2022 else if (v.type == jbvNumeric)
2024 PointerGetDatum(v.val.numeric)));
2025 else if (v.type == jbvNull)
2026 return pstrdup("null");
2027 else
2028 {
2029 elog(ERROR, "unrecognized jsonb value type %d", v.type);
2030 return NULL;
2031 }
2032 }
2033 else
2034 return JsonbToCString(NULL, &jb->root, VARSIZE(jb));
2035}
Datum numeric_out(PG_FUNCTION_ARGS)
Definition numeric.c:799
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition jsonb.c:1749
char * pstrdup(const char *in)
Definition mcxt.c:1781
char * pnstrdup(const char *in, Size len)
Definition mcxt.c:1792
static char * DatumGetCString(Datum X)
Definition postgres.h:355

References DatumGetCString(), DirectFunctionCall1, elog, ERROR, fb(), JB_ROOT_IS_SCALAR, jbvBool, jbvNull, jbvNumeric, jbvString, JsonbExtractScalar(), JsonbToCString(), numeric_out(), pnstrdup(), PointerGetDatum(), pstrdup(), JsonbValue::type, JsonbValue::val, and VARSIZE().

Referenced by json_populate_type().

◆ JsonbValueToJsonb()

Jsonb * JsonbValueToJsonb ( JsonbValue val)
extern

Definition at line 96 of file jsonb_util.c.

97{
98 Jsonb *out;
99
100 if (IsAJsonbScalar(val))
101 {
102 /* Scalar value, so wrap it in an array */
103 JsonbInState pstate = {0};
105
107 scalarArray.val.array.rawScalar = true;
108 scalarArray.val.array.nElems = 1;
109
111 pushJsonbValue(&pstate, WJB_ELEM, val);
113
114 out = convertToJsonb(pstate.result);
115 }
116 else if (val->type == jbvObject || val->type == jbvArray)
117 {
118 out = convertToJsonb(val);
119 }
120 else
121 {
122 Assert(val->type == jbvBinary);
123 out = palloc(VARHDRSZ + val->val.binary.len);
124 SET_VARSIZE(out, VARHDRSZ + val->val.binary.len);
125 memcpy(VARDATA(out), val->val.binary.data, val->val.binary.len);
126 }
127
128 return out;
129}
static Jsonb * convertToJsonb(JsonbValue *val)
void * palloc(Size size)
Definition mcxt.c:1387
static char * VARDATA(const void *PTR)
Definition varatt.h:305
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432

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

Referenced by datum_to_jsonb(), each_worker_jsonb(), elements_worker_jsonb(), ExecEvalJsonExprPath(), ExecGetJsonValueItemString(), executeKeyValueMethod(), hstore_to_jsonb(), hstore_to_jsonb_loose(), jsonb_agg_finalfn(), jsonb_array_element(), jsonb_build_array_noargs(), jsonb_build_array_worker(), jsonb_build_object_noargs(), jsonb_build_object_worker(), 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_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(), JsonPathQuery(), JsonTablePlanScanNextRow(), plperl_to_jsonb(), plpython_to_jsonb(), populate_scalar(), and transform_jsonb_string_values().

◆ pushJsonbValue()

void pushJsonbValue ( JsonbInState pstate,
JsonbIteratorToken  seq,
JsonbValue jbval 
)
extern

Definition at line 583 of file jsonb_util.c.

585{
587 JsonbValue v;
589 int i;
590
591 /*
592 * pushJsonbValueScalar handles all cases not involving pushing a
593 * container object as an ELEM or VALUE.
594 */
595 if (!jbval || IsAJsonbScalar(jbval) ||
596 (seq != WJB_ELEM && seq != WJB_VALUE))
597 {
599 return;
600 }
601
602 /* If an object or array is pushed, recursively push its contents */
603 if (jbval->type == jbvObject)
604 {
606 for (i = 0; i < jbval->val.object.nPairs; i++)
607 {
608 pushJsonbValue(pstate, WJB_KEY, &jbval->val.object.pairs[i].key);
609 pushJsonbValue(pstate, WJB_VALUE, &jbval->val.object.pairs[i].value);
610 }
612 return;
613 }
614
615 if (jbval->type == jbvArray)
616 {
618 for (i = 0; i < jbval->val.array.nElems; i++)
619 {
620 pushJsonbValue(pstate, WJB_ELEM, &jbval->val.array.elems[i]);
621 }
623 return;
624 }
625
626 /* Else it must be a jbvBinary value; push its contents */
627 Assert(jbval->type == jbvBinary);
628
629 it = JsonbIteratorInit(jbval->val.binary.data);
630
631 /* ... with a special case for pushing a raw scalar */
632 if ((jbval->val.binary.data->header & JB_FSCALAR) &&
633 pstate->parseState != NULL)
634 {
635 tok = JsonbIteratorNext(&it, &v, true);
637 Assert(v.type == jbvArray && v.val.array.rawScalar);
638
639 tok = JsonbIteratorNext(&it, &v, true);
640 Assert(tok == WJB_ELEM);
641
642 pushJsonbValueScalar(pstate, seq, &v);
643
644 tok = JsonbIteratorNext(&it, &v, true);
646 Assert(it == NULL);
647
648 return;
649 }
650
651 while ((tok = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
654 (tok == WJB_BEGIN_ARRAY &&
655 v.val.array.rawScalar) ? &v : NULL);
656}
#define JB_FSCALAR
Definition jsonb.h:203
static void pushJsonbValueScalar(JsonbInState *pstate, JsonbIteratorToken seq, JsonbValue *scalarVal)
Definition jsonb_util.c:663

References Assert, fb(), i, IsAJsonbScalar, JB_FSCALAR, jbvArray, jbvBinary, jbvObject, JsonbIteratorInit(), JsonbIteratorNext(), JsonbInState::parseState, 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_internal(), executeKeyValueMethod(), hstore_to_jsonb(), hstore_to_jsonb_loose(), HV_to_JsonbValue(), IteratorConcat(), jsonb_agg_finalfn(), jsonb_agg_transfn_worker(), jsonb_build_array_noargs(), jsonb_build_array_worker(), jsonb_build_object_noargs(), jsonb_build_object_worker(), 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_worker(), 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().

◆ to_jsonb_is_immutable()

bool to_jsonb_is_immutable ( Oid  typoid)
extern

Definition at line 1081 of file jsonb.c.

1082{
1083 bool has_mutable = false;
1084
1085 json_check_mutability(typoid, true, &has_mutable);
1086 return !has_mutable;
1087}
void json_check_mutability(Oid typoid, bool is_jsonb, bool *has_mutable)
Definition jsonfuncs.c:6078

References fb(), and json_check_mutability().

Referenced by contain_mutable_functions_walker().