PostgreSQL Source Code: src/backend/utils/adt/json.c File Reference (original) (raw)

Go to the source code of this file.

Data Structures
struct JsonUniqueHashEntry
struct JsonUniqueStackEntry
struct JsonUniqueParsingState
struct JsonUniqueBuilderState
struct JsonAggState
Typedefs
typedef struct HTAB * JsonUniqueCheckState
typedef struct JsonUniqueHashEntry JsonUniqueHashEntry
typedef struct JsonUniqueStackEntry JsonUniqueStackEntry
typedef struct JsonUniqueParsingState JsonUniqueParsingState
typedef struct JsonUniqueBuilderState JsonUniqueBuilderState
typedef struct JsonAggState JsonAggState
Functions
static void composite_to_json (Datum composite, StringInfo result, bool use_line_feeds)
static void array_dim_to_json (StringInfo result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid, bool use_line_feeds)
static void array_to_json_internal (Datum array, StringInfo result, bool use_line_feeds)
static void datum_to_json_internal (Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
static void add_json (Datum val, bool is_null, StringInfo result, Oid val_type, bool key_scalar)
static text * catenate_stringinfo_string (StringInfo buffer, const char *addon)
Datum json_in (PG_FUNCTION_ARGS)
Datum json_out (PG_FUNCTION_ARGS)
Datum json_send (PG_FUNCTION_ARGS)
Datum json_recv (PG_FUNCTION_ARGS)
char * JsonEncodeDateTime (char *buf, Datum value, Oid typid, const int *tzp)
Datum array_to_json (PG_FUNCTION_ARGS)
Datum array_to_json_pretty (PG_FUNCTION_ARGS)
Datum row_to_json (PG_FUNCTION_ARGS)
Datum row_to_json_pretty (PG_FUNCTION_ARGS)
bool to_json_is_immutable (Oid typoid)
Datum to_json (PG_FUNCTION_ARGS)
Datum datum_to_json (Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
static Datum json_agg_transfn_worker (FunctionCallInfo fcinfo, bool absent_on_null)
Datum json_agg_transfn (PG_FUNCTION_ARGS)
Datum json_agg_strict_transfn (PG_FUNCTION_ARGS)
Datum json_agg_finalfn (PG_FUNCTION_ARGS)
static uint32 json_unique_hash (const void *key, Size keysize)
static int json_unique_hash_match (const void *key1, const void *key2, Size keysize)
static void json_unique_check_init (JsonUniqueCheckState *cxt)
static void json_unique_builder_init (JsonUniqueBuilderState *cxt)
static bool json_unique_check_key (JsonUniqueCheckState *cxt, const char *key, int object_id)
static StringInfo json_unique_builder_get_throwawaybuf (JsonUniqueBuilderState *cxt)
static Datum json_object_agg_transfn_worker (FunctionCallInfo fcinfo, bool absent_on_null, bool unique_keys)
Datum json_object_agg_transfn (PG_FUNCTION_ARGS)
Datum json_object_agg_strict_transfn (PG_FUNCTION_ARGS)
Datum json_object_agg_unique_transfn (PG_FUNCTION_ARGS)
Datum json_object_agg_unique_strict_transfn (PG_FUNCTION_ARGS)
Datum json_object_agg_finalfn (PG_FUNCTION_ARGS)
Datum json_build_object_worker (int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null, bool unique_keys)
Datum json_build_object (PG_FUNCTION_ARGS)
Datum json_build_object_noargs (PG_FUNCTION_ARGS)
Datum json_build_array_worker (int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
Datum json_build_array (PG_FUNCTION_ARGS)
Datum json_build_array_noargs (PG_FUNCTION_ARGS)
Datum json_object (PG_FUNCTION_ARGS)
Datum json_object_two_arg (PG_FUNCTION_ARGS)
static pg_attribute_always_inline void escape_json_char (StringInfo buf, char c)
void escape_json (StringInfo buf, const char *str)
void escape_json_with_len (StringInfo buf, const char *str, int len)
void escape_json_text (StringInfo buf, const text *txt)
static JsonParseErrorType json_unique_object_start (void *_state)
static JsonParseErrorType json_unique_object_end (void *_state)
static JsonParseErrorType json_unique_object_field_start (void *_state, char *field, bool isnull)
bool json_validate (text *json, bool check_unique_keys, bool throw_error)
Datum json_typeof (PG_FUNCTION_ARGS)

ESCAPE_JSON_FLUSH_AFTER

#define ESCAPE_JSON_FLUSH_AFTER 512

JsonAggState

JsonUniqueBuilderState

JsonUniqueCheckState

JsonUniqueHashEntry

JsonUniqueParsingState

JsonUniqueStackEntry

add_json()

static void add_json ( Datum val, bool is_null, StringInfo result, Oid val_type, bool key_scalar ) static

Definition at line 602 of file json.c.

604{

606 Oid outfuncoid;

607

610 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

611 errmsg("could not determine input data type")));

612

613 if (is_null)

614 {

617 }

618 else

620 &tcategory, &outfuncoid);

621

623 key_scalar);

624}

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

static void datum_to_json_internal(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)

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

References datum_to_json_internal(), ereport, errcode(), errmsg(), ERROR, InvalidOid, json_categorize_type(), JSONTYPE_NULL, and val.

Referenced by json_build_array_worker(), and json_build_object_worker().

array_dim_to_json()

static void array_dim_to_json ( StringInfo result, int dim, int ndims, int * dims, Datum * vals, bool * nulls, int * valcount, JsonTypeCategory tcategory, Oid outfuncoid, bool use_line_feeds ) static

Definition at line 431 of file json.c.

434{

435 int i;

436 const char *sep;

437

439

440 sep = use_line_feeds ? ",\n " : ",";

441

443

444 for (i = 1; i <= dims[dim]; i++)

445 {

446 if (i > 1)

448

449 if (dim + 1 == ndims)

450 {

452 result, tcategory,

453 outfuncoid, false);

454 (*valcount)++;

455 }

456 else

457 {

458

459

460

461

463 valcount, tcategory, outfuncoid, false);

464 }

465 }

466

468}

Assert(PointerIsAligned(start, uint64))

static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid, bool use_line_feeds)

void appendStringInfoString(StringInfo str, const char *s)

void appendStringInfoChar(StringInfo str, char ch)

References appendStringInfoChar(), appendStringInfoString(), array_dim_to_json(), Assert(), datum_to_json_internal(), and i.

Referenced by array_dim_to_json(), and array_to_json_internal().

array_to_json()

array_to_json_internal()

static void array_to_json_internal ( Datum array, StringInfo result, bool use_line_feeds ) static

Definition at line 474 of file json.c.

475{

478 int *dim;

479 int ndim;

481 int count = 0;

483 bool *nulls;

485 bool typbyval;

488 Oid outfuncoid;

489

493

495 {

497 return;

498 }

499

501 &typlen, &typbyval, &typalign);

502

504 &tcategory, &outfuncoid);

505

509

510 array_dim_to_json(result, 0, ndim, dim, elements, nulls, &count, tcategory,

511 outfuncoid, use_line_feeds);

512

515}

#define DatumGetArrayTypeP(X)

void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)

int ArrayGetNItems(int ndim, const int *dims)

void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)

void pfree(void *pointer)

References appendStringInfoString(), ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, array_dim_to_json(), ArrayGetNItems(), DatumGetArrayTypeP, deconstruct_array(), get_typlenbyvalalign(), json_categorize_type(), nitems, pfree(), and typalign.

Referenced by array_to_json(), array_to_json_pretty(), and datum_to_json_internal().

array_to_json_pretty()

catenate_stringinfo_string()

static text * catenate_stringinfo_string ( StringInfo buffer, const char * addon ) static

Definition at line 1209 of file json.c.

1210{

1211

1212 int buflen = buffer->len;

1213 int addlen = strlen(addon);

1215

1217 memcpy(VARDATA(result), buffer->data, buflen);

1218 memcpy(VARDATA(result) + buflen, addon, addlen);

1219

1220 return result;

1221}

#define SET_VARSIZE(PTR, len)

References StringInfoData::data, StringInfoData::len, palloc(), SET_VARSIZE, VARDATA, and VARHDRSZ.

Referenced by json_agg_finalfn(), and json_object_agg_finalfn().

composite_to_json()

static void composite_to_json ( Datum composite, StringInfo result, bool use_line_feeds ) static

Definition at line 521 of file json.c.

522{

524 Oid tupType;

528 *tuple;

529 int i;

530 bool needsep = false;

531 const char *sep;

532 int seplen;

533

534

535

536

537

538 sep = use_line_feeds ? ",\n " : ",";

539 seplen = use_line_feeds ? strlen(",\n ") : strlen(",");

540

542

543

547

548

551 tuple = &tmptup;

552

554

555 for (i = 0; i < tupdesc->natts; i++)

556 {

558 bool isnull;

561 Oid outfuncoid;

563

564 if (att->attisdropped)

565 continue;

566

567 if (needsep)

569 needsep = true;

570

574

576

577 if (isnull)

578 {

581 }

582 else

584 &outfuncoid);

585

587 false);

588 }

589

592}

#define DatumGetHeapTupleHeader(X)

static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)

static int32 HeapTupleHeaderGetTypMod(const HeapTupleHeaderData *tup)

static uint32 HeapTupleHeaderGetDatumLength(const HeapTupleHeaderData *tup)

static Oid HeapTupleHeaderGetTypeId(const HeapTupleHeaderData *tup)

void escape_json(StringInfo buf, const char *str)

FormData_pg_attribute * Form_pg_attribute

void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)

#define ReleaseTupleDesc(tupdesc)

static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)

TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)

References appendBinaryStringInfo(), appendStringInfoChar(), attname, datum_to_json_internal(), DatumGetHeapTupleHeader, escape_json(), heap_getattr(), HeapTupleHeaderGetDatumLength(), HeapTupleHeaderGetTypeId(), HeapTupleHeaderGetTypMod(), i, InvalidOid, json_categorize_type(), JSONTYPE_NULL, lookup_rowtype_tupdesc(), NameStr, TupleDescData::natts, ReleaseTupleDesc, HeapTupleData::t_data, HeapTupleData::t_len, TupleDescAttr(), and val.

Referenced by datum_to_json_internal(), row_to_json(), and row_to_json_pretty().

datum_to_json()

datum_to_json_internal()

Definition at line 179 of file json.c.

182{

183 char *outputstr;

184 text *jsontext;

185

187

188

189 Assert(!(key_scalar && is_null));

190

191 if (is_null)

192 {

194 return;

195 }

196

197 if (key_scalar &&

203 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

204 errmsg("key value must be scalar, not array, composite, or json")));

205

206 switch (tcategory)

207 {

210 break;

213 break;

215 if (key_scalar)

219 else

221 if (key_scalar)

223 break;

226

227

228

229

230

231

232

233 if (!key_scalar &&

234 ((*outputstr >= '0' && *outputstr <= '9') ||

235 (*outputstr == '-' &&

236 (outputstr[1] >= '0' && outputstr[1] <= '9'))))

238 else

239 {

243 }

244 pfree(outputstr);

245 break;

247 {

249

254 }

255 break;

257 {

259

264 }

265 break;

267 {

269

274 }

275 break;

277

280 pfree(outputstr);

281 break;

283

288 break;

289 default:

290

291 if (outfuncoid == F_TEXTOUT || outfuncoid == F_VARCHAROUT ||

292 outfuncoid == F_BPCHAROUT)

294 else

295 {

298 pfree(outputstr);

299 }

300 break;

301 }

302}

char * OidOutputFunctionCall(Oid functionId, Datum val)

#define OidFunctionCall1(functionId, arg1)

#define DatumGetTextPP(X)

void escape_json_text(StringInfo buf, const text *txt)

char * JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp)

static void composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)

static bool DatumGetBool(Datum X)

static Pointer DatumGetPointer(Datum X)

void check_stack_depth(void)

#define VARSIZE_ANY_EXHDR(PTR)

References appendBinaryStringInfo(), appendStringInfoChar(), appendStringInfoString(), array_to_json_internal(), Assert(), buf, check_stack_depth(), composite_to_json(), DatumGetBool(), DatumGetPointer(), DatumGetTextPP, ereport, errcode(), errmsg(), ERROR, escape_json(), escape_json_text(), JsonEncodeDateTime(), JSONTYPE_ARRAY, JSONTYPE_BOOL, JSONTYPE_CAST, JSONTYPE_COMPOSITE, JSONTYPE_DATE, JSONTYPE_JSON, JSONTYPE_NUMERIC, JSONTYPE_TIMESTAMP, JSONTYPE_TIMESTAMPTZ, MAXDATELEN, OidFunctionCall1, OidOutputFunctionCall(), pfree(), val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by add_json(), array_dim_to_json(), composite_to_json(), datum_to_json(), json_agg_transfn_worker(), and json_object_agg_transfn_worker().

escape_json()

static void escape_json ( StringInfo buf,
const char * str
)

Definition at line 1602 of file json.c.

1603{

1605

1606 for (; *str != '\0'; str++)

1608

1610}

static pg_attribute_always_inline void escape_json_char(StringInfo buf, char c)

#define appendStringInfoCharMacro(str, ch)

References appendStringInfoCharMacro, buf, escape_json_char(), and str.

Referenced by appendJSONKeyValue(), composite_to_json(), datum_to_json_internal(), escape_yaml(), ExplainDummyGroup(), ExplainOpenGroup(), ExplainProperty(), ExplainPropertyList(), ExplainPropertyListNested(), generate_error_response(), populate_scalar(), sn_object_field_start(), sn_scalar(), transform_string_values_object_field_start(), transformJsonTableColumn(), and write_jsonlog().

escape_json_char()

escape_json_text()

Definition at line 1736 of file json.c.

1737{

1738

1741 char *str;

1742

1744

1746

1747

1748 if (tunpacked != txt)

1749 pfree(tunpacked);

1750}

#define unconstify(underlying_type, expr)

struct varlena * pg_detoast_datum_packed(struct varlena *datum)

void escape_json_with_len(StringInfo buf, const char *str, int len)

References buf, escape_json_with_len(), len, pfree(), pg_detoast_datum_packed(), str, unconstify, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by datum_to_json_internal(), json_object(), json_object_two_arg(), and transform_string_values_scalar().

escape_json_with_len()

void escape_json_with_len ( StringInfo buf,
const char * str,
int len
)

Definition at line 1631 of file json.c.

1632{

1633 int vlen;

1634

1636

1637

1638

1639

1640

1641

1643

1644

1645

1646

1647

1648 vlen = len & (int) (~(sizeof(Vector8) - 1));

1649

1651

1652 for (int i = 0, copypos = 0;;)

1653 {

1654

1655

1656

1657

1658

1659

1660

1661

1662

1663

1664 for (; i < vlen; i += sizeof(Vector8))

1665 {

1667

1669

1670

1671

1672

1673

1675 vector8_has(chunk, (unsigned char) '"') ||

1676 vector8_has(chunk, (unsigned char) '\\'))

1677 break;

1678

1679#ifdef ESCAPE_JSON_FLUSH_AFTER

1680

1681

1682

1683

1684

1685

1687 {

1689 copypos = i;

1690 }

1691#endif

1692 }

1693

1694

1695

1696

1697

1698

1699 if (copypos < i)

1700 {

1702 copypos = i;

1703 }

1704

1705

1706

1707

1708

1709 for (int b = 0; b < sizeof(Vector8); b++)

1710 {

1711

1712 if (i == len)

1713 goto done;

1714

1716

1718 }

1719

1720 copypos = i;

1721

1722 }

1723

1724done:

1726}

#define ESCAPE_JSON_FLUSH_AFTER

static bool vector8_has_le(const Vector8 v, const uint8 c)

static void vector8_load(Vector8 *v, const uint8 *s)

static bool vector8_has(const Vector8 v, const uint8 c)

void enlargeStringInfo(StringInfo str, int needed)

References appendBinaryStringInfo(), appendStringInfoCharMacro, Assert(), b, buf, enlargeStringInfo(), escape_json_char(), ESCAPE_JSON_FLUSH_AFTER, i, len, str, vector8_has(), vector8_has_le(), and vector8_load().

Referenced by AddFileToBackupManifest(), escape_json_text(), hstore_to_json(), hstore_to_json_loose(), jsonb_put_escaped_value(), populate_scalar(), and printJsonPathItem().

json_agg_finalfn()

json_agg_strict_transfn()

json_agg_transfn()

json_agg_transfn_worker()

Definition at line 779 of file json.c.

780{

782 oldcontext;

785

787 {

788

789 elog(ERROR, "json_agg_transfn called in non-aggregate context");

790 }

791

793 {

795

798 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

799 errmsg("could not determine input data type")));

800

801

802

803

804

805

806

811

814 &state->val_output_func);

815 }

816 else

817 {

819 }

820

823

824 if (state->str->len > 1)

826

827

829 {

833 }

834

836

837

841 {

843 }

844

846 state->val_output_func, false);

847

848

849

850

851

852

854}

Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)

#define PG_RETURN_POINTER(x)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

References AggCheckCallContext(), appendStringInfoChar(), appendStringInfoString(), datum_to_json_internal(), elog, ereport, errcode(), errmsg(), ERROR, FunctionCallInfoBaseData::flinfo, get_fn_expr_argtype(), InvalidOid, json_categorize_type(), JSONTYPE_ARRAY, JSONTYPE_COMPOSITE, JSONTYPE_NULL, makeStringInfo(), MemoryContextSwitchTo(), palloc(), PG_ARGISNULL, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_RETURN_POINTER, and val.

Referenced by json_agg_strict_transfn(), and json_agg_transfn().

json_build_array()

Definition at line 1374 of file json.c.

1375{

1377 bool *nulls;

1379

1380

1383

1384 if (nargs < 0)

1386

1388}

#define PG_RETURN_DATUM(x)

int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)

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

References generate_unaccent_rules::args, extract_variadic_args(), json_build_array_worker(), PG_RETURN_DATUM, PG_RETURN_NULL, and types.

json_build_array_noargs()

json_build_array_worker()

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

Definition at line 1344 of file json.c.

1346{

1347 int i;

1348 const char *sep = "";

1350

1352

1354

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

1356 {

1357 if (absent_on_null && nulls[i])

1358 continue;

1359

1361 sep = ", ";

1363 }

1364

1366

1368}

static void add_json(Datum val, bool is_null, StringInfo result, Oid val_type, bool key_scalar)

References add_json(), appendStringInfoChar(), appendStringInfoString(), generate_unaccent_rules::args, cstring_to_text_with_len(), StringInfoData::data, i, StringInfoData::len, makeStringInfo(), PointerGetDatum(), and types.

Referenced by ExecEvalJsonConstructor(), and json_build_array().

json_build_object()

Definition at line 1318 of file json.c.

1319{

1321 bool *nulls;

1323

1324

1327

1328 if (nargs < 0)

1330

1332}

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

References generate_unaccent_rules::args, extract_variadic_args(), json_build_object_worker(), PG_RETURN_DATUM, PG_RETURN_NULL, and types.

json_build_object_noargs()

json_build_object_worker()

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

Definition at line 1224 of file json.c.

1226{

1227 int i;

1228 const char *sep = "";

1231

1232 if (nargs % 2 != 0)

1234 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

1236

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

1238 "json_build_object()")));

1239

1241

1243

1244 if (unique_keys)

1246

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

1248 {

1251 int key_offset;

1252

1253

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

1255

1257 {

1258

1259 if (!unique_keys)

1260 continue;

1261

1263 }

1264 else

1265 {

1267 sep = ", ";

1268 out = result;

1269 }

1270

1271

1272 if (nulls[i])

1274 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

1275 errmsg("null value not allowed for object key")));

1276

1277

1278 key_offset = out->len;

1279

1281

1282 if (unique_keys)

1283 {

1284

1285

1286

1287

1288

1289

1290

1291

1293

1296 errcode(ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE),

1297 errmsg("duplicate JSON object key value: %s", key));

1298

1300 continue;

1301 }

1302

1304

1305

1307 }

1308

1310

1312}

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

static StringInfo json_unique_builder_get_throwawaybuf(JsonUniqueBuilderState *cxt)

static bool json_unique_check_key(JsonUniqueCheckState *cxt, const char *key, int object_id)

static void json_unique_builder_init(JsonUniqueBuilderState *cxt)

char * pstrdup(const char *in)

static const struct exclude_list_item skip[]

JsonUniqueCheckState check

References add_json(), appendStringInfoChar(), appendStringInfoString(), generate_unaccent_rules::args, JsonUniqueBuilderState::check, cstring_to_text_with_len(), StringInfoData::data, ereport, errcode(), errhint(), errmsg(), ERROR, i, json_unique_builder_get_throwawaybuf(), json_unique_builder_init(), json_unique_check_key(), sort-test::key, StringInfoData::len, makeStringInfo(), PointerGetDatum(), pstrdup(), skip, and types.

Referenced by ExecEvalJsonConstructor(), and json_build_object().

json_in()

Definition at line 107 of file json.c.

108{

112

113

117

118

120}

#define PG_GETARG_CSTRING(n)

const JsonSemAction nullSemAction

JsonLexContext * makeJsonLexContext(JsonLexContext *lex, text *json, bool need_escapes)

bool pg_parse_json_or_errsave(JsonLexContext *lex, const JsonSemAction *sem, Node *escontext)

text * cstring_to_text(const char *s)

References cstring_to_text(), makeJsonLexContext(), nullSemAction, PG_GETARG_CSTRING, pg_parse_json_or_errsave(), PG_RETURN_NULL, and PG_RETURN_TEXT_P.

json_object()

Definition at line 1406 of file json.c.

1407{

1409 int ndims = ARR_NDIM(in_array);

1411 Datum *in_datums;

1412 bool *in_nulls;

1413 int in_count,

1414 count,

1415 i;

1417

1418 switch (ndims)

1419 {

1420 case 0:

1422 break;

1423

1424 case 1:

1425 if ((ARR_DIMS(in_array)[0]) % 2)

1427 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

1428 errmsg("array must have even number of elements")));

1429 break;

1430

1431 case 2:

1432 if ((ARR_DIMS(in_array)[1]) != 2)

1434 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

1435 errmsg("array must have two columns")));

1436 break;

1437

1438 default:

1440 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

1441 errmsg("wrong number of array subscripts")));

1442 }

1443

1445

1446 count = in_count / 2;

1447

1449

1451

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

1453 {

1454 if (in_nulls[i * 2])

1456 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

1457 errmsg("null value not allowed for object key")));

1458

1459 if (i > 0)

1463 if (in_nulls[i * 2 + 1])

1465 else

1466 {

1469 }

1470 }

1471

1473

1474 pfree(in_datums);

1475 pfree(in_nulls);

1476

1479

1481}

#define PG_GETARG_ARRAYTYPE_P(n)

void deconstruct_array_builtin(ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)

#define CStringGetTextDatum(s)

void initStringInfo(StringInfo str)

References appendStringInfoChar(), appendStringInfoString(), ARR_DIMS, ARR_NDIM, cstring_to_text_with_len(), CStringGetTextDatum, StringInfoData::data, DatumGetPointer(), deconstruct_array_builtin(), ereport, errcode(), errmsg(), ERROR, escape_json_text(), i, initStringInfo(), StringInfoData::len, pfree(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_DATUM, and PG_RETURN_TEXT_P.

json_object_agg_finalfn()

json_object_agg_strict_transfn()

json_object_agg_transfn()

json_object_agg_transfn_worker()

static Datum json_object_agg_transfn_worker ( FunctionCallInfo fcinfo, bool absent_on_null, bool unique_keys ) static

Definition at line 1002 of file json.c.

1004{

1006 oldcontext;

1011 int key_offset;

1012

1014 {

1015

1016 elog(ERROR, "json_object_agg_transfn called in non-aggregate context");

1017 }

1018

1020 {

1021 Oid arg_type;

1022

1023

1024

1025

1026

1027

1028

1032 if (unique_keys)

1034 else

1035 memset(&state->unique_check, 0, sizeof(state->unique_check));

1037

1039

1042 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1043 errmsg("could not determine data type for argument %d", 1)));

1044

1046 &state->key_output_func);

1047

1049

1052 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1053 errmsg("could not determine data type for argument %d", 2)));

1054

1056 &state->val_output_func);

1057

1059 }

1060 else

1061 {

1063 }

1064

1065

1066

1067

1068

1069

1070

1071

1072

1075 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

1076 errmsg("null value not allowed for object key")));

1077

1078

1080

1082 {

1083

1084

1085

1086

1087

1088 if (!unique_keys)

1090

1092 }

1093 else

1094 {

1095 out = state->str;

1096

1097

1098

1099

1100

1101 if (out->len > 2)

1103 }

1104

1106

1107 key_offset = out->len;

1108

1110 state->key_output_func, true);

1111

1112 if (unique_keys)

1113 {

1114

1115

1116

1117

1118

1119

1121 &out->data[key_offset]);

1122

1125 errcode(ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE),

1126 errmsg("duplicate JSON object key value: %s", key));

1127

1130 }

1131

1133

1136 else

1138

1140 state->val_category,

1141 state->val_output_func, false);

1142

1144}

char * MemoryContextStrdup(MemoryContext context, const char *string)

References AggCheckCallContext(), appendStringInfoString(), arg, StringInfoData::data, datum_to_json_internal(), elog, ereport, errcode(), errmsg(), ERROR, FunctionCallInfoBaseData::flinfo, get_fn_expr_argtype(), InvalidOid, json_categorize_type(), json_unique_builder_get_throwawaybuf(), json_unique_builder_init(), json_unique_check_key(), sort-test::key, StringInfoData::len, makeStringInfo(), MemoryContextStrdup(), MemoryContextSwitchTo(), palloc(), PG_ARGISNULL, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_RETURN_POINTER, and skip.

Referenced by json_object_agg_strict_transfn(), json_object_agg_transfn(), json_object_agg_unique_strict_transfn(), and json_object_agg_unique_transfn().

json_object_agg_unique_strict_transfn()

json_object_agg_unique_transfn()

json_object_two_arg()

Definition at line 1490 of file json.c.

1491{

1494 int nkdims = ARR_NDIM(key_array);

1495 int nvdims = ARR_NDIM(val_array);

1497 Datum *key_datums,

1498 *val_datums;

1499 bool *key_nulls,

1500 *val_nulls;

1501 int key_count,

1502 val_count,

1503 i;

1505

1506 if (nkdims > 1 || nkdims != nvdims)

1508 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

1509 errmsg("wrong number of array subscripts")));

1510

1511 if (nkdims == 0)

1513

1516

1517 if (key_count != val_count)

1519 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

1520 errmsg("mismatched array dimensions")));

1521

1523

1525

1526 for (i = 0; i < key_count; ++i)

1527 {

1528 if (key_nulls[i])

1530 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

1531 errmsg("null value not allowed for object key")));

1532

1533 if (i > 0)

1537 if (val_nulls[i])

1539 else

1542 }

1543

1545

1546 pfree(key_datums);

1547 pfree(key_nulls);

1548 pfree(val_datums);

1549 pfree(val_nulls);

1550

1553

1555}

References appendStringInfoChar(), appendStringInfoString(), ARR_NDIM, cstring_to_text_with_len(), CStringGetTextDatum, StringInfoData::data, DatumGetPointer(), deconstruct_array_builtin(), ereport, errcode(), errmsg(), ERROR, escape_json_text(), i, initStringInfo(), StringInfoData::len, pfree(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_DATUM, and PG_RETURN_TEXT_P.

json_out()

json_recv()

Definition at line 152 of file json.c.

153{

155 char *str;

156 int nbytes;

158

160

161

163 false);

165

167}

JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json, size_t len, int encoding, bool need_escapes)

#define pg_parse_json_or_ereport(lex, sem)

int GetDatabaseEncoding(void)

char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)

StringInfoData * StringInfo

References buf, cstring_to_text_with_len(), GetDatabaseEncoding(), makeJsonLexContextCstringLen(), nullSemAction, PG_GETARG_POINTER, pg_parse_json_or_ereport, PG_RETURN_TEXT_P, pq_getmsgtext(), and str.

json_send()

json_typeof()

Definition at line 1874 of file json.c.

1875{

1880

1881

1886

1888 {

1890 type = "object";

1891 break;

1893 type = "array";

1894 break;

1896 type = "string";

1897 break;

1899 type = "number";

1900 break;

1903 type = "boolean";

1904 break;

1906 type = "null";

1907 break;

1908 default:

1910 }

1911

1913}

JsonParseErrorType json_lex(JsonLexContext *lex)

@ JSON_TOKEN_OBJECT_START

void json_errsave_error(JsonParseErrorType error, JsonLexContext *lex, Node *escontext)

References cstring_to_text(), elog, ERROR, json_errsave_error(), json_lex(), JSON_SUCCESS, JSON_TOKEN_ARRAY_START, JSON_TOKEN_FALSE, JSON_TOKEN_NULL, JSON_TOKEN_NUMBER, JSON_TOKEN_OBJECT_START, JSON_TOKEN_STRING, JSON_TOKEN_TRUE, makeJsonLexContext(), PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, JsonLexContext::token_type, and type.

json_unique_builder_get_throwawaybuf()

json_unique_builder_init()

json_unique_check_init()

Definition at line 932 of file json.c.

933{

935

936 memset(&ctl, 0, sizeof(ctl));

942

943 *cxt = hash_create("json object hashtable",

944 32,

947}

HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)

static uint32 json_unique_hash(const void *key, Size keysize)

static int json_unique_hash_match(const void *key1, const void *key2, Size keysize)

struct JsonUniqueHashEntry JsonUniqueHashEntry

References ctl, CurrentMemoryContext, HASH_COMPARE, HASH_CONTEXT, hash_create(), HASH_ELEM, HASH_FUNCTION, json_unique_hash(), and json_unique_hash_match().

Referenced by json_unique_builder_init(), and json_validate().

json_unique_check_key()

static bool json_unique_check_key ( JsonUniqueCheckState * cxt, const char * key, int object_id ) static

Definition at line 958 of file json.c.

959{

961 bool found;

962

966

968

969 return !found;

970}

void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)

References HASH_ENTER, hash_search(), JsonUniqueHashEntry::key, sort-test::key, JsonUniqueHashEntry::key_len, and JsonUniqueHashEntry::object_id.

Referenced by json_build_object_worker(), json_object_agg_transfn_worker(), and json_unique_object_field_start().

json_unique_hash()

static uint32 json_unique_hash ( const void * key, Size keysize ) static

json_unique_hash_match()

static int json_unique_hash_match ( const void * key1, const void * key2, Size keysize ) static

json_unique_object_end()

json_unique_object_field_start()

static JsonParseErrorType json_unique_object_field_start ( void * _state, char * field, bool isnull ) static

json_unique_object_start()

json_validate()

bool json_validate ( text * json,
bool check_unique_keys,
bool throw_error
)

Definition at line 1812 of file json.c.

1813{

1818

1820

1821 if (check_unique_keys)

1822 {

1823 state.lex = &lex;

1824 state.stack = NULL;

1825 state.id_counter = 0;

1826 state.unique = true;

1828

1833 }

1834

1836

1838 {

1839 if (throw_error)

1841

1842 return false;

1843 }

1844

1845 if (check_unique_keys && state.unique)

1846 {

1847 if (throw_error)

1849 (errcode(ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE),

1850 errmsg("duplicate JSON object key value")));

1851

1852 return false;

1853 }

1854

1855 if (check_unique_keys)

1857

1858 return true;

1859}

static JsonParseErrorType json_unique_object_start(void *_state)

static JsonParseErrorType json_unique_object_field_start(void *_state, char *field, bool isnull)

static JsonParseErrorType json_unique_object_end(void *_state)

JsonParseErrorType pg_parse_json(JsonLexContext *lex, const JsonSemAction *sem)

void freeJsonLexContext(JsonLexContext *lex)

json_struct_action object_start

json_ofield_action object_field_start

json_struct_action object_end

References ereport, errcode(), errmsg(), ERROR, freeJsonLexContext(), json_errsave_error(), JSON_SUCCESS, json_unique_check_init(), json_unique_object_end(), json_unique_object_field_start(), json_unique_object_start(), makeJsonLexContext(), nullSemAction, JsonSemAction::object_end, JsonSemAction::object_field_start, JsonSemAction::object_start, pg_parse_json(), and JsonSemAction::semstate.

Referenced by ExecEvalJsonConstructor(), and ExecEvalJsonIsPredicate().

JsonEncodeDateTime()

char * JsonEncodeDateTime ( char * buf,
Datum value,
Oid typid,
const int * tzp
)

Definition at line 310 of file json.c.

311{

312 if (buf)

314

315 switch (typid)

316 {

317 case DATEOID:

318 {

321

323

324

327 else

328 {

332 }

333 }

334 break;

335 case TIMEOID:

336 {

339 *tm = &tt;

341

342

345 }

346 break;

347 case TIMETZOID:

348 {

351 *tm = &tt;

353 int tz;

354

355

358 }

359 break;

360 case TIMESTAMPOID:

361 {

365

367

372 else

374 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

375 errmsg("timestamp out of range")));

376 }

377 break;

378 case TIMESTAMPTZOID:

379 {

382 int tz;

384 const char *tzn = NULL;

385

387

388

389

390

391

392

393

394 if (tzp)

395 {

396 tz = *tzp;

398 }

399

400

404 tzp ? NULL : &tzn, NULL) == 0)

405 {

406 if (tzp)

407 tm.tm_isdst = 1;

408

410 }

411 else

413 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

414 errmsg("timestamp out of range")));

415 }

416 break;

417 default:

418 elog(ERROR, "unknown jsonb value datetime type oid %u", typid);

419 return NULL;

420 }

421

422 return buf;

423}

void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str)

void j2date(int jd, int *year, int *month, int *day)

void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)

void EncodeDateOnly(struct pg_tm *tm, int style, char *str)

void EncodeSpecialTimestamp(Timestamp dt, char *str)

int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)

#define TIMESTAMP_NOT_FINITE(j)

#define POSTGRES_EPOCH_JDATE

int timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp)

int time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)

void EncodeSpecialDate(DateADT dt, char *str)

#define DATE_NOT_FINITE(j)

static TimeTzADT * DatumGetTimeTzADTP(Datum X)

static DateADT DatumGetDateADT(Datum X)

static TimeADT DatumGetTimeADT(Datum X)

static Timestamp DatumGetTimestamp(Datum X)

static TimestampTz DatumGetTimestampTz(Datum X)

References buf, DATE_NOT_FINITE, DatumGetDateADT(), DatumGetTimeADT(), DatumGetTimestamp(), DatumGetTimestampTz(), DatumGetTimeTzADTP(), elog, EncodeDateOnly(), EncodeDateTime(), EncodeSpecialDate(), EncodeSpecialTimestamp(), EncodeTimeOnly(), ereport, errcode(), errmsg(), ERROR, j2date(), MAXDATELEN, palloc(), POSTGRES_EPOCH_JDATE, time2tm(), timestamp2tm(), TIMESTAMP_NOT_FINITE, timetz2tm(), tm, pg_tm::tm_isdst, pg_tm::tm_mday, pg_tm::tm_mon, pg_tm::tm_year, USE_XSD_DATES, USECS_PER_SEC, and value.

Referenced by convertJsonbScalar(), datum_to_json_internal(), datum_to_jsonb_internal(), and executeItemOptUnwrapTarget().

row_to_json()

row_to_json_pretty()

to_json()

Definition at line 739 of file json.c.

740{

744 Oid outfuncoid;

745

748 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

749 errmsg("could not determine input data type")));

750

752 &tcategory, &outfuncoid);

753

755}

Datum datum_to_json(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)

References datum_to_json(), ereport, errcode(), errmsg(), ERROR, get_fn_expr_argtype(), InvalidOid, json_categorize_type(), PG_GETARG_DATUM, PG_RETURN_DATUM, and val.

to_json_is_immutable()

bool to_json_is_immutable ( Oid typoid )

Definition at line 700 of file json.c.

701{

703 Oid outfuncoid;

704

706

707 switch (tcategory)

708 {

713 return true;

714

718 return false;

719

721 return false;

722

724 return false;

725

729 return func_volatile(outfuncoid) == PROVOLATILE_IMMUTABLE;

730 }

731

732 return false;

733}

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