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:547
uint32_t uint32
Definition c.h:546
size_t Size
Definition c.h:619
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 @172 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:2042
Datum jsonb_build_array_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
Definition jsonb.c:1247
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:1679
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:466
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:1531
const char * JsonbTypeName(JsonbValue *val)
Definition jsonb.c:173
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:1162
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:1781
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:475
bool JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
bool to_jsonb_is_immutable(Oid typoid)
Definition jsonb.c:1086
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
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:873
#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(), 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(), 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 1247 of file jsonb.c.

1249{
1250 int i;
1251 JsonbInState result;
1252
1253 memset(&result, 0, sizeof(JsonbInState));
1254
1256
1257 for (i = 0; i < nargs; i++)
1258 {
1259 if (absent_on_null && nulls[i])
1260 continue;
1261
1262 add_jsonb(args[i], nulls[i], &result, types[i], false);
1263 }
1264
1266
1267 return JsonbPGetDatum(JsonbValueToJsonb(result.result));
1268}
static void add_jsonb(Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
Definition jsonb.c:1053
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 1162 of file jsonb.c.

1164{
1165 int i;
1166 JsonbInState result;
1167
1168 if (nargs % 2 != 0)
1169 ereport(ERROR,
1171 errmsg("argument list must have even number of elements"),
1172 /* translator: %s is a SQL function name */
1173 errhint("The arguments of %s must consist of alternating keys and values.",
1174 "jsonb_build_object()")));
1175
1176 memset(&result, 0, sizeof(JsonbInState));
1177
1179 result.parseState->unique_keys = unique_keys;
1180 result.parseState->skip_nulls = absent_on_null;
1181
1182 for (i = 0; i < nargs; i += 2)
1183 {
1184 /* process key */
1185 bool skip;
1186
1187 if (nulls[i])
1188 ereport(ERROR,
1190 errmsg("argument %d: key must not be null", i + 1)));
1191
1192 /* skip null values if absent_on_null */
1193 skip = absent_on_null && nulls[i + 1];
1194
1195 /* we need to save skipped keys for the key uniqueness check */
1196 if (skip && !unique_keys)
1197 continue;
1198
1199 add_jsonb(args[i], false, &result, types[i], true);
1200
1201 /* process value */
1202 add_jsonb(args[i + 1], nulls[i + 1], &result, types[i + 1], false);
1203 }
1204
1206
1207 return JsonbPGetDatum(JsonbValueToJsonb(result.result));
1208}
int errhint(const char *fmt,...)
Definition elog.c:1330
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ereport(elevel,...)
Definition elog.h:150
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 1531 of file jsonfuncs.c.

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

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 1679 of file jsonfuncs.c.

1681{
1682 JsonbInState state = {0};
1684 bool *path_nulls = palloc0_array(bool, path_len);
1685
1686 if (newval->type == jbvArray && newval->val.array.rawScalar)
1687 *newval = newval->val.array.elems[0];
1688
1689 it = JsonbIteratorInit(&jb->root);
1690
1691 setPath(&it, path, path_nulls, path_len, &state, 0, newval,
1694
1696
1698}
#define palloc0_array(type, count)
Definition fe_memutils.h:77
#define JB_PATH_CREATE
Definition jsonfuncs.c:44
#define JB_PATH_CONSISTENT_POSITION
Definition jsonfuncs.c:52
#define JB_PATH_FILL_GAPS
Definition jsonfuncs.c:51
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:5173

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 1781 of file jsonb.c.

1782{
1785 JsonbValue tmp;
1786
1788 {
1789 /* inform caller about actual type of container */
1790 res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
1791 return false;
1792 }
1793
1794 /*
1795 * A root scalar is stored as an array of one element, so we get the array
1796 * and then its first (and only) member.
1797 */
1798 it = JsonbIteratorInit(jbc);
1799
1800 tok = JsonbIteratorNext(&it, &tmp, true);
1802 Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
1803
1804 tok = JsonbIteratorNext(&it, res, true);
1805 Assert(tok == WJB_ELEM);
1806 Assert(IsAJsonbScalar(res));
1807
1808 tok = JsonbIteratorNext(&it, &tmp, true);
1810
1811 tok = JsonbIteratorNext(&it, &tmp, true);
1812 Assert(tok == WJB_DONE);
1813
1814 return true;
1815}
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:223

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:232

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:53
static uint64 DatumGetUInt64(Datum X)
Definition postgres.h:433
static Datum UInt64GetDatum(uint64 X)
Definition postgres.h:443
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 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 466 of file jsonb.c.

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

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 475 of file jsonb.c.

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

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:711
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 173 of file jsonb.c.

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

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 2042 of file jsonb.c.

2043{
2044 if (JB_ROOT_IS_SCALAR(jb))
2045 {
2046 JsonbValue v;
2047
2048 (void) JsonbExtractScalar(&jb->root, &v);
2049
2050 if (v.type == jbvString)
2051 return pnstrdup(v.val.string.val, v.val.string.len);
2052 else if (v.type == jbvBool)
2053 return pstrdup(v.val.boolean ? "true" : "false");
2054 else if (v.type == jbvNumeric)
2056 PointerGetDatum(v.val.numeric)));
2057 else if (v.type == jbvNull)
2058 return pstrdup("null");
2059 else
2060 {
2061 elog(ERROR, "unrecognized jsonb value type %d", v.type);
2062 return NULL;
2063 }
2064 }
2065 else
2066 return JsonbToCString(NULL, &jb->root, VARSIZE(jb));
2067}
Datum numeric_out(PG_FUNCTION_ARGS)
Definition numeric.c:799
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition jsonb.c:1781
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:365

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 1086 of file jsonb.c.

1087{
1090
1091 json_categorize_type(typoid, true, &tcategory, &outfuncoid);
1092
1093 switch (tcategory)
1094 {
1095 case JSONTYPE_NULL:
1096 case JSONTYPE_BOOL:
1097 case JSONTYPE_JSON:
1098 case JSONTYPE_JSONB:
1099 return true;
1100
1101 case JSONTYPE_DATE:
1102 case JSONTYPE_TIMESTAMP:
1104 return false;
1105
1106 case JSONTYPE_ARRAY:
1107 return false; /* TODO recurse into elements */
1108
1109 case JSONTYPE_COMPOSITE:
1110 return false; /* TODO recurse into fields */
1111
1112 case JSONTYPE_NUMERIC:
1113 case JSONTYPE_CAST:
1114 case JSONTYPE_OTHER:
1116 }
1117
1118 return false; /* not reached */
1119}
void json_categorize_type(Oid typoid, bool is_jsonb, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition jsonfuncs.c:5964
JsonTypeCategory
Definition jsonfuncs.h:69
@ JSONTYPE_JSON
Definition jsonfuncs.h:76
@ JSONTYPE_NULL
Definition jsonfuncs.h:70
@ JSONTYPE_TIMESTAMP
Definition jsonfuncs.h:74
@ JSONTYPE_NUMERIC
Definition jsonfuncs.h:72
@ JSONTYPE_DATE
Definition jsonfuncs.h:73
@ JSONTYPE_BOOL
Definition jsonfuncs.h:71
@ JSONTYPE_OTHER
Definition jsonfuncs.h:81
@ JSONTYPE_CAST
Definition jsonfuncs.h:80
@ JSONTYPE_COMPOSITE
Definition jsonfuncs.h:79
@ JSONTYPE_ARRAY
Definition jsonfuncs.h:78
@ JSONTYPE_TIMESTAMPTZ
Definition jsonfuncs.h:75
@ JSONTYPE_JSONB
Definition jsonfuncs.h:77
char func_volatile(Oid funcid)
Definition lsyscache.c:1930

References fb(), func_volatile(), json_categorize_type(), JSONTYPE_ARRAY, JSONTYPE_BOOL, JSONTYPE_CAST, JSONTYPE_COMPOSITE, JSONTYPE_DATE, JSONTYPE_JSON, JSONTYPE_JSONB, JSONTYPE_NULL, JSONTYPE_NUMERIC, JSONTYPE_OTHER, JSONTYPE_TIMESTAMP, and JSONTYPE_TIMESTAMPTZ.

Referenced by contain_mutable_functions_walker().