PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 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 DatumGetJsonb(d)   ((Jsonb *) PG_DETOAST_DATUM(d))
 
#define JsonbGetDatum(p)   PointerGetDatum(p)
 
#define PG_GETARG_JSONB(x)   DatumGetJsonb(PG_GETARG_DATUM(x))
 
#define PG_RETURN_JSONB(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
}
 
enum  JsonbIterState {
  JBI_ARRAY_START, JBI_ARRAY_ELEM, JBI_OBJECT_START, JBI_OBJECT_KEY,
  JBI_OBJECT_VALUE
}
 

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)
 
JsonbValuegetIthJsonbValueFromContainer (JsonbContainer *sheader, uint32 i)
 
JsonbValuepushJsonbValue (JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbVal)
 
JsonbIteratorJsonbIteratorInit (JsonbContainer *container)
 
JsonbIteratorToken JsonbIteratorNext (JsonbIterator **it, JsonbValue *val, bool skipNested)
 
JsonbJsonbValueToJsonb (JsonbValue *val)
 
bool JsonbDeepContains (JsonbIterator **val, JsonbIterator **mContained)
 
void JsonbHashScalarValue (const JsonbValue *scalarVal, uint32 *hash)
 
char * JsonbToCString (StringInfo out, JsonbContainer *in, int estimated_len)
 
char * JsonbToCStringIndent (StringInfo out, JsonbContainer *in, int estimated_len)
 

Macro Definition Documentation

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

Definition at line 68 of file jsonb.h.

Referenced by datum_to_jsonb().

#define IsAJsonbScalar (   jsonbval)
Value:
((jsonbval)->type >= jbvNull && \
(jsonbval)->type <= jbvBool)
Definition: jsonb.h:234
Definition: jsonb.h:231

Definition at line 283 of file jsonb.h.

Referenced by convertJsonbValue(), JsonbDeepContains(), JsonbIteratorNext(), JsonbValueToJsonb(), JsValueToJsObject(), and pushJsonbValueScalar().

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

Definition at line 203 of file jsonb.h.

#define JB_FSCALAR   0x10000000 /* flag bits */

Definition at line 204 of file jsonb.h.

Referenced by convertJsonbArray().

#define JB_OFFSET_STRIDE   32

Definition at line 181 of file jsonb.h.

Referenced by convertJsonbArray(), and convertJsonbObject().

#define JB_ROOT_IS_OBJECT (   jbp_)    ((*(uint32 *) VARDATA(jbp_) & JB_FOBJECT) != 0)
#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_OFFLENFLD(je_)
Definition: jsonb.h:154
uint32 JEntry
Definition: jsonb.h:139
#define JBE_HAS_OFF(je_)
Definition: jsonb.h:155

Definition at line 165 of file jsonb.h.

Referenced by findJsonbValueFromContainer(), and JsonbIteratorNext().

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

Definition at line 155 of file jsonb.h.

Referenced by getJsonbLength(), and getJsonbOffset().

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

Definition at line 162 of file jsonb.h.

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

Definition at line 161 of file jsonb.h.

Referenced by fillJsonbValue().

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

Definition at line 160 of file jsonb.h.

Referenced by fillJsonbValue().

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

Definition at line 158 of file jsonb.h.

Referenced by fillJsonbValue().

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

Definition at line 159 of file jsonb.h.

Referenced by fillJsonbValue().

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

Definition at line 157 of file jsonb.h.

Referenced by fillJsonbValue().

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

Definition at line 156 of file jsonb.h.

Referenced by fillJsonbValue().

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

Definition at line 154 of file jsonb.h.

Referenced by convertJsonbArray(), convertJsonbObject(), getJsonbLength(), and getJsonbOffset().

#define JENTRY_HAS_OFF   0x80000000

Definition at line 143 of file jsonb.h.

Referenced by convertJsonbArray(), and convertJsonbObject().

#define JENTRY_ISBOOL_FALSE   0x20000000

Definition at line 148 of file jsonb.h.

Referenced by convertJsonbScalar().

#define JENTRY_ISBOOL_TRUE   0x30000000

Definition at line 149 of file jsonb.h.

Referenced by convertJsonbScalar().

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

Definition at line 151 of file jsonb.h.

Referenced by convertJsonbArray(), and convertJsonbObject().

#define JENTRY_ISNULL   0x40000000

Definition at line 150 of file jsonb.h.

Referenced by convertJsonbScalar().

#define JENTRY_ISNUMERIC   0x10000000

Definition at line 147 of file jsonb.h.

Referenced by convertJsonbScalar().

#define JENTRY_ISSTRING   0x00000000

Definition at line 146 of file jsonb.h.

#define JENTRY_OFFLENMASK   0x0FFFFFFF

Definition at line 141 of file jsonb.h.

Referenced by checkStringLen(), convertJsonbArray(), and convertJsonbObject().

#define JENTRY_TYPEMASK   0x70000000

Definition at line 142 of file jsonb.h.

Referenced by convertJsonbArray(), and convertJsonbObject().

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

Definition at line 65 of file jsonb.h.

Referenced by make_text_key().

#define JGINFLAG_BOOL   0x03 /* boolean value */

Definition at line 61 of file jsonb.h.

Referenced by make_scalar_key().

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

Definition at line 64 of file jsonb.h.

Referenced by make_text_key().

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

Definition at line 59 of file jsonb.h.

Referenced by gin_extract_jsonb_query(), and make_scalar_key().

#define JGINFLAG_NULL   0x02 /* null value */

Definition at line 60 of file jsonb.h.

Referenced by make_scalar_key().

#define JGINFLAG_NUM   0x04 /* numeric value */

Definition at line 62 of file jsonb.h.

Referenced by make_scalar_key().

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

Definition at line 63 of file jsonb.h.

Referenced by make_scalar_key().

#define JsonbExistsAllStrategyNumber   11

Definition at line 36 of file jsonb.h.

Referenced by gin_consistent_jsonb(), gin_extract_jsonb_query(), and gin_triconsistent_jsonb().

#define JsonbExistsAnyStrategyNumber   10

Definition at line 35 of file jsonb.h.

Referenced by gin_consistent_jsonb(), gin_extract_jsonb_query(), and gin_triconsistent_jsonb().

#define JsonbExistsStrategyNumber   9

Definition at line 34 of file jsonb.h.

Referenced by gin_consistent_jsonb(), gin_extract_jsonb_query(), and gin_triconsistent_jsonb().

#define JsonbGetDatum (   p)    PointerGetDatum(p)

Definition at line 69 of file jsonb.h.

Referenced by jsonb_to_tsvector(), and populate_scalar().

#define JsonContainerIsArray (   jc)    (((jc)->header & JB_FARRAY) != 0)
#define JsonContainerIsObject (   jc)    (((jc)->header & JB_FOBJECT) != 0)
#define JsonContainerIsScalar (   jc)    (((jc)->header & JB_FSCALAR) != 0)

Definition at line 210 of file jsonb.h.

Referenced by iteratorFromContainer(), JsValueToJsObject(), and populate_array_dim_jsonb().

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

Typedef Documentation

Definition at line 139 of file jsonb.h.

Definition at line 73 of file jsonb.h.

Definition at line 74 of file jsonb.h.

Enumeration Type Documentation

enum jbvType
Enumerator
jbvNull 
jbvString 
jbvNumeric 
jbvBool 
jbvArray 
jbvObject 
jbvBinary 

Definition at line 228 of file jsonb.h.

229 {
230  /* Scalar types */
231  jbvNull = 0x0,
232  jbvString,
233  jbvNumeric,
234  jbvBool,
235  /* Composite types */
236  jbvArray = 0x10,
237  jbvObject,
238  /* Binary (i.e. struct Jsonb) jbvArray/jbvObject */
239  jbvBinary
240 };
Definition: jsonb.h:234
Definition: jsonb.h:231
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,
Definition: jsonb.h:22
Definition: jsonb.h:23
JsonbIteratorToken
Definition: jsonb.h:20
Definition: jsonb.h:25
Enumerator
JBI_ARRAY_START 
JBI_ARRAY_ELEM 
JBI_OBJECT_START 
JBI_OBJECT_KEY 
JBI_OBJECT_VALUE 

Definition at line 315 of file jsonb.h.

Function Documentation

int compareJsonbContainers ( JsonbContainer a,
JsonbContainer b 
)

Definition at line 178 of file jsonb_util.c.

References Assert, compareJsonbScalarValue(), elog, ERROR, i, jbvArray, jbvBinary, jbvBool, jbvNull, jbvNumeric, jbvObject, jbvString, JsonbIteratorInit(), JsonbIteratorNext(), NULL, 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().

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

Definition at line 327 of file jsonb_util.c.

References Assert, JsonbContainer::children, difference(), equalsJsonbScalarValue(), fillJsonbValue(), getJsonbLength(), getJsonbOffset(), i, JB_FARRAY, JB_FOBJECT, JBE_ADVANCE_OFFSET, jbvString, JsonContainerIsArray, JsonContainerIsObject, JsonContainerSize, lengthCompareJsonbStringValue(), NULL, palloc(), pfree(), result, JsonbValue::type, and JsonbValue::val.

Referenced by findJsonbValueFromContainerLen(), jsonb_exists(), jsonb_exists_all(), jsonb_exists_any(), and JsonbDeepContains().

329 {
330  JEntry *children = container->children;
331  int count = JsonContainerSize(container);
333 
334  Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
335 
336  /* Quick out without a palloc cycle if object/array is empty */
337  if (count <= 0)
338  return NULL;
339 
340  result = palloc(sizeof(JsonbValue));
341 
342  if ((flags & JB_FARRAY) && JsonContainerIsArray(container))
343  {
344  char *base_addr = (char *) (children + count);
345  uint32 offset = 0;
346  int i;
347 
348  for (i = 0; i < count; i++)
349  {
350  fillJsonbValue(container, i, base_addr, offset, result);
351 
352  if (key->type == result->type)
353  {
354  if (equalsJsonbScalarValue(key, result))
355  return result;
356  }
357 
358  JBE_ADVANCE_OFFSET(offset, children[i]);
359  }
360  }
361  else if ((flags & JB_FOBJECT) && JsonContainerIsObject(container))
362  {
363  /* Since this is an object, account for *Pairs* of Jentrys */
364  char *base_addr = (char *) (children + count * 2);
365  uint32 stopLow = 0,
366  stopHigh = count;
367 
368  /* Object key passed by caller must be a string */
369  Assert(key->type == jbvString);
370 
371  /* Binary search on object/pair keys *only* */
372  while (stopLow < stopHigh)
373  {
374  uint32 stopMiddle;
375  int difference;
376  JsonbValue candidate;
377 
378  stopMiddle = stopLow + (stopHigh - stopLow) / 2;
379 
380  candidate.type = jbvString;
381  candidate.val.string.val =
382  base_addr + getJsonbOffset(container, stopMiddle);
383  candidate.val.string.len = getJsonbLength(container, stopMiddle);
384 
385  difference = lengthCompareJsonbStringValue(&candidate, key);
386 
387  if (difference == 0)
388  {
389  /* Found our key, return corresponding value */
390  int index = stopMiddle + count;
391 
392  fillJsonbValue(container, index, base_addr,
393  getJsonbOffset(container, index),
394  result);
395 
396  return result;
397  }
398  else
399  {
400  if (difference < 0)
401  stopLow = stopMiddle + 1;
402  else
403  stopHigh = stopMiddle;
404  }
405  }
406  }
407 
408  /* Not found */
409  pfree(result);
410  return NULL;
411 }
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:121
#define JB_FARRAY
Definition: jsonb.h:206
char * val
Definition: jsonb.h:259
uint32 getJsonbLength(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:146
return result
Definition: formatting.c:1632
Definition: type.h:89
#define JBE_ADVANCE_OFFSET(offset, je)
Definition: jsonb.h:165
void pfree(void *pointer)
Definition: mcxt.c:950
#define JsonContainerSize(jc)
Definition: jsonb.h:209
unsigned int uint32
Definition: c.h:268
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition: jsonb_util.c:456
#define JsonContainerIsArray(jc)
Definition: jsonb.h:212
static bool equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b)
Definition: jsonb_util.c:1256
#define JsonContainerIsObject(jc)
Definition: jsonb.h:211
Datum difference(PG_FUNCTION_ARGS)
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define JB_FOBJECT
Definition: jsonb.h:205
uint32 JEntry
Definition: jsonb.h:139
enum jbvType type
Definition: jsonb.h:250
void * palloc(Size size)
Definition: mcxt.c:849
int i
static int lengthCompareJsonbStringValue(const void *a, const void *b)
Definition: jsonb_util.c:1719
JsonbValue* getIthJsonbValueFromContainer ( JsonbContainer sheader,
uint32  i 
)

Definition at line 419 of file jsonb_util.c.

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

Referenced by get_jsonb_path_all(), jsonb_array_element(), and jsonb_array_element_text().

420 {
422  char *base_addr;
423  uint32 nelements;
424 
425  if (!JsonContainerIsArray(container))
426  elog(ERROR, "not a jsonb array");
427 
428  nelements = JsonContainerSize(container);
429  base_addr = (char *) &container->children[nelements];
430 
431  if (i >= nelements)
432  return NULL;
433 
434  result = palloc(sizeof(JsonbValue));
435 
436  fillJsonbValue(container, i, base_addr,
437  getJsonbOffset(container, i),
438  result);
439 
440  return result;
441 }
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:121
return result
Definition: formatting.c:1632
#define ERROR
Definition: elog.h:43
#define JsonContainerSize(jc)
Definition: jsonb.h:209
unsigned int uint32
Definition: c.h:268
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition: jsonb_util.c:456
#define JsonContainerIsArray(jc)
Definition: jsonb.h:212
#define NULL
Definition: c.h:229
void * palloc(Size size)
Definition: mcxt.c:849
int i
#define elog
Definition: elog.h:219
uint32 getJsonbLength ( const JsonbContainer jc,
int  index 
)

Definition at line 146 of file jsonb_util.c.

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

Referenced by fillJsonbValue(), and findJsonbValueFromContainer().

147 {
148  uint32 off;
149  uint32 len;
150 
151  /*
152  * If the length is stored directly in the JEntry, just return it.
153  * Otherwise, get the begin offset of the entry, and subtract that from
154  * the stored end+1 offset.
155  */
156  if (JBE_HAS_OFF(jc->children[index]))
157  {
158  off = getJsonbOffset(jc, index);
159  len = JBE_OFFLENFLD(jc->children[index]) - off;
160  }
161  else
162  len = JBE_OFFLENFLD(jc->children[index]);
163 
164  return len;
165 }
JEntry children[FLEXIBLE_ARRAY_MEMBER]
Definition: jsonb.h:197
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:121
#define JBE_OFFLENFLD(je_)
Definition: jsonb.h:154
Definition: type.h:89
unsigned int uint32
Definition: c.h:268
#define JBE_HAS_OFF(je_)
Definition: jsonb.h:155
uint32 getJsonbOffset ( const JsonbContainer jc,
int  index 
)

Definition at line 121 of file jsonb_util.c.

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

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

122 {
123  uint32 offset = 0;
124  int i;
125 
126  /*
127  * Start offset of this entry is equal to the end offset of the previous
128  * entry. Walk backwards to the most recent entry stored as an end
129  * offset, returning that offset plus any lengths in between.
130  */
131  for (i = index - 1; i >= 0; i--)
132  {
133  offset += JBE_OFFLENFLD(jc->children[i]);
134  if (JBE_HAS_OFF(jc->children[i]))
135  break;
136  }
137 
138  return offset;
139 }
JEntry children[FLEXIBLE_ARRAY_MEMBER]
Definition: jsonb.h:197
#define JBE_OFFLENFLD(je_)
Definition: jsonb.h:154
Definition: type.h:89
unsigned int uint32
Definition: c.h:268
#define JBE_HAS_OFF(je_)
Definition: jsonb.h:155
int i
bool JsonbDeepContains ( JsonbIterator **  val,
JsonbIterator **  mContained 
)

Definition at line 963 of file jsonb_util.c.

References Assert, check_stack_depth(), elog, equalsJsonbScalarValue(), ERROR, findJsonbValueFromContainer(), i, IsAJsonbScalar, JB_FARRAY, JB_FOBJECT, jbvArray, jbvBinary, jbvObject, JsonbDeepContains(), JsonbIteratorInit(), JsonbIteratorNext(), NULL, palloc(), pfree(), JsonbValue::type, JsonbValue::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().

964 {
965  JsonbValue vval,
966  vcontained;
967  JsonbIteratorToken rval,
968  rcont;
969 
970  /*
971  * Guard against stack overflow due to overly complex Jsonb.
972  *
973  * Functions called here independently take this precaution, but that
974  * might not be sufficient since this is also a recursive function.
975  */
977 
978  rval = JsonbIteratorNext(val, &vval, false);
979  rcont = JsonbIteratorNext(mContained, &vcontained, false);
980 
981  if (rval != rcont)
982  {
983  /*
984  * The differing return values can immediately be taken as indicating
985  * two differing container types at this nesting level, which is
986  * sufficient reason to give up entirely (but it should be the case
987  * that they're both some container type).
988  */
989  Assert(rval == WJB_BEGIN_OBJECT || rval == WJB_BEGIN_ARRAY);
990  Assert(rcont == WJB_BEGIN_OBJECT || rcont == WJB_BEGIN_ARRAY);
991  return false;
992  }
993  else if (rcont == WJB_BEGIN_OBJECT)
994  {
995  Assert(vval.type == jbvObject);
996  Assert(vcontained.type == jbvObject);
997 
998  /*
999  * If the lhs has fewer pairs than the rhs, it can't possibly contain
1000  * the rhs. (This conclusion is safe only because we de-duplicate
1001  * keys in all Jsonb objects; thus there can be no corresponding
1002  * optimization in the array case.) The case probably won't arise
1003  * often, but since it's such a cheap check we may as well make it.
1004  */
1005  if (vval.val.object.nPairs < vcontained.val.object.nPairs)
1006  return false;
1007 
1008  /* Work through rhs "is it contained within?" object */
1009  for (;;)
1010  {
1011  JsonbValue *lhsVal; /* lhsVal is from pair in lhs object */
1012 
1013  rcont = JsonbIteratorNext(mContained, &vcontained, false);
1014 
1015  /*
1016  * When we get through caller's rhs "is it contained within?"
1017  * object without failing to find one of its values, it's
1018  * contained.
1019  */
1020  if (rcont == WJB_END_OBJECT)
1021  return true;
1022 
1023  Assert(rcont == WJB_KEY);
1024 
1025  /* First, find value by key... */
1026  lhsVal = findJsonbValueFromContainer((*val)->container,
1027  JB_FOBJECT,
1028  &vcontained);
1029 
1030  if (!lhsVal)
1031  return false;
1032 
1033  /*
1034  * ...at this stage it is apparent that there is at least a key
1035  * match for this rhs pair.
1036  */
1037  rcont = JsonbIteratorNext(mContained, &vcontained, true);
1038 
1039  Assert(rcont == WJB_VALUE);
1040 
1041  /*
1042  * Compare rhs pair's value with lhs pair's value just found using
1043  * key
1044  */
1045  if (lhsVal->type != vcontained.type)
1046  {
1047  return false;
1048  }
1049  else if (IsAJsonbScalar(lhsVal))
1050  {
1051  if (!equalsJsonbScalarValue(lhsVal, &vcontained))
1052  return false;
1053  }
1054  else
1055  {
1056  /* Nested container value (object or array) */
1057  JsonbIterator *nestval,
1058  *nestContained;
1059 
1060  Assert(lhsVal->type == jbvBinary);
1061  Assert(vcontained.type == jbvBinary);
1062 
1063  nestval = JsonbIteratorInit(lhsVal->val.binary.data);
1064  nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1065 
1066  /*
1067  * Match "value" side of rhs datum object's pair recursively.
1068  * It's a nested structure.
1069  *
1070  * Note that nesting still has to "match up" at the right
1071  * nesting sub-levels. However, there need only be zero or
1072  * more matching pairs (or elements) at each nesting level
1073  * (provided the *rhs* pairs/elements *all* match on each
1074  * level), which enables searching nested structures for a
1075  * single String or other primitive type sub-datum quite
1076  * effectively (provided the user constructed the rhs nested
1077  * structure such that we "know where to look").
1078  *
1079  * In other words, the mapping of container nodes in the rhs
1080  * "vcontained" Jsonb to internal nodes on the lhs is
1081  * injective, and parent-child edges on the rhs must be mapped
1082  * to parent-child edges on the lhs to satisfy the condition
1083  * of containment (plus of course the mapped nodes must be
1084  * equal).
1085  */
1086  if (!JsonbDeepContains(&nestval, &nestContained))
1087  return false;
1088  }
1089  }
1090  }
1091  else if (rcont == WJB_BEGIN_ARRAY)
1092  {
1093  JsonbValue *lhsConts = NULL;
1094  uint32 nLhsElems = vval.val.array.nElems;
1095 
1096  Assert(vval.type == jbvArray);
1097  Assert(vcontained.type == jbvArray);
1098 
1099  /*
1100  * Handle distinction between "raw scalar" pseudo arrays, and real
1101  * arrays.
1102  *
1103  * A raw scalar may contain another raw scalar, and an array may
1104  * contain a raw scalar, but a raw scalar may not contain an array. We
1105  * don't do something like this for the object case, since objects can
1106  * only contain pairs, never raw scalars (a pair is represented by an
1107  * rhs object argument with a single contained pair).
1108  */
1109  if (vval.val.array.rawScalar && !vcontained.val.array.rawScalar)
1110  return false;
1111 
1112  /* Work through rhs "is it contained within?" array */
1113  for (;;)
1114  {
1115  rcont = JsonbIteratorNext(mContained, &vcontained, true);
1116 
1117  /*
1118  * When we get through caller's rhs "is it contained within?"
1119  * array without failing to find one of its values, it's
1120  * contained.
1121  */
1122  if (rcont == WJB_END_ARRAY)
1123  return true;
1124 
1125  Assert(rcont == WJB_ELEM);
1126 
1127  if (IsAJsonbScalar(&vcontained))
1128  {
1129  if (!findJsonbValueFromContainer((*val)->container,
1130  JB_FARRAY,
1131  &vcontained))
1132  return false;
1133  }
1134  else
1135  {
1136  uint32 i;
1137 
1138  /*
1139  * If this is first container found in rhs array (at this
1140  * depth), initialize temp lhs array of containers
1141  */
1142  if (lhsConts == NULL)
1143  {
1144  uint32 j = 0;
1145 
1146  /* Make room for all possible values */
1147  lhsConts = palloc(sizeof(JsonbValue) * nLhsElems);
1148 
1149  for (i = 0; i < nLhsElems; i++)
1150  {
1151  /* Store all lhs elements in temp array */
1152  rcont = JsonbIteratorNext(val, &vval, true);
1153  Assert(rcont == WJB_ELEM);
1154 
1155  if (vval.type == jbvBinary)
1156  lhsConts[j++] = vval;
1157  }
1158 
1159  /* No container elements in temp array, so give up now */
1160  if (j == 0)
1161  return false;
1162 
1163  /* We may have only partially filled array */
1164  nLhsElems = j;
1165  }
1166 
1167  /* XXX: Nested array containment is O(N^2) */
1168  for (i = 0; i < nLhsElems; i++)
1169  {
1170  /* Nested container value (object or array) */
1171  JsonbIterator *nestval,
1172  *nestContained;
1173  bool contains;
1174 
1175  nestval = JsonbIteratorInit(lhsConts[i].val.binary.data);
1176  nestContained = JsonbIteratorInit(vcontained.val.binary.data);
1177 
1178  contains = JsonbDeepContains(&nestval, &nestContained);
1179 
1180  if (nestval)
1181  pfree(nestval);
1182  if (nestContained)
1183  pfree(nestContained);
1184  if (contains)
1185  break;
1186  }
1187 
1188  /*
1189  * Report rhs container value is not contained if couldn't
1190  * match rhs container to *some* lhs cont
1191  */
1192  if (i == nLhsElems)
1193  return false;
1194  }
1195  }
1196  }
1197  else
1198  {
1199  elog(ERROR, "invalid jsonb container type");
1200  }
1201 
1202  elog(ERROR, "unexpectedly fell off end of jsonb container");
1203  return false;
1204 }
#define JB_FARRAY
Definition: jsonb.h:206
bool JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
Definition: jsonb_util.c:963
char * val
Definition: jsonb.h:259
void pfree(void *pointer)
Definition: mcxt.c:950
#define ERROR
Definition: elog.h:43
void check_stack_depth(void)
Definition: postgres.c:3117
unsigned int uint32
Definition: c.h:268
Definition: jsonb.h:23
static bool equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b)
Definition: jsonb_util.c:1256
JsonbIteratorToken
Definition: jsonb.h:20
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:718
#define JB_FOBJECT
Definition: jsonb.h:205
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:283
enum jbvType type
Definition: jsonb.h:250
void * palloc(Size size)
Definition: mcxt.c:849
int i
JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)
Definition: jsonb_util.c:327
#define elog
Definition: elog.h:219
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:754
Definition: jsonb.h:25
void JsonbHashScalarValue ( const JsonbValue scalarVal,
uint32 hash 
)

Definition at line 1214 of file jsonb_util.c.

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

Referenced by gin_extract_jsonb_path(), and jsonb_hash().

1215 {
1216  uint32 tmp;
1217 
1218  /* Compute hash value for scalarVal */
1219  switch (scalarVal->type)
1220  {
1221  case jbvNull:
1222  tmp = 0x01;
1223  break;
1224  case jbvString:
1225  tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->val.string.val,
1226  scalarVal->val.string.len));
1227  break;
1228  case jbvNumeric:
1229  /* Must hash equal numerics to equal hash codes */
1231  NumericGetDatum(scalarVal->val.numeric)));
1232  break;
1233  case jbvBool:
1234  tmp = scalarVal->val.boolean ? 0x02 : 0x04;
1235 
1236  break;
1237  default:
1238  elog(ERROR, "invalid jsonb scalar type");
1239  tmp = 0; /* keep compiler quiet */
1240  break;
1241  }
1242 
1243  /*
1244  * Combine hash values of successive keys, values and elements by rotating
1245  * the previous value left 1 bit, then XOR'ing in the new
1246  * key/value/element's hash value.
1247  */
1248  *hash = (*hash << 1) | (*hash >> 31);
1249  *hash ^= tmp;
1250 }
#define DatumGetUInt32(X)
Definition: postgres.h:492
Datum hash_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:2158
char * val
Definition: jsonb.h:259
#define NumericGetDatum(X)
Definition: numeric.h:51
Definition: jsonb.h:234
Definition: jsonb.h:231
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:584
#define ERROR
Definition: elog.h:43
unsigned int uint32
Definition: c.h:268
Datum hash_any(register const unsigned char *k, register int keylen)
Definition: hashfunc.c:307
enum jbvType type
Definition: jsonb.h:250
#define elog
Definition: elog.h:219
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:541
JsonbIteratorToken JsonbIteratorNext ( JsonbIterator **  it,
JsonbValue val,
bool  skipNested 
)

Definition at line 754 of file jsonb_util.c.

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, NULL, 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 addJsonbToParseState(), compareJsonbContainers(), datum_to_jsonb(), each_worker_jsonb(), elements_worker_jsonb(), get_jsonb_path_all(), gin_extract_jsonb(), gin_extract_jsonb_path(), iterate_jsonb_string_values(), IteratorConcat(), jsonb_agg_transfn(), jsonb_delete(), jsonb_delete_array(), jsonb_delete_idx(), jsonb_hash(), jsonb_object_agg_transfn(), jsonb_object_keys(), jsonb_strip_nulls(), jsonb_typeof(), JsonbDeepContains(), JsonbToCStringWorker(), populate_array_dim_jsonb(), populate_recordset_worker(), pushJsonbValue(), setPath(), setPathArray(), setPathObject(), and transform_jsonb_string_values().

755 {
756  if (*it == NULL)
757  return WJB_DONE;
758 
759  /*
760  * When stepping into a nested container, we jump back here to start
761  * processing the child. We will not recurse further in one call, because
762  * processing the child will always begin in JBI_ARRAY_START or
763  * JBI_OBJECT_START state.
764  */
765 recurse:
766  switch ((*it)->state)
767  {
768  case JBI_ARRAY_START:
769  /* Set v to array on first array call */
770  val->type = jbvArray;
771  val->val.array.nElems = (*it)->nElems;
772 
773  /*
774  * v->val.array.elems is not actually set, because we aren't doing
775  * a full conversion
776  */
777  val->val.array.rawScalar = (*it)->isScalar;
778  (*it)->curIndex = 0;
779  (*it)->curDataOffset = 0;
780  (*it)->curValueOffset = 0; /* not actually used */
781  /* Set state for next call */
782  (*it)->state = JBI_ARRAY_ELEM;
783  return WJB_BEGIN_ARRAY;
784 
785  case JBI_ARRAY_ELEM:
786  if ((*it)->curIndex >= (*it)->nElems)
787  {
788  /*
789  * All elements within array already processed. Report this
790  * to caller, and give it back original parent iterator (which
791  * independently tracks iteration progress at its level of
792  * nesting).
793  */
794  *it = freeAndGetParent(*it);
795  return WJB_END_ARRAY;
796  }
797 
798  fillJsonbValue((*it)->container, (*it)->curIndex,
799  (*it)->dataProper, (*it)->curDataOffset,
800  val);
801 
802  JBE_ADVANCE_OFFSET((*it)->curDataOffset,
803  (*it)->children[(*it)->curIndex]);
804  (*it)->curIndex++;
805 
806  if (!IsAJsonbScalar(val) && !skipNested)
807  {
808  /* Recurse into container. */
809  *it = iteratorFromContainer(val->val.binary.data, *it);
810  goto recurse;
811  }
812  else
813  {
814  /*
815  * Scalar item in array, or a container and caller didn't want
816  * us to recurse into it.
817  */
818  return WJB_ELEM;
819  }
820 
821  case JBI_OBJECT_START:
822  /* Set v to object on first object call */
823  val->type = jbvObject;
824  val->val.object.nPairs = (*it)->nElems;
825 
826  /*
827  * v->val.object.pairs is not actually set, because we aren't
828  * doing a full conversion
829  */
830  (*it)->curIndex = 0;
831  (*it)->curDataOffset = 0;
832  (*it)->curValueOffset = getJsonbOffset((*it)->container,
833  (*it)->nElems);
834  /* Set state for next call */
835  (*it)->state = JBI_OBJECT_KEY;
836  return WJB_BEGIN_OBJECT;
837 
838  case JBI_OBJECT_KEY:
839  if ((*it)->curIndex >= (*it)->nElems)
840  {
841  /*
842  * All pairs within object already processed. Report this to
843  * caller, and give it back original containing iterator
844  * (which independently tracks iteration progress at its level
845  * of nesting).
846  */
847  *it = freeAndGetParent(*it);
848  return WJB_END_OBJECT;
849  }
850  else
851  {
852  /* Return key of a key/value pair. */
853  fillJsonbValue((*it)->container, (*it)->curIndex,
854  (*it)->dataProper, (*it)->curDataOffset,
855  val);
856  if (val->type != jbvString)
857  elog(ERROR, "unexpected jsonb type as object key");
858 
859  /* Set state for next call */
860  (*it)->state = JBI_OBJECT_VALUE;
861  return WJB_KEY;
862  }
863 
864  case JBI_OBJECT_VALUE:
865  /* Set state for next call */
866  (*it)->state = JBI_OBJECT_KEY;
867 
868  fillJsonbValue((*it)->container, (*it)->curIndex + (*it)->nElems,
869  (*it)->dataProper, (*it)->curValueOffset,
870  val);
871 
872  JBE_ADVANCE_OFFSET((*it)->curDataOffset,
873  (*it)->children[(*it)->curIndex]);
874  JBE_ADVANCE_OFFSET((*it)->curValueOffset,
875  (*it)->children[(*it)->curIndex + (*it)->nElems]);
876  (*it)->curIndex++;
877 
878  /*
879  * Value may be a container, in which case we recurse with new,
880  * child iterator (unless the caller asked not to, by passing
881  * skipNested).
882  */
883  if (!IsAJsonbScalar(val) && !skipNested)
884  {
885  *it = iteratorFromContainer(val->val.binary.data, *it);
886  goto recurse;
887  }
888  else
889  return WJB_VALUE;
890  }
891 
892  elog(ERROR, "invalid iterator state");
893  return -1;
894 }
uint32 getJsonbOffset(const JsonbContainer *jc, int index)
Definition: jsonb_util.c:121
char * val
Definition: jsonb.h:259
Definition: jsonb.h:22
static JsonbIterator * freeAndGetParent(JsonbIterator *it)
Definition: jsonb_util.c:942
#define JBE_ADVANCE_OFFSET(offset, je)
Definition: jsonb.h:165
#define ERROR
Definition: elog.h:43
Definition: jsonb.h:23
static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)
Definition: jsonb_util.c:456
static JsonbIterator * iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent)
Definition: jsonb_util.c:900
#define NULL
Definition: c.h:229
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:283
enum jbvType type
Definition: jsonb.h:250
#define elog
Definition: elog.h:219
Definition: jsonb.h:25
char* JsonbToCString ( StringInfo  out,
JsonbContainer in,
int  estimated_len 
)

Definition at line 428 of file jsonb.c.

References JsonbToCStringWorker().

Referenced by each_worker_jsonb(), elements_worker_jsonb(), get_jsonb_path_all(), jsonb_array_element_text(), jsonb_object_field_text(), jsonb_out(), jsonb_send(), and populate_scalar().

429 {
430  return JsonbToCStringWorker(out, in, estimated_len, false);
431 }
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition: jsonb.c:446
char* JsonbToCStringIndent ( StringInfo  out,
JsonbContainer in,
int  estimated_len 
)

Definition at line 437 of file jsonb.c.

References JsonbToCStringWorker().

Referenced by jsonb_pretty().

438 {
439  return JsonbToCStringWorker(out, in, estimated_len, true);
440 }
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition: jsonb.c:446
Jsonb* JsonbValueToJsonb ( JsonbValue val)

Definition at line 79 of file jsonb_util.c.

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

Referenced by each_worker_jsonb(), elements_worker_jsonb(), get_jsonb_path_all(), hstore_to_jsonb(), hstore_to_jsonb_loose(), jsonb_agg_finalfn(), jsonb_agg_transfn(), jsonb_array_element(), jsonb_build_array(), jsonb_build_array_noargs(), jsonb_build_object(), jsonb_build_object_noargs(), jsonb_concat(), jsonb_delete(), jsonb_delete_array(), jsonb_delete_idx(), jsonb_delete_path(), jsonb_from_cstring(), jsonb_insert(), jsonb_object(), jsonb_object_agg_finalfn(), jsonb_object_agg_transfn(), jsonb_object_field(), jsonb_object_two_arg(), jsonb_set(), jsonb_strip_nulls(), populate_scalar(), to_jsonb(), and transform_jsonb_string_values().

80 {
81  Jsonb *out;
82 
83  if (IsAJsonbScalar(val))
84  {
85  /* Scalar value */
86  JsonbParseState *pstate = NULL;
87  JsonbValue *res;
88  JsonbValue scalarArray;
89 
90  scalarArray.type = jbvArray;
91  scalarArray.val.array.rawScalar = true;
92  scalarArray.val.array.nElems = 1;
93 
94  pushJsonbValue(&pstate, WJB_BEGIN_ARRAY, &scalarArray);
95  pushJsonbValue(&pstate, WJB_ELEM, val);
96  res = pushJsonbValue(&pstate, WJB_END_ARRAY, NULL);
97 
98  out = convertToJsonb(res);
99  }
100  else if (val->type == jbvObject || val->type == jbvArray)
101  {
102  out = convertToJsonb(val);
103  }
104  else
105  {
106  Assert(val->type == jbvBinary);
107  out = palloc(VARHDRSZ + val->val.binary.len);
108  SET_VARSIZE(out, VARHDRSZ + val->val.binary.len);
109  memcpy(VARDATA(out), val->val.binary.data, val->val.binary.len);
110  }
111 
112  return out;
113 }
#define VARDATA(PTR)
Definition: postgres.h:303
Definition: jsonb.h:215
#define VARHDRSZ
Definition: c.h:445
char * val
Definition: jsonb.h:259
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:517
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
static Jsonb * convertToJsonb(JsonbValue *val)
Definition: jsonb_util.c:1403
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:283
enum jbvType type
Definition: jsonb.h:250
void * palloc(Size size)
Definition: mcxt.c:849
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328
Definition: jsonb.h:25
JsonbValue* pushJsonbValue ( JsonbParseState **  pstate,
JsonbIteratorToken  seq,
JsonbValue jbVal 
)

Definition at line 517 of file jsonb_util.c.

References jbvBinary, JsonbIteratorInit(), JsonbIteratorNext(), NULL, pushJsonbValueScalar(), JsonbValue::type, JsonbValue::val, WJB_BEGIN_ARRAY, WJB_DONE, WJB_ELEM, and WJB_VALUE.

Referenced by addJsonbToParseState(), array_dim_to_jsonb(), array_to_jsonb_internal(), composite_to_jsonb(), datum_to_jsonb(), hstore_to_jsonb(), hstore_to_jsonb_loose(), IteratorConcat(), jsonb_agg_finalfn(), jsonb_agg_transfn(), jsonb_build_array(), jsonb_build_array_noargs(), jsonb_build_object(), jsonb_build_object_noargs(), jsonb_delete(), jsonb_delete_array(), jsonb_delete_idx(), jsonb_in_array_end(), jsonb_in_array_start(), jsonb_in_object_end(), jsonb_in_object_field_start(), jsonb_in_object_start(), jsonb_in_scalar(), jsonb_object(), jsonb_object_agg_finalfn(), jsonb_object_agg_transfn(), jsonb_object_two_arg(), jsonb_strip_nulls(), JsonbValueToJsonb(), setPath(), setPathArray(), setPathObject(), and transform_jsonb_string_values().

519 {
520  JsonbIterator *it;
521  JsonbValue *res = NULL;
522  JsonbValue v;
523  JsonbIteratorToken tok;
524 
525  if (!jbval || (seq != WJB_ELEM && seq != WJB_VALUE) ||
526  jbval->type != jbvBinary)
527  {
528  /* drop through */
529  return pushJsonbValueScalar(pstate, seq, jbval);
530  }
531 
532  /* unpack the binary and add each piece to the pstate */
533  it = JsonbIteratorInit(jbval->val.binary.data);
534  while ((tok = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
535  res = pushJsonbValueScalar(pstate, tok,
536  tok < WJB_BEGIN_ARRAY ? &v : NULL);
537 
538  return res;
539 }
Definition: jsonb.h:22
static JsonbValue * pushJsonbValueScalar(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *scalarVal)
Definition: jsonb_util.c:546
JsonbIteratorToken
Definition: jsonb.h:20
#define NULL
Definition: c.h:229
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:718
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:754
Definition: jsonb.h:25