PostgreSQL Source Code: src/include/utils/jsonb.h File Reference (original) (raw)

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_) |
#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 Jsonb * DatumGetJsonbP (Datum d)
static Jsonb * DatumGetJsonbPCopy (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)
JsonbValue * findJsonbValueFromContainer (JsonbContainer *container, uint32 flags, JsonbValue *key)
JsonbValue * getKeyJsonValueFromContainer (JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)
JsonbValue * getIthJsonbValueFromContainer (JsonbContainer *container, uint32 i)
JsonbValue * pushJsonbValue (JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
JsonbIterator * JsonbIteratorInit (JsonbContainer *container)
JsonbIteratorToken JsonbIteratorNext (JsonbIterator **it, JsonbValue *val, bool skipNested)
void JsonbToJsonbValue (Jsonb *jsonb, JsonbValue *val)
Jsonb * JsonbValueToJsonb (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)

IsAJsonbScalar

| #define IsAJsonbScalar | ( | | jsonbval | ) | | ---------------------- | - | | -------- | - |

JB_CMASK

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

JB_FARRAY

#define JB_FARRAY 0x40000000

JB_FOBJECT

#define JB_FOBJECT 0x20000000

JB_FSCALAR

#define JB_FSCALAR 0x10000000 /* flag bits */

JB_OFFSET_STRIDE

#define JB_OFFSET_STRIDE 32

JB_ROOT_COUNT

JB_ROOT_IS_ARRAY

JB_ROOT_IS_OBJECT

JB_ROOT_IS_SCALAR

JBE_ADVANCE_OFFSET

| #define JBE_ADVANCE_OFFSET | ( | | offset, | | ---------------------------- | - | | ------- | | | je | | | | | ) | | | |

Value:

do { \

JEntry je_ = (je); \

else \

} while(0)

#define JBE_OFFLENFLD(je_)

Definition at line 162 of file jsonb.h.

JBE_HAS_OFF

JBE_ISBOOL

JBE_ISBOOL_FALSE

JBE_ISBOOL_TRUE

JBE_ISCONTAINER

JBE_ISNULL

JBE_ISNUMERIC

JBE_ISSTRING

JBE_OFFLENFLD

JENTRY_HAS_OFF

#define JENTRY_HAS_OFF 0x80000000

JENTRY_ISBOOL_FALSE

#define JENTRY_ISBOOL_FALSE 0x20000000

JENTRY_ISBOOL_TRUE

#define JENTRY_ISBOOL_TRUE 0x30000000

JENTRY_ISCONTAINER

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

JENTRY_ISNULL

#define JENTRY_ISNULL 0x40000000

JENTRY_ISNUMERIC

#define JENTRY_ISNUMERIC 0x10000000

JENTRY_ISSTRING

#define JENTRY_ISSTRING 0x00000000

JENTRY_OFFLENMASK

#define JENTRY_OFFLENMASK 0x0FFFFFFF

JENTRY_TYPEMASK

#define JENTRY_TYPEMASK 0x70000000

JGIN_MAXLENGTH

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

JGINFLAG_NULL

#define JGINFLAG_NULL 0x02 /* null value */

Definition at line 63 of file jsonb.h.

JGINFLAG_NUM

JGINFLAG_STR

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

JsonContainerIsObject

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

JsonContainerIsScalar

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

JsonContainerSize

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

PG_GETARG_JSONB_P

PG_GETARG_JSONB_P_COPY

PG_RETURN_JSONB_P

JEntry

JsonbContainer

JsonbIterator

JsonbPair

JsonbParseState

JsonbValue

jbvType

Enumerator
jbvNull
jbvString
jbvNumeric
jbvBool
jbvArray
jbvObject
jbvBinary
jbvDatetime

Definition at line 225 of file jsonb.h.

226{

227

232

235

237

238

239

240

241

242

243

245};

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.

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.

compareJsonbContainers()

Definition at line 191 of file jsonb_util.c.

192{

194 *itb;

195 int res = 0;

196

199

200 do

201 {

203 vb;

205 rb;

206

209

210 if (ra == rb)

211 {

213 {

214

215 break;

216 }

217

219 {

220

221

222

223

224

225

226 continue;

227 }

228

230 {

231 switch (va.type)

232 {

238 break;

240

241

242

243

244

245

246

247 if (va.val.array.rawScalar != vb.val.array.rawScalar)

248 res = (va.val.array.rawScalar) ? -1 : 1;

249

250

251

252

253

254

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;

260 if (va.val.object.nPairs != vb.val.object.nPairs)

261 res = (va.val.object.nPairs > vb.val.object.nPairs) ? 1 : -1;

262 break;

264 elog(ERROR, "unexpected jbvBinary value");

265 break;

267 elog(ERROR, "unexpected jbvDatetime value");

268 break;

269 }

270 }

271 else

272 {

273

274 res = (va.type > vb.type) ? 1 : -1;

275 }

276 }

277 else

278 {

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

296

300

301 res = (va.type > vb.type) ? 1 : -1;

302 }

303 }

304 while (res == 0);

305

306 while (ita != NULL)

307 {

309

311 ita = i;

312 }

313 while (itb != NULL)

314 {

316

318 itb = i;

319 }

320

321 return res;

322}

Assert(PointerIsAligned(start, uint64))

JsonbIterator * JsonbIteratorInit(JsonbContainer *container)

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

static int compareJsonbScalarValue(JsonbValue *a, JsonbValue *b)

void pfree(void *pointer)

struct JsonbIterator * parent

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

static Jsonb * DatumGetJsonbP ( Datum d) inlinestatic

Definition at line 374 of file jsonb.h.

375{

377}

#define PG_DETOAST_DATUM(datum)

References PG_DETOAST_DATUM.

Referenced by datum_to_jsonb_internal(), ExecEvalJsonIsPredicate(), json_populate_type(), jsonb_subscript_assign(), jsonb_subscript_fetch(), jsonb_subscript_fetch_old(), JsonItemFromDatum(), JsonPathExists(), JsonPathQuery(), JsonPathValue(), and JsonTableResetRowPattern().

DatumGetJsonbPCopy()

static Jsonb * DatumGetJsonbPCopy ( Datum d) inlinestatic

findJsonbValueFromContainer()

Definition at line 351 of file jsonb_util.c.

353{

356

358

359

360 if (count <= 0)

361 return NULL;

362

364 {

366 char *base_addr = (char *) (children + count);

368 int i;

369

370 for (i = 0; i < count; i++)

371 {

373

374 if (key->type == result->type)

375 {

377 return result;

378 }

379

381 }

382

384 }

386 {

387

389

391 key->val.string.len, NULL);

392 }

393

394

395 return NULL;

396}

#define JsonContainerIsArray(jc)

#define JsonContainerSize(jc)

#define JsonContainerIsObject(jc)

#define JBE_ADVANCE_OFFSET(offset, je)

static void fillJsonbValue(JsonbContainer *container, int index, char *base_addr, uint32 offset, JsonbValue *result)

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

static bool equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b)

JEntry children[FLEXIBLE_ARRAY_MEMBER]

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

Definition at line 475 of file jsonb_util.c.

476{

478 char *base_addr;

480

482 elog(ERROR, "not a jsonb array");

483

485 base_addr = (char *) &container->children[nelements];

486

487 if (i >= nelements)

488 return NULL;

489

491

494 result);

495

496 return result;

497}

if(TABLE==NULL||TABLE_index==NULL)

uint32 getJsonbOffset(const JsonbContainer *jc, int index)

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

getJsonbOffset()

getKeyJsonValueFromContainer()

Definition at line 405 of file jsonb_util.c.

407{

410 char *baseAddr;

412 stopHigh;

413

415

416

417 if (count <= 0)

418 return NULL;

419

420

421

422

423

424 baseAddr = (char *) (children + count * 2);

425 stopLow = 0;

426 stopHigh = count;

427 while (stopLow < stopHigh)

428 {

431 const char *candidateVal;

432 int candidateLen;

433

434 stopMiddle = stopLow + (stopHigh - stopLow) / 2;

435

436 candidateVal = baseAddr + getJsonbOffset(container, stopMiddle);

437 candidateLen = getJsonbLength(container, stopMiddle);

438

440 keyVal, keyLen);

441

443 {

444

445 int index = stopMiddle + count;

446

447 if (!res)

449

452 res);

453

454 return res;

455 }

456 else

457 {

459 stopLow = stopMiddle + 1;

460 else

461 stopHigh = stopMiddle;

462 }

463 }

464

465

466 return NULL;

467}

Datum difference(PG_FUNCTION_ARGS)

static int lengthCompareJsonbString(const char *val1, int len1, const char *val2, int len2)

uint32 getJsonbLength(const JsonbContainer *jc, int index)

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;

1215

1217

1219

1220 for (i = 0; i < nargs; i++)

1221 {

1222 if (absent_on_null && nulls[i])

1223 continue;

1224

1226 }

1227

1229

1231}

static void add_jsonb(Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)

static Datum JsonbPGetDatum(const Jsonb *p)

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

Jsonb * JsonbValueToJsonb(JsonbValue *val)

JsonbParseState * parseState

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;

1130

1131 if (nargs % 2 != 0)

1133 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1134 errmsg("argument list must have even number of elements"),

1135

1136 errhint("The arguments of %s must consist of alternating keys and values.",

1137 "jsonb_build_object()")));

1138

1140

1144

1145 for (i = 0; i < nargs; i += 2)

1146 {

1147

1149

1150 if (nulls[i])

1152 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1153 errmsg("argument %d: key must not be null", i + 1)));

1154

1155

1156 skip = absent_on_null && nulls[i + 1];

1157

1158

1159 if (skip && !unique_keys)

1160 continue;

1161

1163

1164

1166 }

1167

1169

1171}

int errhint(const char *fmt,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

static const struct exclude_list_item skip[]

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{

1535 int i;

1536 bool have_object = false,

1537 have_array = false;

1538

1539 *isnull = false;

1540

1541

1543 have_object = true;

1545 have_array = true;

1546 else

1547 {

1549

1550 if (npath <= 0)

1552 }

1553

1554

1555

1556

1557

1558

1559

1560

1561

1562 if (npath <= 0 && jbvp == NULL)

1563 {

1564 if (as_text)

1565 {

1567 container,

1569 }

1570 else

1571 {

1572

1574 }

1575 }

1576

1577 for (i = 0; i < npath; i++)

1578 {

1579 if (have_object)

1580 {

1582

1586 NULL);

1587 }

1588 else if (have_array)

1589 {

1590 int lindex;

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;

1601 }

1602

1603 if (lindex >= 0)

1604 {

1606 }

1607 else

1608 {

1609

1611

1612

1614 elog(ERROR, "not a jsonb array");

1615

1617

1618 if (lindex == INT_MIN || -lindex > nelements)

1619 {

1620 *isnull = true;

1622 }

1623 else

1624 index = nelements + lindex;

1625 }

1626

1628 }

1629 else

1630 {

1631

1632 *isnull = true;

1634 }

1635

1636 if (jbvp == NULL)

1637 {

1638 *isnull = true;

1640 }

1641 else if (i == npath - 1)

1642 break;

1643

1645 {

1646 container = jbvp->val.binary.data;

1650 }

1651 else

1652 {

1654 have_object = false;

1655 have_array = false;

1656 }

1657 }

1658

1659 if (as_text)

1660 {

1662 {

1663 *isnull = true;

1665 }

1666

1668 }

1669 else

1670 {

1672

1673

1675 }

1676}

#define TextDatumGetCString(d)

#define DatumGetTextPP(X)

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

#define JsonContainerIsScalar(jc)

#define JB_ROOT_IS_OBJECT(jbp_)

#define IsAJsonbScalar(jsonbval)

#define PG_RETURN_JSONB_P(x)

#define JB_ROOT_IS_ARRAY(jbp_)

#define JB_ROOT_IS_SCALAR(jbp_)

JsonbValue * getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)

static text * JsonbValueAsText(JsonbValue *v)

static Datum PointerGetDatum(const void *X)

int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)

#define VARSIZE_ANY_EXHDR(PTR)

text * cstring_to_text(const char *s)

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

Definition at line 1679 of file jsonfuncs.c.

1681{

1685 bool *path_nulls = palloc0(path_len * sizeof(bool));

1686

1689

1691

1695

1696 pfree(path_nulls);

1697

1699}

static JsonbValue * setPath(JsonbIterator **it, Datum *path_elems, bool *path_nulls, int path_len, JsonbParseState **st, int level, JsonbValue *newval, int op_type)

#define JB_PATH_CONSISTENT_POSITION

#define JB_PATH_FILL_GAPS

void * palloc0(Size size)

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

Definition at line 1069 of file jsonb_util.c.

1070{

1072 vcontained;

1074 rcont;

1075

1076

1077

1078

1079

1080

1081

1083

1086

1087 if (rval != rcont)

1088 {

1089

1090

1091

1092

1093

1094

1097 return false;

1098 }

1100 {

1103

1104

1105

1106

1107

1108

1109

1110

1111 if (vval.val.object.nPairs < vcontained.val.object.nPairs)

1112 return false;

1113

1114

1115 for (;;)

1116 {

1117 JsonbValue *lhsVal;

1119

1121

1122

1123

1124

1125

1126

1128 return true;

1129

1132

1133

1134 lhsVal =

1136 vcontained.val.string.val,

1137 vcontained.val.string.len,

1138 &lhsValBuf);

1139 if (!lhsVal)

1140 return false;

1141

1142

1143

1144

1145

1147

1149

1150

1151

1152

1153

1154 if (lhsVal->type != vcontained.type)

1155 {

1156 return false;

1157 }

1159 {

1161 return false;

1162 }

1163 else

1164 {

1165

1167 *nestContained;

1168

1171

1174

1175

1176

1177

1178

1179

1180

1181

1182

1183

1184

1185

1186

1187

1188

1189

1190

1191

1192

1193

1194

1196 return false;

1197 }

1198 }

1199 }

1201 {

1203 uint32 nLhsElems = vval.val.array.nElems;

1204

1207

1208

1209

1210

1211

1212

1213

1214

1215

1216

1217

1218 if (vval.val.array.rawScalar && !vcontained.val.array.rawScalar)

1219 return false;

1220

1221

1222 for (;;)

1223 {

1225

1226

1227

1228

1229

1230

1232 return true;

1233

1235

1237 {

1240 &vcontained))

1241 return false;

1242 }

1243 else

1244 {

1246

1247

1248

1249

1250

1251 if (lhsConts == NULL)

1252 {

1254

1255

1257

1258 for (i = 0; i < nLhsElems; i++)

1259 {

1260

1263

1265 lhsConts[j++] = vval;

1266 }

1267

1268

1269 if (j == 0)

1270 return false;

1271

1272

1273 nLhsElems = j;

1274 }

1275

1276

1277 for (i = 0; i < nLhsElems; i++)

1278 {

1279

1281 *nestContained;

1282 bool contains;

1283

1286

1288

1289 if (nestval)

1291 if (nestContained)

1292 pfree(nestContained);

1293 if (contains)

1294 break;

1295 }

1296

1297

1298

1299

1300

1301 if (i == nLhsElems)

1302 return false;

1303 }

1304 }

1305 }

1306 else

1307 {

1308 elog(ERROR, "invalid jsonb container type");

1309 }

1310

1311 elog(ERROR, "unexpectedly fell off end of jsonb container");

1312 return false;

1313}

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

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

void check_stack_depth(void)

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

Definition at line 1968 of file jsonb.c.

1969{

1973

1975 {

1976

1978 return false;

1979 }

1980

1981

1982

1983

1984

1986

1989 Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);

1990

1994

1997

2000

2001 return true;

2002}

#define PG_USED_FOR_ASSERTS_ONLY

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

Definition at line 1323 of file jsonb_util.c.

1324{

1326

1327

1328 switch (scalarVal->type)

1329 {

1331 tmp = 0x01;

1332 break;

1335 scalarVal->val.string.len));

1336 break;

1338

1341 break;

1343 tmp = scalarVal->val.boolean ? 0x02 : 0x04;

1344

1345 break;

1346 default:

1347 elog(ERROR, "invalid jsonb scalar type");

1348 tmp = 0;

1349 break;

1350 }

1351

1352

1353

1354

1355

1356

1358 *hash ^= tmp;

1359}

Datum hash_numeric(PG_FUNCTION_ARGS)

#define DirectFunctionCall1(func, arg1)

static Datum hash_any(const unsigned char *k, int keylen)

static Datum NumericGetDatum(Numeric X)

static uint32 pg_rotate_left32(uint32 word, int n)

static uint32 DatumGetUInt32(Datum X)

static unsigned hash(unsigned *uv, int n)

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

Definition at line 1366 of file jsonb_util.c.

1368{

1370

1371 switch (scalarVal->type)

1372 {

1374 tmp = seed + 0x01;

1375 break;

1378 scalarVal->val.string.len,

1379 seed));

1380 break;

1385 break;

1387 if (seed)

1391 else

1392 tmp = scalarVal->val.boolean ? 0x02 : 0x04;

1393

1394 break;

1395 default:

1396 elog(ERROR, "invalid jsonb scalar type");

1397 break;

1398 }

1399

1401 *hash ^= tmp;

1402}

Datum hash_numeric_extended(PG_FUNCTION_ARGS)

#define DirectFunctionCall2(func, arg1, arg2)

#define ROTATE_HIGH_AND_LOW_32BITS(v)

static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)

Datum hashcharextended(PG_FUNCTION_ARGS)

static uint64 DatumGetUInt64(Datum X)

static Datum UInt64GetDatum(uint64 X)

static Datum BoolGetDatum(bool X)

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

Definition at line 824 of file jsonb_util.c.

825{

827}

static JsonbIterator * iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent)

References iteratorFromContainer().

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(), jsonb_agg_transfn_worker(), jsonb_concat(), jsonb_contained(), jsonb_contains(), jsonb_delete(), jsonb_delete_array(), jsonb_delete_idx(), jsonb_delete_path(), jsonb_hash(), jsonb_hash_extended(), jsonb_insert(), jsonb_object_agg_transfn_worker(), jsonb_object_keys(), jsonb_set(), jsonb_set_element(), jsonb_strip_nulls(), Jsonb_to_SV(), JsonbDeepContains(), JsonbExtractScalar(), JsonbToCStringWorker(), parse_jsonb_index_flags(), PLyObject_FromJsonbContainer(), populate_array_dim_jsonb(), populate_recordset_worker(), pushJsonbValue(), and transform_jsonb_string_values().

JsonbIteratorNext()

Definition at line 860 of file jsonb_util.c.

861{

862 if (*it == NULL)

864

865

866

867

868

869

870

871recurse:

872 switch ((*it)->state)

873 {

875

877 val->val.array.nElems = (*it)->nElems;

878

879

880

881

882

883 val->val.array.rawScalar = (*it)->isScalar;

884 (*it)->curIndex = 0;

885 (*it)->curDataOffset = 0;

886 (*it)->curValueOffset = 0;

887

890

892 if ((*it)->curIndex >= (*it)->nElems)

893 {

894

895

896

897

898

899

902 }

903

905 (*it)->dataProper, (*it)->curDataOffset,

907

909 (*it)->children[(*it)->curIndex]);

910 (*it)->curIndex++;

911

913 {

914

916 goto recurse;

917 }

918 else

919 {

920

921

922

923

925 }

926

928

930 val->val.object.nPairs = (*it)->nElems;

931

932

933

934

935

936 (*it)->curIndex = 0;

937 (*it)->curDataOffset = 0;

938 (*it)->curValueOffset = getJsonbOffset((*it)->container,

939 (*it)->nElems);

940

943

945 if ((*it)->curIndex >= (*it)->nElems)

946 {

947

948

949

950

951

952

955 }

956 else

957 {

958

960 (*it)->dataProper, (*it)->curDataOffset,

963 elog(ERROR, "unexpected jsonb type as object key");

964

965

968 }

969

971

973

974 fillJsonbValue((*it)->container, (*it)->curIndex + (*it)->nElems,

975 (*it)->dataProper, (*it)->curValueOffset,

977

979 (*it)->children[(*it)->curIndex]);

981 (*it)->children[(*it)->curIndex + (*it)->nElems]);

982 (*it)->curIndex++;

983

984

985

986

987

988

990 {

992 goto recurse;

993 }

994 else

996 }

997

998 elog(ERROR, "invalid iterator state");

999 return -1;

1000}

static JsonbIterator * freeAndGetParent(JsonbIterator *it)

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

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

static Datum JsonbPGetDatum ( const Jsonb * p) inlinestatic

JsonbToCString()

JsonbToCStringIndent()

JsonbToJsonbValue()

JsonbTypeName()

Definition at line 180 of file jsonb.c.

181{

182 switch (val->type)

183 {

187 return "object";

189 return "array";

191 return "number";

193 return "string";

195 return "boolean";

197 return "null";

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)

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{

2232 {

2234

2236

2238 return pnstrdup(v.val.string.val, v.val.string.len);

2240 return pstrdup(v.val.boolean ? "true" : "false");

2246 else

2247 {

2248 elog(ERROR, "unrecognized jsonb value type %d", v.type);

2249 return NULL;

2250 }

2251 }

2252 else

2254}

Datum numeric_out(PG_FUNCTION_ARGS)

bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)

char * pstrdup(const char *in)

char * pnstrdup(const char *in, Size len)

static char * DatumGetCString(Datum X)

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

Definition at line 92 of file jsonb_util.c.

93{

95

97 {

98

102

104 scalarArray.val.array.rawScalar = true;

105 scalarArray.val.array.nElems = 1;

106

110

112 }

114 {

116 }

117 else

118 {

122 memcpy(VARDATA(out), val->val.binary.data, val->val.binary.len);

123 }

124

125 return out;

126}

static Jsonb * convertToJsonb(JsonbValue *val)

#define SET_VARSIZE(PTR, len)

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

Definition at line 573 of file jsonb_util.c.

575{

580 int i;

581

583 {

585 for (i = 0; i < jbval->val.object.nPairs; i++)

586 {

589 }

590

592 }

593

595 {

597 for (i = 0; i < jbval->val.array.nElems; i++)

598 {

600 }

601

603 }

604

607 {

608

610 }

611

612

614

615 if ((jbval->val.binary.data->header & JB_FSCALAR) && *pstate)

616 {

620

623

625

629

630 return res;

631 }

632

637 v.val.array.rawScalar) ? &v : NULL);

638

639 return res;

640}

static JsonbValue * pushJsonbValueScalar(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *scalarVal)

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{

1052 Oid outfuncoid;

1053

1055

1056 switch (tcategory)

1057 {

1062 return true;

1063

1067 return false;

1068

1070 return false;

1071

1073 return false;

1074

1078 return func_volatile(outfuncoid) == PROVOLATILE_IMMUTABLE;

1079 }

1080

1081 return false;

1082}

void json_categorize_type(Oid typoid, bool is_jsonb, JsonTypeCategory *tcategory, Oid *outfuncoid)

char func_volatile(Oid funcid)

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