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

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)

408 tm.tm_isdst = 1;

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

1714 if (i == len)

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

1763

1764

1768 state->stack = entry;

1769

1771}

1772

1775{

1778

1779 if (state->unique)

1781

1782 entry = state->stack;

1783 state->stack = entry->parent;

1786}

1787

1790{

1793

1794 if (state->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 && state.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)