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