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

Go to the source code of this file.

Data Structures

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

Macros

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

Typedefs

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

Enumerations

enum  JsonbIteratorToken {
  WJB_DONE , WJB_KEY , WJB_VALUE , WJB_ELEM ,
  WJB_BEGIN_ARRAY , WJB_END_ARRAY , WJB_BEGIN_OBJECT , WJB_END_OBJECT
}
 
enum  jbvType {
  jbvNull = 0x0 , jbvString , jbvNumeric , jbvBool ,
  jbvArray = 0x10 , jbvObject , jbvBinary , jbvDatetime = 0x20
}
 
enum  JsonbIterState {
  JBI_ARRAY_START , JBI_ARRAY_ELEM , JBI_OBJECT_START , JBI_OBJECT_KEY ,
  JBI_OBJECT_VALUE
}
 
enum  JsonbTypeCategory {
  JSONBTYPE_NULL , JSONBTYPE_BOOL , JSONBTYPE_NUMERIC , JSONBTYPE_DATE ,
  JSONBTYPE_TIMESTAMP , JSONBTYPE_TIMESTAMPTZ , JSONBTYPE_JSON , JSONBTYPE_JSONB ,
  JSONBTYPE_ARRAY , JSONBTYPE_COMPOSITE , JSONBTYPE_JSONCAST , JSONBTYPE_OTHER
}
 

Functions

uint32 getJsonbOffset (const JsonbContainer *jc, int index)
 
uint32 getJsonbLength (const JsonbContainer *jc, int index)
 
int compareJsonbContainers (JsonbContainer *a, JsonbContainer *b)
 
JsonbValuefindJsonbValueFromContainer (JsonbContainer *sheader, uint32 flags, JsonbValue *key)
 
JsonbValuegetKeyJsonValueFromContainer (JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
 
JsonbValuegetIthJsonbValueFromContainer (JsonbContainer *sheader, uint32 i)
 
JsonbValuepushJsonbValue (JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
 
JsonbIteratorJsonbIteratorInit (JsonbContainer *container)
 
JsonbIteratorToken JsonbIteratorNext (JsonbIterator **it, JsonbValue *val, bool skipNested)
 
void JsonbToJsonbValue (Jsonb *jsonb, JsonbValue *val)
 
JsonbJsonbValueToJsonb (JsonbValue *val)
 
bool JsonbDeepContains (JsonbIterator **val, JsonbIterator **mContained)
 
void JsonbHashScalarValue (const JsonbValue *scalarVal, uint32 *hash)
 
void JsonbHashScalarValueExtended (const JsonbValue *scalarVal, uint64 *hash, uint64 seed)
 
Datum jsonb_from_text (text *js, bool unique_keys)
 
char * JsonbToCString (StringInfo out, JsonbContainer *in, int estimated_len)
 
char * JsonbToCStringIndent (StringInfo out, JsonbContainer *in, int estimated_len)
 
JsonbJsonbMakeEmptyArray (void)
 
JsonbJsonbMakeEmptyObject (void)
 
char * JsonbUnquote (Jsonb *jb)
 
bool JsonbExtractScalar (JsonbContainer *jbc, JsonbValue *res)
 
const char * JsonbTypeName (JsonbValue *jb)
 
Datum jsonb_set_element (Jsonb *jb, Datum *path, int path_len, JsonbValue *newval)
 
Datum jsonb_get_element (Jsonb *jb, Datum *path, int npath, bool *isnull, bool as_text)
 
bool to_jsonb_is_immutable (Oid typoid)
 
void jsonb_categorize_type (Oid typoid, JsonbTypeCategory *tcategory, Oid *outfuncoid)
 
Datum to_jsonb_worker (Datum val, JsonbTypeCategory tcategory, Oid outfuncoid)
 
Datum jsonb_build_object_worker (int nargs, Datum *args, bool *nulls, Oid *types, bool absent_on_null, bool unique_keys)
 
Datum jsonb_build_array_worker (int nargs, Datum *args, bool *nulls, Oid *types, bool absent_on_null)
 

Macro Definition Documentation

◆ DatumGetJsonbP

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

Definition at line 71 of file jsonb.h.

◆ DatumGetJsonbPCopy

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

Definition at line 72 of file jsonb.h.

◆ IsAJsonbScalar

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

Definition at line 305 of file jsonb.h.

◆ JB_CMASK

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

Definition at line 208 of file jsonb.h.

◆ JB_FARRAY

#define JB_FARRAY   0x40000000

Definition at line 211 of file jsonb.h.

◆ JB_FOBJECT

#define JB_FOBJECT   0x20000000

Definition at line 210 of file jsonb.h.

◆ JB_FSCALAR

#define JB_FSCALAR   0x10000000 /* flag bits */

Definition at line 209 of file jsonb.h.

◆ JB_OFFSET_STRIDE

#define JB_OFFSET_STRIDE   32

Definition at line 186 of file jsonb.h.

◆ JB_ROOT_COUNT

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

Definition at line 227 of file jsonb.h.

◆ JB_ROOT_IS_ARRAY

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

Definition at line 230 of file jsonb.h.

◆ JB_ROOT_IS_OBJECT

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

Definition at line 229 of file jsonb.h.

◆ JB_ROOT_IS_SCALAR

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

Definition at line 228 of file jsonb.h.

◆ JBE_ADVANCE_OFFSET

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

Definition at line 170 of file jsonb.h.

◆ JBE_HAS_OFF

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

Definition at line 160 of file jsonb.h.

◆ JBE_ISBOOL

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

Definition at line 167 of file jsonb.h.

◆ JBE_ISBOOL_FALSE

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

Definition at line 166 of file jsonb.h.

◆ JBE_ISBOOL_TRUE

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

Definition at line 165 of file jsonb.h.

◆ JBE_ISCONTAINER

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

Definition at line 163 of file jsonb.h.

◆ JBE_ISNULL

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

Definition at line 164 of file jsonb.h.

◆ JBE_ISNUMERIC

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

Definition at line 162 of file jsonb.h.

◆ JBE_ISSTRING

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

Definition at line 161 of file jsonb.h.

◆ JBE_OFFLENFLD

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

Definition at line 159 of file jsonb.h.

◆ JENTRY_HAS_OFF

#define JENTRY_HAS_OFF   0x80000000

Definition at line 148 of file jsonb.h.

◆ JENTRY_ISBOOL_FALSE

#define JENTRY_ISBOOL_FALSE   0x20000000

Definition at line 153 of file jsonb.h.

◆ JENTRY_ISBOOL_TRUE

#define JENTRY_ISBOOL_TRUE   0x30000000

Definition at line 154 of file jsonb.h.

◆ JENTRY_ISCONTAINER

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

Definition at line 156 of file jsonb.h.

◆ JENTRY_ISNULL

#define JENTRY_ISNULL   0x40000000

Definition at line 155 of file jsonb.h.

◆ JENTRY_ISNUMERIC

#define JENTRY_ISNUMERIC   0x10000000

Definition at line 152 of file jsonb.h.

◆ JENTRY_ISSTRING

#define JENTRY_ISSTRING   0x00000000

Definition at line 151 of file jsonb.h.

◆ JENTRY_OFFLENMASK

#define JENTRY_OFFLENMASK   0x0FFFFFFF

Definition at line 146 of file jsonb.h.

◆ JENTRY_TYPEMASK

#define JENTRY_TYPEMASK   0x70000000

Definition at line 147 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.

◆ JsonbPGetDatum

#define JsonbPGetDatum (   p)    PointerGetDatum(p)

Definition at line 73 of file jsonb.h.

◆ JsonContainerIsArray

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

Definition at line 217 of file jsonb.h.

◆ JsonContainerIsObject

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

Definition at line 216 of file jsonb.h.

◆ JsonContainerIsScalar

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

Definition at line 215 of file jsonb.h.

◆ JsonContainerSize

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

Definition at line 214 of file jsonb.h.

◆ PG_GETARG_JSONB_P

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

Definition at line 74 of file jsonb.h.

◆ PG_GETARG_JSONB_P_COPY

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

Definition at line 75 of file jsonb.h.

◆ PG_RETURN_JSONB_P

#define PG_RETURN_JSONB_P (   x)    PG_RETURN_POINTER(x)

Definition at line 76 of file jsonb.h.

Typedef Documentation

◆ JEntry

typedef uint32 JEntry

Definition at line 144 of file jsonb.h.

◆ JsonbContainer

◆ JsonbIterator

typedef struct JsonbIterator JsonbIterator

◆ JsonbPair

typedef struct JsonbPair JsonbPair

Definition at line 1 of file jsonb.h.

◆ JsonbParseState

◆ JsonbValue

typedef struct JsonbValue JsonbValue

Definition at line 1 of file jsonb.h.

Enumeration Type Documentation

◆ jbvType

enum jbvType
Enumerator
jbvNull 
jbvString 
jbvNumeric 
jbvBool 
jbvArray 
jbvObject 
jbvBinary 
jbvDatetime 

Definition at line 233 of file jsonb.h.

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

◆ JsonbIteratorToken

Enumerator
WJB_DONE 
WJB_KEY 
WJB_VALUE 
WJB_ELEM 
WJB_BEGIN_ARRAY 
WJB_END_ARRAY 
WJB_BEGIN_OBJECT 
WJB_END_OBJECT 

Definition at line 20 of file jsonb.h.

21 {
22  WJB_DONE,
23  WJB_KEY,
24  WJB_VALUE,
25  WJB_ELEM,
JsonbIteratorToken
Definition: jsonb.h:21
@ WJB_KEY
Definition: jsonb.h:23
@ WJB_DONE
Definition: jsonb.h:22
@ WJB_END_ARRAY
Definition: jsonb.h:27
@ WJB_VALUE
Definition: jsonb.h:24
@ WJB_END_OBJECT
Definition: jsonb.h:29
@ WJB_ELEM
Definition: jsonb.h:25
@ WJB_BEGIN_OBJECT
Definition: jsonb.h:28
@ WJB_BEGIN_ARRAY
Definition: jsonb.h:26

◆ JsonbIterState

Enumerator
JBI_ARRAY_START 
JBI_ARRAY_ELEM 
JBI_OBJECT_START 
JBI_OBJECT_KEY 
JBI_OBJECT_VALUE 

Definition at line 340 of file jsonb.h.

341 {
JsonbIterState
Definition: jsonb.h:341
@ JBI_OBJECT_VALUE
Definition: jsonb.h:346
@ JBI_ARRAY_START
Definition: jsonb.h:342
@ JBI_ARRAY_ELEM
Definition: jsonb.h:343
@ JBI_OBJECT_START
Definition: jsonb.h:344
@ JBI_OBJECT_KEY
Definition: jsonb.h:345

◆ JsonbTypeCategory

Enumerator
JSONBTYPE_NULL 
JSONBTYPE_BOOL 
JSONBTYPE_NUMERIC 
JSONBTYPE_DATE 
JSONBTYPE_TIMESTAMP 
JSONBTYPE_TIMESTAMPTZ 
JSONBTYPE_JSON 
JSONBTYPE_JSONB 
JSONBTYPE_ARRAY 
JSONBTYPE_COMPOSITE 
JSONBTYPE_JSONCAST 
JSONBTYPE_OTHER 

Definition at line 380 of file jsonb.h.

381 {
382  JSONBTYPE_NULL, /* null, so we didn't bother to identify */
383  JSONBTYPE_BOOL, /* boolean (built-in types only) */
384  JSONBTYPE_NUMERIC, /* numeric (ditto) */
385  JSONBTYPE_DATE, /* we use special formatting for datetimes */
386  JSONBTYPE_TIMESTAMP, /* we use special formatting for timestamp */
387  JSONBTYPE_TIMESTAMPTZ, /* ... and timestamptz */
388  JSONBTYPE_JSON, /* JSON */
389  JSONBTYPE_JSONB, /* JSONB */
390  JSONBTYPE_ARRAY, /* array */
391  JSONBTYPE_COMPOSITE, /* composite */
392  JSONBTYPE_JSONCAST, /* something with an explicit cast to JSON */
393  JSONBTYPE_OTHER /* all else */
JsonbTypeCategory
Definition: jsonb.h:381
@ JSONBTYPE_OTHER
Definition: jsonb.h:393
@ JSONBTYPE_TIMESTAMPTZ
Definition: jsonb.h:387
@ JSONBTYPE_JSONB
Definition: jsonb.h:389
@ JSONBTYPE_DATE
Definition: jsonb.h:385
@ JSONBTYPE_NUMERIC
Definition: jsonb.h:384
@ JSONBTYPE_ARRAY
Definition: jsonb.h:390
@ JSONBTYPE_COMPOSITE
Definition: jsonb.h:391
@ JSONBTYPE_JSON
Definition: jsonb.h:388
@ JSONBTYPE_BOOL
Definition: jsonb.h:383
@ JSONBTYPE_NULL
Definition: jsonb.h:382
@ JSONBTYPE_TIMESTAMP
Definition: jsonb.h:386
@ JSONBTYPE_JSONCAST
Definition: jsonb.h:392

Function Documentation

◆ compareJsonbContainers()

int compareJsonbContainers ( JsonbContainer a,
JsonbContainer b 
)

Definition at line 193 of file jsonb_util.c.

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

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

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

◆ findJsonbValueFromContainer()

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

Definition at line 346 of file jsonb_util.c.

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

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

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

◆ getIthJsonbValueFromContainer()

JsonbValue* getIthJsonbValueFromContainer ( JsonbContainer sheader,
uint32  i 
)

Definition at line 470 of file jsonb_util.c.

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

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

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

◆ getJsonbLength()

uint32 getJsonbLength ( const JsonbContainer jc,
int  index 
)

Definition at line 161 of file jsonb_util.c.

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

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

Referenced by fillJsonbValue(), and getKeyJsonValueFromContainer().

◆ getJsonbOffset()

uint32 getJsonbOffset ( const JsonbContainer jc,
int  index 
)

Definition at line 136 of file jsonb_util.c.

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

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

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

◆ getKeyJsonValueFromContainer()

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

Definition at line 400 of file jsonb_util.c.

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

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

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

◆ jsonb_build_array_worker()

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

Definition at line 1271 of file jsonb.c.

1273 {
1274  int i;
1275  JsonbInState result;
1276 
1277  memset(&result, 0, sizeof(JsonbInState));
1278 
1279  result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
1280 
1281  for (i = 0; i < nargs; i++)
1282  {
1283  if (absent_on_null && nulls[i])
1284  continue;
1285 
1286  add_jsonb(args[i], nulls[i], &result, types[i], false);
1287  }
1288 
1289  result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
1290 
1291  return JsonbPGetDatum(JsonbValueToJsonb(result.res));
1292 }
struct typedefs * types
Definition: ecpg.c:29
static void add_jsonb(Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
Definition: jsonb.c:1095
#define JsonbPGetDatum(p)
Definition: jsonb.h:73
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:94
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:568
JsonbParseState * parseState
Definition: jsonb.c:35
JsonbValue * res
Definition: jsonb.c:36

References add_jsonb(), generate_unaccent_rules::args, i, JsonbPGetDatum, JsonbValueToJsonb(), JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, 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,
Datum args,
bool nulls,
Oid types,
bool  absent_on_null,
bool  unique_keys 
)

Definition at line 1186 of file jsonb.c.

1188 {
1189  int i;
1190  JsonbInState result;
1191 
1192  if (nargs % 2 != 0)
1193  ereport(ERROR,
1194  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1195  errmsg("argument list must have even number of elements"),
1196  /* translator: %s is a SQL function name */
1197  errhint("The arguments of %s must consist of alternating keys and values.",
1198  "jsonb_build_object()")));
1199 
1200  memset(&result, 0, sizeof(JsonbInState));
1201 
1202  result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1203  result.parseState->unique_keys = unique_keys;
1204  result.parseState->skip_nulls = absent_on_null;
1205 
1206  for (i = 0; i < nargs; i += 2)
1207  {
1208  /* process key */
1209  bool skip;
1210 
1211  if (nulls[i])
1212  ereport(ERROR,
1213  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1214  errmsg("argument %d: key must not be null", i + 1)));
1215 
1216  /* skip null values if absent_on_null */
1217  skip = absent_on_null && nulls[i + 1];
1218 
1219  /* we need to save skipped keys for the key uniqueness check */
1220  if (skip && !unique_keys)
1221  continue;
1222 
1223  add_jsonb(args[i], false, &result, types[i], true);
1224 
1225  /* process value */
1226  add_jsonb(args[i + 1], nulls[i + 1], &result, types[i + 1], false);
1227  }
1228 
1229  result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1230 
1231  return JsonbPGetDatum(JsonbValueToJsonb(result.res));
1232 }
int errhint(const char *fmt,...)
Definition: elog.c:1151
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ereport(elevel,...)
Definition: elog.h:143
static const struct exclude_list_item skip[]
Definition: pg_checksums.c:116
bool unique_keys
Definition: jsonb.h:332
bool skip_nulls
Definition: jsonb.h:333

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

Referenced by ExecEvalJsonConstructor(), and jsonb_build_object().

◆ jsonb_categorize_type()

void jsonb_categorize_type ( Oid  typoid,
JsonbTypeCategory tcategory,
Oid outfuncoid 
)

Definition at line 613 of file jsonb.c.

616 {
617  bool typisvarlena;
618 
619  /* Look through any domain */
620  typoid = getBaseType(typoid);
621 
622  *outfuncoid = InvalidOid;
623 
624  /*
625  * We need to get the output function for everything except date and
626  * timestamp types, booleans, array and composite types, json and jsonb,
627  * and non-builtin types where there's a cast to json. In this last case
628  * we return the oid of the cast function instead.
629  */
630 
631  switch (typoid)
632  {
633  case BOOLOID:
634  *tcategory = JSONBTYPE_BOOL;
635  break;
636 
637  case INT2OID:
638  case INT4OID:
639  case INT8OID:
640  case FLOAT4OID:
641  case FLOAT8OID:
642  case NUMERICOID:
643  getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
644  *tcategory = JSONBTYPE_NUMERIC;
645  break;
646 
647  case DATEOID:
648  *tcategory = JSONBTYPE_DATE;
649  break;
650 
651  case TIMESTAMPOID:
652  *tcategory = JSONBTYPE_TIMESTAMP;
653  break;
654 
655  case TIMESTAMPTZOID:
656  *tcategory = JSONBTYPE_TIMESTAMPTZ;
657  break;
658 
659  case JSONBOID:
660  *tcategory = JSONBTYPE_JSONB;
661  break;
662 
663  case JSONOID:
664  *tcategory = JSONBTYPE_JSON;
665  break;
666 
667  default:
668  /* Check for arrays and composites */
669  if (OidIsValid(get_element_type(typoid)) || typoid == ANYARRAYOID
670  || typoid == ANYCOMPATIBLEARRAYOID || typoid == RECORDARRAYOID)
671  *tcategory = JSONBTYPE_ARRAY;
672  else if (type_is_rowtype(typoid)) /* includes RECORDOID */
673  *tcategory = JSONBTYPE_COMPOSITE;
674  else
675  {
676  /* It's probably the general case ... */
677  *tcategory = JSONBTYPE_OTHER;
678 
679  /*
680  * but first let's look for a cast to json (note: not to
681  * jsonb) if it's not built-in.
682  */
683  if (typoid >= FirstNormalObjectId)
684  {
685  Oid castfunc;
686  CoercionPathType ctype;
687 
688  ctype = find_coercion_pathway(JSONOID, typoid,
689  COERCION_EXPLICIT, &castfunc);
690  if (ctype == COERCION_PATH_FUNC && OidIsValid(castfunc))
691  {
692  *tcategory = JSONBTYPE_JSONCAST;
693  *outfuncoid = castfunc;
694  }
695  else
696  {
697  /* not a cast type, so just get the usual output func */
698  getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
699  }
700  }
701  else
702  {
703  /* any other builtin type */
704  getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
705  }
706  break;
707  }
708  }
709 }
#define OidIsValid(objectId)
Definition: c.h:710
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2716
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2612
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2864
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2478
CoercionPathType find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId, CoercionContext ccontext, Oid *funcid)
CoercionPathType
Definition: parse_coerce.h:25
@ COERCION_PATH_FUNC
Definition: parse_coerce.h:27
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
@ COERCION_EXPLICIT
Definition: primnodes.h:475
#define FirstNormalObjectId
Definition: transam.h:197

References COERCION_EXPLICIT, COERCION_PATH_FUNC, find_coercion_pathway(), FirstNormalObjectId, get_element_type(), getBaseType(), getTypeOutputInfo(), InvalidOid, JSONBTYPE_ARRAY, JSONBTYPE_BOOL, JSONBTYPE_COMPOSITE, JSONBTYPE_DATE, JSONBTYPE_JSON, JSONBTYPE_JSONB, JSONBTYPE_JSONCAST, JSONBTYPE_NUMERIC, JSONBTYPE_OTHER, JSONBTYPE_TIMESTAMP, JSONBTYPE_TIMESTAMPTZ, OidIsValid, and type_is_rowtype().

Referenced by add_jsonb(), array_to_jsonb_internal(), composite_to_jsonb(), ExecInitExprRec(), jsonb_agg_transfn_worker(), jsonb_object_agg_transfn_worker(), to_jsonb(), and to_jsonb_is_immutable().

◆ jsonb_from_text()

Datum jsonb_from_text ( text js,
bool  unique_keys 
)

Definition at line 146 of file jsonb.c.

147 {
148  return jsonb_from_cstring(VARDATA_ANY(js),
149  VARSIZE_ANY_EXHDR(js),
150  unique_keys);
151 }
static Datum jsonb_from_cstring(char *json, int len, bool unique_keys)
Definition: jsonb.c:243
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354

References jsonb_from_cstring(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by ExecEvalJsonConstructor().

◆ jsonb_get_element()

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

Definition at line 1471 of file jsonfuncs.c.

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

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

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

◆ jsonb_set_element()

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

Definition at line 1617 of file jsonfuncs.c.

1619 {
1620  JsonbValue *res;
1621  JsonbParseState *state = NULL;
1622  JsonbIterator *it;
1623  bool *path_nulls = palloc0(path_len * sizeof(bool));
1624 
1625  if (newval->type == jbvArray && newval->val.array.rawScalar)
1626  *newval = newval->val.array.elems[0];
1627 
1628  it = JsonbIteratorInit(&jb->root);
1629 
1630  res = setPath(&it, path, path_nulls, path_len, &state, 0, newval,
1633 
1634  pfree(path_nulls);
1635 
1637 }
#define newval
static JsonbValue * setPath(JsonbIterator **it, Datum *path_elems, bool *path_nulls, int path_len, JsonbParseState **st, int level, JsonbValue *newval, int op_type)
Definition: jsonfuncs.c:4836
#define JB_PATH_CREATE
Definition: jsonfuncs.c:41
#define JB_PATH_CONSISTENT_POSITION
Definition: jsonfuncs.c:49
#define JB_PATH_FILL_GAPS
Definition: jsonfuncs.c:48
void * palloc0(Size size)
Definition: mcxt.c:1099
Definition: regguts.h:318

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

Referenced by jsonb_subscript_assign().

◆ JsonbDeepContains()

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

Definition at line 1064 of file jsonb_util.c.

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

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

Referenced by jsonb_contained(), and jsonb_contains().

◆ JsonbExtractScalar()

bool JsonbExtractScalar ( JsonbContainer jbc,
JsonbValue res 
)

Definition at line 2034 of file jsonb.c.

2035 {
2036  JsonbIterator *it;
2038  JsonbValue tmp;
2039 
2040  if (!JsonContainerIsArray(jbc) || !JsonContainerIsScalar(jbc))
2041  {
2042  /* inform caller about actual type of container */
2043  res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
2044  return false;
2045  }
2046 
2047  /*
2048  * A root scalar is stored as an array of one element, so we get the array
2049  * and then its first (and only) member.
2050  */
2051  it = JsonbIteratorInit(jbc);
2052 
2053  tok = JsonbIteratorNext(&it, &tmp, true);
2054  Assert(tok == WJB_BEGIN_ARRAY);
2055  Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
2056 
2057  tok = JsonbIteratorNext(&it, res, true);
2058  Assert(tok == WJB_ELEM);
2060 
2061  tok = JsonbIteratorNext(&it, &tmp, true);
2062  Assert(tok == WJB_END_ARRAY);
2063 
2064  tok = JsonbIteratorNext(&it, &tmp, true);
2065  Assert(tok == WJB_DONE);
2066 
2067  return true;
2068 }
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:155

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

Referenced by ExecPrepareJsonItemCoercion(), 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 
)

Definition at line 1318 of file jsonb_util.c.

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

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

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

◆ JsonbHashScalarValueExtended()

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

Definition at line 1361 of file jsonb_util.c.

1363 {
1364  uint64 tmp;
1365 
1366  switch (scalarVal->type)
1367  {
1368  case jbvNull:
1369  tmp = seed + 0x01;
1370  break;
1371  case jbvString:
1372  tmp = DatumGetUInt64(hash_any_extended((const unsigned char *) scalarVal->val.string.val,
1373  scalarVal->val.string.len,
1374  seed));
1375  break;
1376  case jbvNumeric:
1378  NumericGetDatum(scalarVal->val.numeric),
1379  UInt64GetDatum(seed)));
1380  break;
1381  case jbvBool:
1382  if (seed)
1384  BoolGetDatum(scalarVal->val.boolean),
1385  UInt64GetDatum(seed)));
1386  else
1387  tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1388 
1389  break;
1390  default:
1391  elog(ERROR, "invalid jsonb scalar type");
1392  break;
1393  }
1394 
1396  *hash ^= tmp;
1397 }
Datum hash_numeric_extended(PG_FUNCTION_ARGS)
Definition: numeric.c:2694
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:633
#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
#define DatumGetUInt64(X)
Definition: postgres.h:678
#define BoolGetDatum(X)
Definition: postgres.h:446
#define UInt64GetDatum(X)
Definition: postgres.h:692

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

Referenced by jsonb_hash_extended().

◆ JsonbIteratorInit()

◆ JsonbIteratorNext()

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

Definition at line 855 of file jsonb_util.c.

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

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

Referenced by compareJsonbContainers(), datum_to_jsonb(), each_worker_jsonb(), elements_worker_jsonb(), executeAnyItem(), executeKeyValueMethod(), gin_extract_jsonb(), gin_extract_jsonb_path(), iterate_jsonb_values(), IteratorConcat(), jsonb_agg_transfn_worker(), jsonb_delete(), jsonb_delete_array(), jsonb_delete_idx(), jsonb_hash(), jsonb_hash_extended(), jsonb_object_agg_transfn_worker(), 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().

◆ JsonbMakeEmptyArray()

Jsonb* JsonbMakeEmptyArray ( void  )

Definition at line 2232 of file jsonb.c.

2233 {
2234  JsonbValue jbv;
2235 
2236  jbv.type = jbvArray;
2237  jbv.val.array.elems = NULL;
2238  jbv.val.array.nElems = 0;
2239  jbv.val.array.rawScalar = false;
2240 
2241  return JsonbValueToJsonb(&jbv);
2242 }

References jbvArray, JsonbValueToJsonb(), JsonbValue::type, and JsonbValue::val.

Referenced by ExecEvalJsonBehavior().

◆ JsonbMakeEmptyObject()

Jsonb* JsonbMakeEmptyObject ( void  )

Definition at line 2248 of file jsonb.c.

2249 {
2250  JsonbValue jbv;
2251 
2252  jbv.type = jbvObject;
2253  jbv.val.object.pairs = NULL;
2254  jbv.val.object.nPairs = 0;
2255 
2256  return JsonbValueToJsonb(&jbv);
2257 }

References jbvObject, JsonbValueToJsonb(), JsonbValue::type, and JsonbValue::val.

Referenced by ExecEvalJsonBehavior().

◆ JsonbToCString()

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

Definition at line 450 of file jsonb.c.

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

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

Definition at line 459 of file jsonb.c.

460 {
461  return JsonbToCStringWorker(out, in, estimated_len, true);
462 }

References JsonbToCStringWorker().

Referenced by jsonb_pretty().

◆ JsonbToJsonbValue()

void JsonbToJsonbValue ( Jsonb jsonb,
JsonbValue val 
)

Definition at line 74 of file jsonb_util.c.

75 {
76  val->type = jbvBinary;
77  val->val.binary.data = &jsonb->root;
78  val->val.binary.len = VARSIZE(jsonb) - VARHDRSZ;
79 }

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

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

◆ JsonbTypeName()

const char* JsonbTypeName ( JsonbValue jb)

Definition at line 178 of file jsonb.c.

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

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

Referenced by executeItemOptUnwrapTarget(), and JsonbContainerTypeName().

◆ JsonbUnquote()

char* JsonbUnquote ( Jsonb jb)

Definition at line 2263 of file jsonb.c.

2264 {
2265  if (JB_ROOT_IS_SCALAR(jb))
2266  {
2267  JsonbValue v;
2268 
2269  (void) JsonbExtractScalar(&jb->root, &v);
2270 
2271  if (v.type == jbvString)
2272  return pnstrdup(v.val.string.val, v.val.string.len);
2273  else if (v.type == jbvBool)
2274  return pstrdup(v.val.boolean ? "true" : "false");
2275  else if (v.type == jbvNumeric)
2277  PointerGetDatum(v.val.numeric)));
2278  else if (v.type == jbvNull)
2279  return pstrdup("null");
2280  else
2281  {
2282  elog(ERROR, "unrecognized jsonb value type %d", v.type);
2283  return NULL;
2284  }
2285  }
2286  else
2287  return JsonbToCString(NULL, &jb->root, VARSIZE(jb));
2288 }
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:735
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:2034
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1316
char * pstrdup(const char *in)
Definition: mcxt.c:1305
#define DatumGetCString(X)
Definition: postgres.h:610

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

Referenced by ExecEvalJsonExprCoercion().

◆ JsonbValueToJsonb()

Jsonb* JsonbValueToJsonb ( JsonbValue val)

Definition at line 94 of file jsonb_util.c.

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

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

Referenced by each_worker_jsonb(), elements_worker_jsonb(), ExecEvalJsonExpr(), ExecPrepareJsonItemCoercion(), executeKeyValueMethod(), hstore_to_jsonb(), hstore_to_jsonb_loose(), jsonb_agg_finalfn(), jsonb_agg_transfn_worker(), 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_agg_transfn_worker(), 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(), JsonbMakeEmptyArray(), JsonbMakeEmptyObject(), JsonPathQuery(), JsonTableNextRow(), plperl_to_jsonb(), plpython_to_jsonb(), populate_scalar(), to_jsonb_worker(), and transform_jsonb_string_values().

◆ pushJsonbValue()

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

Definition at line 568 of file jsonb_util.c.

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

References Assert(), i, JB_FSCALAR, jbvArray, jbvBinary, jbvObject, JsonbIteratorInit(), JsonbIteratorNext(), pushJsonbValueScalar(), res, JsonbValue::type, JsonbValue::val, WJB_BEGIN_ARRAY, WJB_BEGIN_OBJECT, WJB_DONE, WJB_ELEM, WJB_END_ARRAY, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

Referenced by array_dim_to_jsonb(), array_to_jsonb_internal(), AV_to_JsonbValue(), composite_to_jsonb(), datum_to_jsonb(), executeKeyValueMethod(), hstore_to_jsonb(), hstore_to_jsonb_loose(), HV_to_JsonbValue(), IteratorConcat(), jsonb_agg_finalfn(), jsonb_agg_transfn_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(), setPath(), setPathArray(), setPathObject(), SV_to_JsonbValue(), transform_jsonb_string_values(), and wrapItemsInArray().

◆ to_jsonb_is_immutable()

bool to_jsonb_is_immutable ( Oid  typoid)

Definition at line 1131 of file jsonb.c.

1132 {
1133  JsonbTypeCategory tcategory;
1134  Oid outfuncoid;
1135 
1136  jsonb_categorize_type(typoid, &tcategory, &outfuncoid);
1137 
1138  switch (tcategory)
1139  {
1140  case JSONBTYPE_BOOL:
1141  case JSONBTYPE_JSON:
1142  case JSONBTYPE_JSONB:
1143  return true;
1144 
1145  case JSONBTYPE_DATE:
1146  case JSONBTYPE_TIMESTAMP:
1147  case JSONBTYPE_TIMESTAMPTZ:
1148  return false;
1149 
1150  case JSONBTYPE_ARRAY:
1151  return false; /* TODO recurse into elements */
1152 
1153  case JSONBTYPE_COMPOSITE:
1154  return false; /* TODO recurse into fields */
1155 
1156  case JSONBTYPE_NUMERIC:
1157  case JSONBTYPE_JSONCAST:
1158  default:
1159  return func_volatile(outfuncoid) == PROVOLATILE_IMMUTABLE;
1160  }
1161 }
void jsonb_categorize_type(Oid typoid, JsonbTypeCategory *tcategory, Oid *outfuncoid)
Definition: jsonb.c:613
char func_volatile(Oid funcid)
Definition: lsyscache.c:1761

References func_volatile(), jsonb_categorize_type(), JSONBTYPE_ARRAY, JSONBTYPE_BOOL, JSONBTYPE_COMPOSITE, JSONBTYPE_DATE, JSONBTYPE_JSON, JSONBTYPE_JSONB, JSONBTYPE_JSONCAST, JSONBTYPE_NUMERIC, JSONBTYPE_TIMESTAMP, and JSONBTYPE_TIMESTAMPTZ.

Referenced by contain_mutable_functions_walker().

◆ to_jsonb_worker()

Datum to_jsonb_worker ( Datum  val,
JsonbTypeCategory  tcategory,
Oid  outfuncoid 
)

Definition at line 1119 of file jsonb.c.

1120 {
1121  JsonbInState result;
1122 
1123  memset(&result, 0, sizeof(JsonbInState));
1124 
1125  datum_to_jsonb(val, false, &result, tcategory, outfuncoid, false);
1126 
1127  return JsonbPGetDatum(JsonbValueToJsonb(result.res));
1128 }
static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result, JsonbTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: jsonb.c:721

References datum_to_jsonb(), JsonbPGetDatum, JsonbValueToJsonb(), JsonbInState::res, and val.

Referenced by ExecEvalJsonConstructor(), and to_jsonb().