PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
jsonb.h File Reference
#include "lib/stringinfo.h"
#include "utils/array.h"
#include "utils/numeric.h"
Include dependency graph for jsonb.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

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

Macros

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

Typedefs

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

Enumerations

enum  JsonbIteratorToken {
  WJB_DONE , WJB_KEY , WJB_VALUE , WJB_ELEM ,
  WJB_BEGIN_ARRAY , WJB_END_ARRAY , WJB_BEGIN_OBJECT , WJB_END_OBJECT
}
 
enum  jbvType {
  jbvNull = 0x0 , jbvString , jbvNumeric , jbvBool ,
  jbvArray = 0x10 , jbvObject , jbvBinary , jbvDatetime = 0x20
}
 
enum  JsonbIterState {
  JBI_ARRAY_START , JBI_ARRAY_ELEM , JBI_OBJECT_START , JBI_OBJECT_KEY ,
  JBI_OBJECT_VALUE
}
 

Functions

static JsonbDatumGetJsonbP (Datum d)
 
static JsonbDatumGetJsonbPCopy (Datum d)
 
static Datum JsonbPGetDatum (const Jsonb *p)
 
uint32 getJsonbOffset (const JsonbContainer *jc, int index)
 
uint32 getJsonbLength (const JsonbContainer *jc, int index)
 
int compareJsonbContainers (JsonbContainer *a, JsonbContainer *b)
 
JsonbValuefindJsonbValueFromContainer (JsonbContainer *container, uint32 flags, JsonbValue *key)
 
JsonbValuegetKeyJsonValueFromContainer (JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
 
JsonbValuegetIthJsonbValueFromContainer (JsonbContainer *container, uint32 i)
 
JsonbValuepushJsonbValue (JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
 
JsonbIteratorJsonbIteratorInit (JsonbContainer *container)
 
JsonbIteratorToken JsonbIteratorNext (JsonbIterator **it, JsonbValue *val, bool skipNested)
 
void JsonbToJsonbValue (Jsonb *jsonb, JsonbValue *val)
 
JsonbJsonbValueToJsonb (JsonbValue *val)
 
bool JsonbDeepContains (JsonbIterator **val, JsonbIterator **mContained)
 
void JsonbHashScalarValue (const JsonbValue *scalarVal, uint32 *hash)
 
void JsonbHashScalarValueExtended (const JsonbValue *scalarVal, uint64 *hash, uint64 seed)
 
char * JsonbToCString (StringInfo out, JsonbContainer *in, int estimated_len)
 
char * JsonbToCStringIndent (StringInfo out, JsonbContainer *in, int estimated_len)
 
char * JsonbUnquote (Jsonb *jb)
 
bool JsonbExtractScalar (JsonbContainer *jbc, JsonbValue *res)
 
const char * JsonbTypeName (JsonbValue *val)
 
Datum jsonb_set_element (Jsonb *jb, Datum *path, int path_len, JsonbValue *newval)
 
Datum jsonb_get_element (Jsonb *jb, Datum *path, int npath, bool *isnull, bool as_text)
 
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:231
@ jbvNull
Definition: jsonb.h:228
@ jbvDatetime
Definition: jsonb.h:244
const char * type

Definition at line 297 of file jsonb.h.

◆ JB_CMASK

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

Definition at line 200 of file jsonb.h.

◆ JB_FARRAY

#define JB_FARRAY   0x40000000

Definition at line 203 of file jsonb.h.

◆ JB_FOBJECT

#define JB_FOBJECT   0x20000000

Definition at line 202 of file jsonb.h.

◆ JB_FSCALAR

#define JB_FSCALAR   0x10000000 /* flag bits */

Definition at line 201 of file jsonb.h.

◆ JB_OFFSET_STRIDE

#define JB_OFFSET_STRIDE   32

Definition at line 178 of file jsonb.h.

◆ JB_ROOT_COUNT

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

Definition at line 219 of file jsonb.h.

◆ JB_ROOT_IS_ARRAY

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

Definition at line 222 of file jsonb.h.

◆ JB_ROOT_IS_OBJECT

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

Definition at line 221 of file jsonb.h.

◆ JB_ROOT_IS_SCALAR

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

Definition at line 220 of file jsonb.h.

◆ JBE_ADVANCE_OFFSET

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

Definition at line 162 of file jsonb.h.

◆ JBE_HAS_OFF

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

Definition at line 152 of file jsonb.h.

◆ JBE_ISBOOL

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

Definition at line 159 of file jsonb.h.

◆ JBE_ISBOOL_FALSE

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

Definition at line 158 of file jsonb.h.

◆ JBE_ISBOOL_TRUE

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

Definition at line 157 of file jsonb.h.

◆ JBE_ISCONTAINER

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

Definition at line 155 of file jsonb.h.

◆ JBE_ISNULL

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

Definition at line 156 of file jsonb.h.

◆ JBE_ISNUMERIC

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

Definition at line 154 of file jsonb.h.

◆ JBE_ISSTRING

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

Definition at line 153 of file jsonb.h.

◆ JBE_OFFLENFLD

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

Definition at line 151 of file jsonb.h.

◆ JENTRY_HAS_OFF

#define JENTRY_HAS_OFF   0x80000000

Definition at line 140 of file jsonb.h.

◆ JENTRY_ISBOOL_FALSE

#define JENTRY_ISBOOL_FALSE   0x20000000

Definition at line 145 of file jsonb.h.

◆ JENTRY_ISBOOL_TRUE

#define JENTRY_ISBOOL_TRUE   0x30000000

Definition at line 146 of file jsonb.h.

◆ JENTRY_ISCONTAINER

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

Definition at line 148 of file jsonb.h.

◆ JENTRY_ISNULL

#define JENTRY_ISNULL   0x40000000

Definition at line 147 of file jsonb.h.

◆ JENTRY_ISNUMERIC

#define JENTRY_ISNUMERIC   0x10000000

Definition at line 144 of file jsonb.h.

◆ JENTRY_ISSTRING

#define JENTRY_ISSTRING   0x00000000

Definition at line 143 of file jsonb.h.

◆ JENTRY_OFFLENMASK

#define JENTRY_OFFLENMASK   0x0FFFFFFF

Definition at line 138 of file jsonb.h.

◆ JENTRY_TYPEMASK

#define JENTRY_TYPEMASK   0x70000000

Definition at line 139 of file jsonb.h.

◆ JGIN_MAXLENGTH

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

Definition at line 68 of file jsonb.h.

◆ JGINFLAG_BOOL

#define JGINFLAG_BOOL   0x03 /* boolean value */

Definition at line 64 of file jsonb.h.

◆ JGINFLAG_HASHED

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

Definition at line 67 of file jsonb.h.

◆ JGINFLAG_KEY

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

Definition at line 62 of file jsonb.h.

◆ JGINFLAG_NULL

#define JGINFLAG_NULL   0x02 /* null value */

Definition at line 63 of file jsonb.h.

◆ JGINFLAG_NUM

#define JGINFLAG_NUM   0x04 /* numeric value */

Definition at line 65 of file jsonb.h.

◆ JGINFLAG_STR

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

Definition at line 66 of file jsonb.h.

◆ JsonbContainsStrategyNumber

#define JsonbContainsStrategyNumber   7

Definition at line 33 of file jsonb.h.

◆ JsonbExistsAllStrategyNumber

#define JsonbExistsAllStrategyNumber   11

Definition at line 36 of file jsonb.h.

◆ JsonbExistsAnyStrategyNumber

#define JsonbExistsAnyStrategyNumber   10

Definition at line 35 of file jsonb.h.

◆ JsonbExistsStrategyNumber

#define JsonbExistsStrategyNumber   9

Definition at line 34 of file jsonb.h.

◆ JsonbJsonpathExistsStrategyNumber

#define JsonbJsonpathExistsStrategyNumber   15

Definition at line 37 of file jsonb.h.

◆ JsonbJsonpathPredicateStrategyNumber

#define JsonbJsonpathPredicateStrategyNumber   16

Definition at line 38 of file jsonb.h.

◆ JsonContainerIsArray

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

Definition at line 209 of file jsonb.h.

◆ JsonContainerIsObject

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

Definition at line 208 of file jsonb.h.

◆ JsonContainerIsScalar

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

Definition at line 207 of file jsonb.h.

◆ JsonContainerSize

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

Definition at line 206 of file jsonb.h.

◆ PG_GETARG_JSONB_P

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

Definition at line 391 of file jsonb.h.

◆ PG_GETARG_JSONB_P_COPY

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

Definition at line 392 of file jsonb.h.

◆ PG_RETURN_JSONB_P

#define PG_RETURN_JSONB_P (   x)    PG_RETURN_POINTER(x)

Definition at line 393 of file jsonb.h.

Typedef Documentation

◆ JEntry

typedef uint32 JEntry

Definition at line 136 of file jsonb.h.

◆ JsonbContainer

◆ JsonbIterator

typedef struct JsonbIterator JsonbIterator

◆ JsonbPair

typedef struct JsonbPair JsonbPair

Definition at line 70 of file jsonb.h.

◆ JsonbParseState

◆ JsonbValue

typedef struct JsonbValue JsonbValue

Definition at line 71 of file jsonb.h.

Enumeration Type Documentation

◆ jbvType

enum jbvType
Enumerator
jbvNull 
jbvString 
jbvNumeric 
jbvBool 
jbvArray 
jbvObject 
jbvBinary 
jbvDatetime 

Definition at line 225 of file jsonb.h.

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

◆ JsonbIteratorToken

Enumerator
WJB_DONE 
WJB_KEY 
WJB_VALUE 
WJB_ELEM 
WJB_BEGIN_ARRAY 
WJB_END_ARRAY 
WJB_BEGIN_OBJECT 
WJB_END_OBJECT 

Definition at line 20 of file jsonb.h.

21{
23 WJB_KEY,
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 332 of file jsonb.h.

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

Function Documentation

◆ compareJsonbContainers()

int compareJsonbContainers ( JsonbContainer a,
JsonbContainer b 
)

Definition at line 191 of file jsonb_util.c.

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

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

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

◆ DatumGetJsonbP()

◆ DatumGetJsonbPCopy()

static Jsonb * DatumGetJsonbPCopy ( Datum  d)
inlinestatic

Definition at line 380 of file jsonb.h.

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

References PG_DETOAST_DATUM_COPY.

◆ findJsonbValueFromContainer()

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

Definition at line 345 of file jsonb_util.c.

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

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

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

◆ getIthJsonbValueFromContainer()

JsonbValue * getIthJsonbValueFromContainer ( JsonbContainer container,
uint32  i 
)

Definition at line 469 of file jsonb_util.c.

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

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 159 of file jsonb_util.c.

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

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 134 of file jsonb_util.c.

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

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

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

◆ getKeyJsonValueFromContainer()

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

Definition at line 399 of file jsonb_util.c.

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

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

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

◆ jsonb_build_array_worker()

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

Definition at line 1210 of file jsonb.c.

1212{
1213 int i;
1214 JsonbInState result;
1215
1216 memset(&result, 0, sizeof(JsonbInState));
1217
1218 result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
1219
1220 for (i = 0; i < nargs; i++)
1221 {
1222 if (absent_on_null && nulls[i])
1223 continue;
1224
1225 add_jsonb(args[i], nulls[i], &result, types[i], false);
1226 }
1227
1228 result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
1229
1230 return JsonbPGetDatum(JsonbValueToJsonb(result.res));
1231}
struct typedefs * types
Definition: ecpg.c:30
static void add_jsonb(Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
Definition: jsonb.c:1016
static Datum JsonbPGetDatum(const Jsonb *p)
Definition: jsonb.h:386
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:567
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:92
JsonbParseState * parseState
Definition: jsonb.c:30
JsonbValue * res
Definition: jsonb.c:31

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,
const Datum args,
const bool *  nulls,
const Oid types,
bool  absent_on_null,
bool  unique_keys 
)

Definition at line 1125 of file jsonb.c.

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

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_get_element()

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

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
1583 jbvp = getKeyJsonValueFromContainer(container,
1584 VARDATA_ANY(subscr),
1585 VARSIZE_ANY_EXHDR(subscr),
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
1627 jbvp = getIthJsonbValueFromContainer(container, index);
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;
1647 have_object = JsonContainerIsObject(container);
1648 have_array = JsonContainerIsArray(container);
1649 Assert(!JsonContainerIsScalar(container));
1650 }
1651 else
1652 {
1653 Assert(IsAJsonbScalar(jbvp));
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
1667 return PointerGetDatum(JsonbValueAsText(jbvp));
1668 }
1669 else
1670 {
1671 Jsonb *res = JsonbValueToJsonb(jbvp);
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:292
char * JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
Definition: jsonb.c:473
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:207
#define JB_ROOT_IS_OBJECT(jbp_)
Definition: jsonb.h:221
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:297
#define PG_RETURN_JSONB_P(x)
Definition: jsonb.h:393
#define JB_ROOT_IS_ARRAY(jbp_)
Definition: jsonb.h:222
#define JB_ROOT_IS_SCALAR(jbp_)
Definition: jsonb.h:220
JsonbValue * getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)
Definition: jsonb_util.c:469
static text * JsonbValueAsText(JsonbValue *v)
Definition: jsonfuncs.c:1805
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
Definition: string.c:50
JsonbContainer root
Definition: jsonb.h:215
Definition: c.h:692
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, getIthJsonbValueFromContainer(), getKeyJsonValueFromContainer(), i, IsAJsonbScalar, JB_ROOT_IS_ARRAY, JB_ROOT_IS_OBJECT, JB_ROOT_IS_SCALAR, jbvBinary, jbvNull, JsonbToCString(), JsonbValueAsText(), JsonbValueToJsonb(), JsonContainerIsArray, JsonContainerIsObject, JsonContainerIsScalar, JsonContainerSize, PG_RETURN_JSONB_P, PointerGetDatum(), Jsonb::root, strtoint(), TextDatumGetCString, JsonbValue::type, JsonbValue::val, VARDATA_ANY(), VARSIZE(), and VARSIZE_ANY_EXHDR().

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

◆ jsonb_set_element()

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

Definition at line 1679 of file jsonfuncs.c.

1681{
1682 JsonbValue *res;
1683 JsonbParseState *state = NULL;
1684 JsonbIterator *it;
1685 bool *path_nulls = palloc0(path_len * sizeof(bool));
1686
1687 if (newval->type == jbvArray && newval->val.array.rawScalar)
1688 *newval = newval->val.array.elems[0];
1689
1690 it = JsonbIteratorInit(&jb->root);
1691
1692 res = setPath(&it, path, path_nulls, path_len, &state, 0, newval,
1695
1696 pfree(path_nulls);
1697
1699}
#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:5204
#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
void * palloc0(Size size)
Definition: mcxt.c:1395
Definition: regguts.h:323

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

Referenced by jsonb_subscript_assign().

◆ JsonbDeepContains()

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

Definition at line 1072 of file jsonb_util.c.

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

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

◆ JsonbExtractScalar()

bool JsonbExtractScalar ( JsonbContainer jbc,
JsonbValue res 
)

Definition at line 1968 of file jsonb.c.

1969{
1970 JsonbIterator *it;
1972 JsonbValue tmp;
1973
1975 {
1976 /* inform caller about actual type of container */
1977 res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
1978 return false;
1979 }
1980
1981 /*
1982 * A root scalar is stored as an array of one element, so we get the array
1983 * and then its first (and only) member.
1984 */
1985 it = JsonbIteratorInit(jbc);
1986
1987 tok = JsonbIteratorNext(&it, &tmp, true);
1988 Assert(tok == WJB_BEGIN_ARRAY);
1989 Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
1990
1991 tok = JsonbIteratorNext(&it, res, true);
1992 Assert(tok == WJB_ELEM);
1993 Assert(IsAJsonbScalar(res));
1994
1995 tok = JsonbIteratorNext(&it, &tmp, true);
1996 Assert(tok == WJB_END_ARRAY);
1997
1998 tok = JsonbIteratorNext(&it, &tmp, true);
1999 Assert(tok == WJB_DONE);
2000
2001 return true;
2002}
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:223

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

Referenced by executeJsonPath(), jsonb_bool(), jsonb_float4(), jsonb_float8(), jsonb_int2(), jsonb_int4(), jsonb_int8(), jsonb_numeric(), JsonbContainerTypeName(), JsonbUnquote(), JsonItemFromDatum(), and JsonPathValue().

◆ JsonbHashScalarValue()

void JsonbHashScalarValue ( const JsonbValue scalarVal,
uint32 hash 
)

Definition at line 1326 of file jsonb_util.c.

1327{
1328 uint32 tmp;
1329
1330 /* Compute hash value for scalarVal */
1331 switch (scalarVal->type)
1332 {
1333 case jbvNull:
1334 tmp = 0x01;
1335 break;
1336 case jbvString:
1337 tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->val.string.val,
1338 scalarVal->val.string.len));
1339 break;
1340 case jbvNumeric:
1341 /* Must hash equal numerics to equal hash codes */
1343 NumericGetDatum(scalarVal->val.numeric)));
1344 break;
1345 case jbvBool:
1346 tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1347
1348 break;
1349 default:
1350 elog(ERROR, "invalid jsonb scalar type");
1351 tmp = 0; /* keep compiler quiet */
1352 break;
1353 }
1354
1355 /*
1356 * Combine hash values of successive keys, values and elements by rotating
1357 * the previous value left 1 bit, then XOR'ing in the new
1358 * key/value/element's hash value.
1359 */
1360 *hash = pg_rotate_left32(*hash, 1);
1361 *hash ^= tmp;
1362}
Datum hash_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:2714
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:682
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)
Definition: pg_bitutils.h:428
static uint32 DatumGetUInt32(Datum X)
Definition: postgres.h:232
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 1369 of file jsonb_util.c.

1371{
1372 uint64 tmp;
1373
1374 switch (scalarVal->type)
1375 {
1376 case jbvNull:
1377 tmp = seed + 0x01;
1378 break;
1379 case jbvString:
1380 tmp = DatumGetUInt64(hash_any_extended((const unsigned char *) scalarVal->val.string.val,
1381 scalarVal->val.string.len,
1382 seed));
1383 break;
1384 case jbvNumeric:
1386 NumericGetDatum(scalarVal->val.numeric),
1387 UInt64GetDatum(seed)));
1388 break;
1389 case jbvBool:
1390 if (seed)
1392 BoolGetDatum(scalarVal->val.boolean),
1393 UInt64GetDatum(seed)));
1394 else
1395 tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1396
1397 break;
1398 default:
1399 elog(ERROR, "invalid jsonb scalar type");
1400 break;
1401 }
1402
1404 *hash ^= tmp;
1405}
Datum hash_numeric_extended(PG_FUNCTION_ARGS)
Definition: numeric.c:2794
uint64_t uint64
Definition: c.h:539
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:684
#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:413
static Datum UInt64GetDatum(uint64 X)
Definition: postgres.h:423
static Datum BoolGetDatum(bool X)
Definition: postgres.h:112

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 856 of file jsonb_util.c.

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

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

◆ JsonbPGetDatum()

◆ JsonbToCString()

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

Definition at line 473 of file jsonb.c.

474{
475 return JsonbToCStringWorker(out, in, estimated_len, false);
476}
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition: jsonb.c:491

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

483{
484 return JsonbToCStringWorker(out, in, estimated_len, true);
485}

References JsonbToCStringWorker().

Referenced by jsonb_pretty().

◆ JsonbToJsonbValue()

void JsonbToJsonbValue ( Jsonb jsonb,
JsonbValue val 
)

Definition at line 72 of file jsonb_util.c.

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

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

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

◆ JsonbTypeName()

const char * JsonbTypeName ( JsonbValue val)

Definition at line 180 of file jsonb.c.

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

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

Referenced by executeItemOptUnwrapTarget(), and JsonbContainerTypeName().

◆ JsonbUnquote()

char * JsonbUnquote ( Jsonb jb)

Definition at line 2229 of file jsonb.c.

2230{
2231 if (JB_ROOT_IS_SCALAR(jb))
2232 {
2233 JsonbValue v;
2234
2235 (void) JsonbExtractScalar(&jb->root, &v);
2236
2237 if (v.type == jbvString)
2238 return pnstrdup(v.val.string.val, v.val.string.len);
2239 else if (v.type == jbvBool)
2240 return pstrdup(v.val.boolean ? "true" : "false");
2241 else if (v.type == jbvNumeric)
2243 PointerGetDatum(v.val.numeric)));
2244 else if (v.type == jbvNull)
2245 return pstrdup("null");
2246 else
2247 {
2248 elog(ERROR, "unrecognized jsonb value type %d", v.type);
2249 return NULL;
2250 }
2251 }
2252 else
2253 return JsonbToCString(NULL, &jb->root, VARSIZE(jb));
2254}
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:799
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1968
char * pstrdup(const char *in)
Definition: mcxt.c:1759
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1770
static char * DatumGetCString(Datum X)
Definition: postgres.h:345

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

◆ JsonbValueToJsonb()

Jsonb * JsonbValueToJsonb ( JsonbValue val)

Definition at line 92 of file jsonb_util.c.

93{
94 Jsonb *out;
95
97 {
98 /* Scalar value */
99 JsonbParseState *pstate = NULL;
100 JsonbValue *res;
101 JsonbValue scalarArray;
102
103 scalarArray.type = jbvArray;
104 scalarArray.val.array.rawScalar = true;
105 scalarArray.val.array.nElems = 1;
106
107 pushJsonbValue(&pstate, WJB_BEGIN_ARRAY, &scalarArray);
108 pushJsonbValue(&pstate, WJB_ELEM, val);
109 res = pushJsonbValue(&pstate, WJB_END_ARRAY, NULL);
110
111 out = convertToJsonb(res);
112 }
113 else if (val->type == jbvObject || val->type == jbvArray)
114 {
115 out = convertToJsonb(val);
116 }
117 else
118 {
119 Assert(val->type == jbvBinary);
120 out = palloc(VARHDRSZ + val->val.binary.len);
121 SET_VARSIZE(out, VARHDRSZ + val->val.binary.len);
122 memcpy(VARDATA(out), val->val.binary.data, val->val.binary.len);
123 }
124
125 return out;
126}
static Jsonb * convertToJsonb(JsonbValue *val)
Definition: jsonb_util.c:1558
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(), IsAJsonbScalar, jbvArray, jbvBinary, jbvObject, palloc(), pushJsonbValue(), SET_VARSIZE(), JsonbValue::type, JsonbValue::val, 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_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(), JsonPathQuery(), JsonTablePlanScanNextRow(), plperl_to_jsonb(), plpython_to_jsonb(), populate_scalar(), and transform_jsonb_string_values().

◆ pushJsonbValue()

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

Definition at line 567 of file jsonb_util.c.

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

References Assert(), i, JB_FSCALAR, jbvArray, jbvBinary, jbvObject, JsonbIteratorInit(), JsonbIteratorNext(), 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)

Definition at line 1049 of file jsonb.c.

1050{
1051 JsonTypeCategory tcategory;
1052 Oid outfuncoid;
1053
1054 json_categorize_type(typoid, true, &tcategory, &outfuncoid);
1055
1056 switch (tcategory)
1057 {
1058 case JSONTYPE_NULL:
1059 case JSONTYPE_BOOL:
1060 case JSONTYPE_JSON:
1061 case JSONTYPE_JSONB:
1062 return true;
1063
1064 case JSONTYPE_DATE:
1065 case JSONTYPE_TIMESTAMP:
1067 return false;
1068
1069 case JSONTYPE_ARRAY:
1070 return false; /* TODO recurse into elements */
1071
1072 case JSONTYPE_COMPOSITE:
1073 return false; /* TODO recurse into fields */
1074
1075 case JSONTYPE_NUMERIC:
1076 case JSONTYPE_CAST:
1077 case JSONTYPE_OTHER:
1078 return func_volatile(outfuncoid) == PROVOLATILE_IMMUTABLE;
1079 }
1080
1081 return false; /* not reached */
1082}
void json_categorize_type(Oid typoid, bool is_jsonb, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition: jsonfuncs.c:5999
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:1947
unsigned int Oid
Definition: postgres_ext.h:32

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