PostgreSQL Source Code: src/backend/utils/adt/json.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
15
28#include "utils/fmgroids.h"
33
34
35
36
37
38
39
40
41
43
44
46{
51
52
54{
58
59
61{
68
69
71{
76
77
78
80{
88
90 bool use_line_feeds);
92 const Datum *vals, const bool *nulls, int *valcount,
94 bool use_line_feeds);
96 bool use_line_feeds);
99 bool key_scalar);
101 Oid val_type, bool key_scalar);
103
104
105
106
109{
113
114
118
119
121}
122
123
124
125
128{
129
131
133}
134
135
136
137
140{
143
147}
148
149
150
151
154{
156 char *str;
157 int nbytes;
159
161
162
164 false);
166
168}
169
170
171
172
173
174
175
176
177
178
179static void
182 bool key_scalar)
183{
184 char *outputstr;
185 text *jsontext;
186
188
189
190 Assert(!(key_scalar && is_null));
191
192 if (is_null)
193 {
195 return;
196 }
197
198 if (key_scalar &&
204 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
205 errmsg("key value must be scalar, not array, composite, or json")));
206
207 switch (tcategory)
208 {
211 break;
214 break;
216 if (key_scalar)
220 else
222 if (key_scalar)
224 break;
227
228
229
230
231
232
233
234 if (!key_scalar &&
235 ((*outputstr >= '0' && *outputstr <= '9') ||
236 (*outputstr == '-' &&
237 (outputstr[1] >= '0' && outputstr[1] <= '9'))))
239 else
240 {
244 }
245 pfree(outputstr);
246 break;
248 {
250
255 }
256 break;
258 {
260
265 }
266 break;
268 {
270
275 }
276 break;
278
281 pfree(outputstr);
282 break;
284
289 break;
290 default:
291
292 if (outfuncoid == F_TEXTOUT || outfuncoid == F_VARCHAROUT ||
293 outfuncoid == F_BPCHAROUT)
295 else
296 {
299 pfree(outputstr);
300 }
301 break;
302 }
303}
304
305
306
307
308
309
310char *
312{
313 if ()
315
316 switch (typid)
317 {
318 case DATEOID:
319 {
322
324
325
328 else
329 {
333 }
334 }
335 break;
336 case TIMEOID:
337 {
340 *tm = &tt;
342
343
346 }
347 break;
348 case TIMETZOID:
349 {
352 *tm = &tt;
354 int tz;
355
356
359 }
360 break;
361 case TIMESTAMPOID:
362 {
366
368
373 else
375 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
376 errmsg("timestamp out of range")));
377 }
378 break;
379 case TIMESTAMPTZOID:
380 {
383 int tz;
385 const char *tzn = NULL;
386
388
389
390
391
392
393
394
395 if (tzp)
396 {
397 tz = *tzp;
399 }
400
401
405 tzp ? NULL : &tzn, NULL) == 0)
406 {
407 if (tzp)
409
411 }
412 else
414 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
415 errmsg("timestamp out of range")));
416 }
417 break;
418 default:
419 elog(ERROR, "unknown jsonb value datetime type oid %u", typid);
420 return NULL;
421 }
422
423 return buf;
424}
425
426
427
428
429
430
431static void
433 const bool *nulls, int *valcount, JsonTypeCategory tcategory,
434 Oid outfuncoid, bool use_line_feeds)
435{
436 int i;
437 const char *sep;
438
440
441 sep = use_line_feeds ? ",\n " : ",";
442
444
445 for (i = 1; i <= dims[dim]; i++)
446 {
447 if (i > 1)
449
450 if (dim + 1 == ndims)
451 {
453 result, tcategory,
454 outfuncoid, false);
455 (*valcount)++;
456 }
457 else
458 {
459
460
461
462
464 valcount, tcategory, outfuncoid, false);
465 }
466 }
467
469}
470
471
472
473
474static void
476{
479 int *dim;
480 int ndim;
482 int count = 0;
484 bool *nulls;
486 bool typbyval;
489 Oid outfuncoid;
490
494
496 {
498 return;
499 }
500
502 &typlen, &typbyval, &typalign);
503
505 &tcategory, &outfuncoid);
506
510
511 array_dim_to_json(result, 0, ndim, dim, elements, nulls, &count, tcategory,
512 outfuncoid, use_line_feeds);
513
516}
517
518
519
520
521static void
523{
525 Oid tupType;
529 *tuple;
530 int i;
531 bool needsep = false;
532 const char *sep;
533 int seplen;
534
535
536
537
538
539 sep = use_line_feeds ? ",\n " : ",";
540 seplen = use_line_feeds ? strlen(",\n ") : strlen(",");
541
543
544
548
549
552 tuple = &tmptup;
553
555
556 for (i = 0; i < tupdesc->natts; i++)
557 {
559 bool isnull;
562 Oid outfuncoid;
564
565 if (att->attisdropped)
566 continue;
567
568 if (needsep)
570 needsep = true;
571
575
577
578 if (isnull)
579 {
582 }
583 else
585 &outfuncoid);
586
588 false);
589 }
590
593}
594
595
596
597
598
599
600
601
602static void
604 Oid val_type, bool key_scalar)
605{
607 Oid outfuncoid;
608
611 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
612 errmsg("could not determine input data type")));
613
614 if (is_null)
615 {
618 }
619 else
621 &tcategory, &outfuncoid);
622
624 key_scalar);
625}
626
627
628
629
632{
635
637
639
641}
642
643
644
645
648{
652
654
656
658}
659
660
661
662
665{
668
670
672
674}
675
676
677
678
681{
685
687
689
691}
692
693
694
695
696
697
698
699
700bool
702{
704 Oid outfuncoid;
705
707
708 switch (tcategory)
709 {
714 return true;
715
719 return false;
720
722 return false;
723
725 return false;
726
730 return func_volatile(outfuncoid) == PROVOLATILE_IMMUTABLE;
731 }
732
733 return false;
734}
735
736
737
738
741{
745 Oid outfuncoid;
746
749 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
750 errmsg("could not determine input data type")));
751
753 &tcategory, &outfuncoid);
754
756}
757
758
759
760
761
762
765{
767
770 false);
771
773}
774
775
776
777
778
779
782{
784 oldcontext;
787
789 {
790
791 elog(ERROR, "json_agg_transfn called in non-aggregate context");
792 }
793
795 {
797
800 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
801 errmsg("could not determine input data type")));
802
803
804
805
806
807
808
813
816 &state->val_output_func);
817 }
818 else
819 {
821 }
822
825
826 if (state->str->len > 1)
828
829
831 {
835 }
836
838
839
843 {
845 }
846
848 state->val_output_func, false);
849
850
851
852
853
854
856}
857
858
859
860
861
864{
866}
867
868
869
870
873{
875}
876
877
878
879
882{
884
885
887
889 NULL :
891
892
893 if (state == NULL)
895
896
898}
899
900
903{
906
908
910}
911
912static int
914{
917
920
923
924 return strncmp(entry1->key, entry2->key, entry1->key_len);
925}
926
927
928
929
930
931
932
933static void
935{
937
938 memset(&ctl, 0, sizeof(ctl));
944
945 *cxt = hash_create("json object hashtable",
946 32,
949}
950
951static void
953{
957}
958
959static bool
961{
963 bool found;
964
968
970
971 return !found;
972}
973
974
975
976
977
978
981{
983
984 if (!out->data)
985 {
987
990 }
991 else
992
993 out->len = 0;
994
995 return out;
996}
997
998
999
1000
1001
1002
1005 bool absent_on_null, bool unique_keys)
1006{
1008 oldcontext;
1013 int key_offset;
1014
1016 {
1017
1018 elog(ERROR, "json_object_agg_transfn called in non-aggregate context");
1019 }
1020
1022 {
1023 Oid arg_type;
1024
1025
1026
1027
1028
1029
1030
1034 if (unique_keys)
1036 else
1037 memset(&state->unique_check, 0, sizeof(state->unique_check));
1039
1041
1044 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1045 errmsg("could not determine data type for argument %d", 1)));
1046
1048 &state->key_output_func);
1049
1051
1054 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1055 errmsg("could not determine data type for argument %d", 2)));
1056
1058 &state->val_output_func);
1059
1061 }
1062 else
1063 {
1065 }
1066
1067
1068
1069
1070
1071
1072
1073
1074
1077 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1078 errmsg("null value not allowed for object key")));
1079
1080
1082
1084 {
1085
1086
1087
1088
1089
1090 if (!unique_keys)
1092
1094 }
1095 else
1096 {
1097 out = state->str;
1098
1099
1100
1101
1102
1103 if (out->len > 2)
1105 }
1106
1108
1109 key_offset = out->len;
1110
1112 state->key_output_func, true);
1113
1114 if (unique_keys)
1115 {
1116
1117
1118
1119
1120
1121
1123 &out->data[key_offset]);
1124
1127 errcode(ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE),
1128 errmsg("duplicate JSON object key value: %s", key));
1129
1132 }
1133
1135
1138 else
1140
1142 state->val_category,
1143 state->val_output_func, false);
1144
1146}
1147
1148
1149
1150
1153{
1155}
1156
1157
1158
1159
1162{
1164}
1165
1166
1167
1168
1171{
1173}
1174
1175
1176
1177
1180{
1182}
1183
1184
1185
1186
1189{
1191
1192
1194
1196
1197
1198 if (state == NULL)
1200
1201
1203}
1204
1205
1206
1207
1208
1209
1210static text *
1212{
1213
1214 int buflen = buffer->len;
1215 int addlen = strlen(addon);
1217
1219 memcpy(VARDATA(result), buffer->data, buflen);
1220 memcpy(VARDATA(result) + buflen, addon, addlen);
1221
1222 return result;
1223}
1224
1227 bool absent_on_null, bool unique_keys)
1228{
1229 int i;
1230 const char *sep = "";
1233
1234 if (nargs % 2 != 0)
1236 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1237 errmsg("argument list must have even number of elements"),
1238
1239 errhint("The arguments of %s must consist of alternating keys and values.",
1240 "json_build_object()")));
1241
1243
1245
1246 if (unique_keys)
1248
1249 for (i = 0; i < nargs; i += 2)
1250 {
1253 int key_offset;
1254
1255
1256 skip = absent_on_null && nulls[i + 1];
1257
1259 {
1260
1261 if (!unique_keys)
1262 continue;
1263
1265 }
1266 else
1267 {
1269 sep = ", ";
1270 out = result;
1271 }
1272
1273
1274 if (nulls[i])
1276 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1277 errmsg("null value not allowed for object key")));
1278
1279
1280 key_offset = out->len;
1281
1283
1284 if (unique_keys)
1285 {
1286
1287
1288
1289
1290
1291
1292
1293
1295
1298 errcode(ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE),
1299 errmsg("duplicate JSON object key value: %s", key));
1300
1302 continue;
1303 }
1304
1306
1307
1309 }
1310
1312
1314}
1315
1316
1317
1318
1321{
1323 bool *nulls;
1325
1326
1329
1330 if (nargs < 0)
1332
1334}
1335
1336
1337
1338
1341{
1343}
1344
1347 bool absent_on_null)
1348{
1349 int i;
1350 const char *sep = "";
1352
1354
1356
1357 for (i = 0; i < nargs; i++)
1358 {
1359 if (absent_on_null && nulls[i])
1360 continue;
1361
1363 sep = ", ";
1365 }
1366
1368
1370}
1371
1372
1373
1374
1377{
1379 bool *nulls;
1381
1382
1385
1386 if (nargs < 0)
1388
1390}
1391
1392
1393
1394
1397{
1399}
1400
1401
1402
1403
1404
1405
1406
1409{
1411 int ndims = ARR_NDIM(in_array);
1413 Datum *in_datums;
1414 bool *in_nulls;
1415 int in_count,
1416 count,
1417 i;
1419
1420 switch (ndims)
1421 {
1422 case 0:
1424 break;
1425
1426 case 1:
1427 if ((ARR_DIMS(in_array)[0]) % 2)
1429 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1430 errmsg("array must have even number of elements")));
1431 break;
1432
1433 case 2:
1434 if ((ARR_DIMS(in_array)[1]) != 2)
1436 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1437 errmsg("array must have two columns")));
1438 break;
1439
1440 default:
1442 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1443 errmsg("wrong number of array subscripts")));
1444 }
1445
1447
1448 count = in_count / 2;
1449
1451
1453
1454 for (i = 0; i < count; ++i)
1455 {
1456 if (in_nulls[i * 2])
1458 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1459 errmsg("null value not allowed for object key")));
1460
1461 if (i > 0)
1465 if (in_nulls[i * 2 + 1])
1467 else
1468 {
1471 }
1472 }
1473
1475
1476 pfree(in_datums);
1477 pfree(in_nulls);
1478
1481
1483}
1484
1485
1486
1487
1488
1489
1490
1493{
1496 int nkdims = ARR_NDIM(key_array);
1497 int nvdims = ARR_NDIM(val_array);
1499 Datum *key_datums,
1500 *val_datums;
1501 bool *key_nulls,
1502 *val_nulls;
1503 int key_count,
1504 val_count,
1505 i;
1507
1508 if (nkdims > 1 || nkdims != nvdims)
1510 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1511 errmsg("wrong number of array subscripts")));
1512
1513 if (nkdims == 0)
1515
1518
1519 if (key_count != val_count)
1521 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1522 errmsg("mismatched array dimensions")));
1523
1525
1527
1528 for (i = 0; i < key_count; ++i)
1529 {
1530 if (key_nulls[i])
1532 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1533 errmsg("null value not allowed for object key")));
1534
1535 if (i > 0)
1539 if (val_nulls[i])
1541 else
1544 }
1545
1547
1548 pfree(key_datums);
1549 pfree(key_nulls);
1550 pfree(val_datums);
1551 pfree(val_nulls);
1552
1555
1557}
1558
1559
1560
1561
1562
1565{
1566 switch (c)
1567 {
1568 case '\b':
1570 break;
1571 case '\f':
1573 break;
1574 case '\n':
1576 break;
1577 case '\r':
1579 break;
1580 case '\t':
1582 break;
1583 case '"':
1585 break;
1586 case '\\':
1588 break;
1589 default:
1590 if ((unsigned char) c < ' ')
1592 else
1594 break;
1595 }
1596}
1597
1598
1599
1600
1601
1602
1603void
1605{
1607
1608 for (; *str != '\0'; str++)
1610
1612}
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624#define ESCAPE_JSON_FLUSH_AFTER 512
1625
1626
1627
1628
1629
1630
1631
1632void
1634{
1635 int vlen;
1636
1638
1639
1640
1641
1642
1643
1645
1646
1647
1648
1649
1650 vlen = len & (int) (~(sizeof(Vector8) - 1));
1651
1653
1654 for (int i = 0, copypos = 0;;)
1655 {
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666 for (; i < vlen; i += sizeof(Vector8))
1667 {
1669
1671
1672
1673
1674
1675
1677 vector8_has(chunk, (unsigned char) '"') ||
1678 vector8_has(chunk, (unsigned char) '\\'))
1679 break;
1680
1681#ifdef ESCAPE_JSON_FLUSH_AFTER
1682
1683
1684
1685
1686
1687
1689 {
1691 copypos = i;
1692 }
1693#endif
1694 }
1695
1696
1697
1698
1699
1700
1701 if (copypos < i)
1702 {
1704 copypos = i;
1705 }
1706
1707
1708
1709
1710
1711 for (int b = 0; b < sizeof(Vector8); b++)
1712 {
1713
1715 goto done;
1716
1718
1720 }
1721
1722 copypos = i;
1723
1724 }
1725
1726done:
1728}
1729
1730
1731
1732
1733
1734
1735
1736
1737void
1739{
1740
1743 char *str;
1744
1746
1748
1749
1750 if (tunpacked != txt)
1751 pfree(tunpacked);
1752}
1753
1754
1757{
1760
1761 if (->unique)
1763
1764
1768 state->stack = entry;
1769
1771}
1772
1775{
1778
1779 if (->unique)
1781
1782 entry = state->stack;
1783 state->stack = entry->parent;
1786}
1787
1790{
1793
1794 if (->unique)
1796
1797
1800
1801 state->unique = false;
1802
1803
1804 while ((entry = state->stack))
1805 {
1808 }
1810}
1811
1812
1813bool
1815{
1820
1822
1823 if (check_unique_keys)
1824 {
1825 state.lex = &lex;
1826 state.stack = NULL;
1827 state.id_counter = 0;
1828 state.unique = true;
1830
1835 }
1836
1838
1840 {
1841 if (throw_error)
1843
1844 return false;
1845 }
1846
1847 if (check_unique_keys && .unique)
1848 {
1849 if (throw_error)
1851 (errcode(ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE),
1852 errmsg("duplicate JSON object key value")));
1853
1854 return false;
1855 }
1856
1857 if (check_unique_keys)
1859
1860 return true;
1861}
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1877{
1882
1883
1888
1890 {
1892 type = "object";
1893 break;
1895 type = "array";
1896 break;
1898 type = "string";
1899 break;
1901 type = "number";
1902 break;
1905 type = "boolean";
1906 break;
1908 type = "null";
1909 break;
1910 default:
1912 }
1913
1915}
#define PG_GETARG_ARRAYTYPE_P(n)
#define DatumGetArrayTypeP(X)
void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
void deconstruct_array(const ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
int ArrayGetNItems(int ndim, const int *dims)
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 CStringGetTextDatum(s)
#define TextDatumGetCString(d)
#define unconstify(underlying_type, expr)
#define pg_attribute_always_inline
#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)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
HTAB * hash_create(const char *tabname, int64 nelem, const HASHCTL *info, int flags)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define palloc_object(type)
struct varlena * pg_detoast_datum_packed(struct varlena *datum)
char * OidOutputFunctionCall(Oid functionId, Datum val)
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
#define OidFunctionCall1(functionId, arg1)
#define PG_GETARG_TEXT_PP(n)
#define PG_RETURN_BYTEA_P(x)
#define DatumGetHeapTupleHeader(X)
#define DatumGetTextPP(X)
#define PG_GETARG_POINTER(n)
#define PG_RETURN_CSTRING(x)
#define PG_GETARG_DATUM(n)
#define PG_GETARG_CSTRING(n)
#define PG_RETURN_TEXT_P(x)
#define PG_GETARG_BOOL(n)
#define PG_RETURN_DATUM(x)
#define PG_RETURN_POINTER(x)
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
uint32 hash_bytes_uint32(uint32 k)
uint32 hash_bytes(const unsigned char *k, int keylen)
Assert(PointerIsAligned(start, uint64))
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)
Datum row_to_json(PG_FUNCTION_ARGS)
struct JsonUniqueStackEntry JsonUniqueStackEntry
static JsonParseErrorType json_unique_object_start(void *_state)
static uint32 json_unique_hash(const void *key, Size keysize)
Datum json_build_object_noargs(PG_FUNCTION_ARGS)
void escape_json_text(StringInfo buf, const text *txt)
char * JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp)
static int json_unique_hash_match(const void *key1, const void *key2, Size keysize)
static void json_unique_check_init(JsonUniqueCheckState *cxt)
static text * catenate_stringinfo_string(StringInfo buffer, const char *addon)
struct HTAB * JsonUniqueCheckState
Datum json_agg_strict_transfn(PG_FUNCTION_ARGS)
static pg_attribute_always_inline void escape_json_char(StringInfo buf, char c)
struct JsonUniqueBuilderState JsonUniqueBuilderState
Datum json_in(PG_FUNCTION_ARGS)
static StringInfo json_unique_builder_get_throwawaybuf(JsonUniqueBuilderState *cxt)
static bool json_unique_check_key(JsonUniqueCheckState *cxt, const char *key, int object_id)
struct JsonUniqueParsingState JsonUniqueParsingState
Datum json_out(PG_FUNCTION_ARGS)
Datum json_agg_transfn(PG_FUNCTION_ARGS)
Datum to_json(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_object_agg_finalfn(PG_FUNCTION_ARGS)
Datum row_to_json_pretty(PG_FUNCTION_ARGS)
struct JsonUniqueHashEntry JsonUniqueHashEntry
Datum json_send(PG_FUNCTION_ARGS)
static Datum json_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
void escape_json_with_len(StringInfo buf, const char *str, int len)
static void datum_to_json_internal(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Datum array_to_json_pretty(PG_FUNCTION_ARGS)
static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, const Datum *vals, const bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid, bool use_line_feeds)
Datum json_object_agg_unique_transfn(PG_FUNCTION_ARGS)
Datum json_object_two_arg(PG_FUNCTION_ARGS)
Datum json_object_agg_unique_strict_transfn(PG_FUNCTION_ARGS)
Datum json_build_array_noargs(PG_FUNCTION_ARGS)
Datum json_object_agg_transfn(PG_FUNCTION_ARGS)
Datum array_to_json(PG_FUNCTION_ARGS)
Datum json_object_agg_strict_transfn(PG_FUNCTION_ARGS)
Datum json_build_array(PG_FUNCTION_ARGS)
static void json_unique_builder_init(JsonUniqueBuilderState *cxt)
Datum json_build_object_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null, bool unique_keys)
#define ESCAPE_JSON_FLUSH_AFTER
static void add_json(Datum val, bool is_null, StringInfo result, Oid val_type, bool key_scalar)
Datum json_agg_finalfn(PG_FUNCTION_ARGS)
Datum json_recv(PG_FUNCTION_ARGS)
Datum datum_to_json(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
bool json_validate(text *json, bool check_unique_keys, bool throw_error)
Datum json_typeof(PG_FUNCTION_ARGS)
void escape_json(StringInfo buf, const char *str)
struct JsonAggState JsonAggState
static void composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
static Datum json_object_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null, bool unique_keys)
Datum json_object(PG_FUNCTION_ARGS)
Datum json_build_object(PG_FUNCTION_ARGS)
bool to_json_is_immutable(Oid typoid)
static JsonParseErrorType json_unique_object_field_start(void *_state, char *field, bool isnull)
static void array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
static JsonParseErrorType json_unique_object_end(void *_state)
JsonParseErrorType pg_parse_json(JsonLexContext *lex, const JsonSemAction *sem)
JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json, size_t len, int encoding, bool need_escapes)
const JsonSemAction nullSemAction
JsonParseErrorType json_lex(JsonLexContext *lex)
void freeJsonLexContext(JsonLexContext *lex)
@ JSON_TOKEN_OBJECT_START
JsonLexContext * makeJsonLexContext(JsonLexContext *lex, text *json, bool need_escapes)
void json_categorize_type(Oid typoid, bool is_jsonb, JsonTypeCategory *tcategory, Oid *outfuncoid)
void json_errsave_error(JsonParseErrorType error, JsonLexContext *lex, Node *escontext)
bool pg_parse_json_or_errsave(JsonLexContext *lex, const JsonSemAction *sem, Node *escontext)
#define pg_parse_json_or_ereport(lex, sem)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
char func_volatile(Oid funcid)
int GetDatabaseEncoding(void)
char * MemoryContextStrdup(MemoryContext context, const char *string)
char * pstrdup(const char *in)
void pfree(void *pointer)
MemoryContext CurrentMemoryContext
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
FormData_pg_attribute * Form_pg_attribute
static const struct exclude_list_item skip[]
static char buf[DEFAULT_XLOG_SEG_SIZE]
static bool DatumGetBool(Datum X)
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
void pq_sendtext(StringInfo buf, const char *str, int slen)
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
void pq_begintypsend(StringInfo buf)
bytea * pq_endtypsend(StringInfo buf)
static unsigned hash(unsigned *uv, int n)
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 check_stack_depth(void)
struct StringInfoData * StringInfo
StringInfo makeStringInfo(void)
void appendStringInfo(StringInfo str, const char *fmt,...)
void enlargeStringInfo(StringInfo str, int needed)
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
#define appendStringInfoCharMacro(str, ch)
JsonUniqueBuilderState unique_check
JsonTypeCategory key_category
JsonTypeCategory val_category
json_struct_action object_start
json_ofield_action object_field_start
json_struct_action object_end
JsonUniqueCheckState check
StringInfoData skipped_keys
JsonUniqueCheckState check
JsonUniqueStackEntry * stack
struct JsonUniqueStackEntry * parent
#define ReleaseTupleDesc(tupdesc)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
static Timestamp DatumGetTimestamp(Datum X)
static TimestampTz DatumGetTimestampTz(Datum X)
static Size VARSIZE_ANY_EXHDR(const void *PTR)
static char * VARDATA(const void *PTR)
static char * VARDATA_ANY(const void *PTR)
static void SET_VARSIZE(void *PTR, Size len)
text * cstring_to_text_with_len(const char *s, int len)
text * cstring_to_text(const char *s)