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
27#include "utils/fmgroids.h"
32
33
34
35
36
37
38
39
40
42
43
45{
50
51
53{
57
58
60{
67
68
70{
75
76
77
79{
87
89 bool use_line_feeds);
91 Datum *vals, bool *nulls, int *valcount,
93 bool use_line_feeds);
95 bool use_line_feeds);
98 bool key_scalar);
100 Oid val_type, bool key_scalar);
102
103
104
105
108{
112
113
117
118
120}
121
122
123
124
127{
128
130
132}
133
134
135
136
139{
142
146}
147
148
149
150
153{
155 char *str;
156 int nbytes;
158
160
161
163 false);
165
167}
168
169
170
171
172
173
174
175
176
177
178static void
181 bool key_scalar)
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}
303
304
305
306
307
308
309char *
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}
424
425
426
427
428
429
430static void
433 Oid outfuncoid, bool use_line_feeds)
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}
469
470
471
472
473static void
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}
516
517
518
519
520static void
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}
593
594
595
596
597
598
599
600
601static void
603 Oid val_type, bool key_scalar)
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}
625
626
627
628
631{
634
636
638
640}
641
642
643
644
647{
651
653
655
657}
658
659
660
661
664{
667
669
671
673}
674
675
676
677
680{
684
686
688
690}
691
692
693
694
695
696
697
698
699bool
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}
734
735
736
737
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}
756
757
758
759
760
761
764{
766
768 false);
769
771}
772
773
774
775
776
777
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}
855
856
857
858
859
862{
864}
865
866
867
868
871{
873}
874
875
876
877
880{
882
883
885
887 NULL :
889
890
891 if (state == NULL)
893
894
896}
897
898
901{
904
906
908}
909
910static int
912{
915
918
921
922 return strncmp(entry1->key, entry2->key, entry1->key_len);
923}
924
925
926
927
928
929
930
931static void
933{
935
936 memset(&ctl, 0, sizeof(ctl));
942
943 *cxt = hash_create("json object hashtable",
944 32,
947}
948
949static void
951{
955}
956
957static bool
959{
961 bool found;
962
966
968
969 return !found;
970}
971
972
973
974
975
976
979{
981
982 if (!out->data)
983 {
985
988 }
989 else
990
991 out->len = 0;
992
993 return out;
994}
995
996
997
998
999
1000
1003 bool absent_on_null, bool unique_keys)
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}
1145
1146
1147
1148
1151{
1153}
1154
1155
1156
1157
1160{
1162}
1163
1164
1165
1166
1169{
1171}
1172
1173
1174
1175
1178{
1180}
1181
1182
1183
1184
1187{
1189
1190
1192
1194
1195
1196 if (state == NULL)
1198
1199
1201}
1202
1203
1204
1205
1206
1207
1208static text *
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}
1222
1225 bool absent_on_null, bool unique_keys)
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}
1313
1314
1315
1316
1319{
1321 bool *nulls;
1323
1324
1327
1328 if (nargs < 0)
1330
1332}
1333
1334
1335
1336
1339{
1341}
1342
1345 bool absent_on_null)
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}
1369
1370
1371
1372
1375{
1377 bool *nulls;
1379
1380
1383
1384 if (nargs < 0)
1386
1388}
1389
1390
1391
1392
1395{
1397}
1398
1399
1400
1401
1402
1403
1404
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}
1482
1483
1484
1485
1486
1487
1488
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}
1556
1557
1558
1559
1560
1563{
1564 switch (c)
1565 {
1566 case '\b':
1568 break;
1569 case '\f':
1571 break;
1572 case '\n':
1574 break;
1575 case '\r':
1577 break;
1578 case '\t':
1580 break;
1581 case '"':
1583 break;
1584 case '\\':
1586 break;
1587 default:
1588 if ((unsigned char) c < ' ')
1590 else
1592 break;
1593 }
1594}
1595
1596
1597
1598
1599
1600
1601void
1603{
1605
1606 for (; *str != '\0'; str++)
1608
1610}
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622#define ESCAPE_JSON_FLUSH_AFTER 512
1623
1624
1625
1626
1627
1628
1629
1630void
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}
1727
1728
1729
1730
1731
1732
1733
1734
1735void
1737{
1738
1741 char *str;
1742
1744
1746
1747
1748 if (tunpacked != txt)
1749 pfree(tunpacked);
1750}
1751
1752
1755{
1758
1759 if (->unique)
1761
1762
1763 entry = palloc(sizeof(*entry));
1766 state->stack = entry;
1767
1769}
1770
1773{
1776
1777 if (->unique)
1779
1780 entry = state->stack;
1781 state->stack = entry->parent;
1784}
1785
1788{
1791
1792 if (->unique)
1794
1795
1798
1799 state->unique = false;
1800
1801
1802 while ((entry = state->stack))
1803 {
1806 }
1808}
1809
1810
1811bool
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}
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
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}
#define PG_GETARG_ARRAYTYPE_P(n)
#define DatumGetArrayTypeP(X)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
void deconstruct_array_builtin(ArrayType *array, Oid elmtype, 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, long nelem, const HASHCTL *info, int flags)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
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)
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)
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)
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 uint32 DatumGetUInt32(Datum X)
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)
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)
StringInfoData * StringInfo
#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)
#define SET_VARSIZE(PTR, len)
#define VARSIZE_ANY_EXHDR(PTR)
text * cstring_to_text_with_len(const char *s, int len)
text * cstring_to_text(const char *s)