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

314

315 switch (typid)

316 {

317 case DATEOID:

318 {

321

323

324

327 else

328 {

332 }

333 }

334 break;

335 case TIMEOID:

336 {

339 *tm = &tt;

341

342

345 }

346 break;

347 case TIMETZOID:

348 {

351 *tm = &tt;

353 int tz;

354

355

358 }

359 break;

360 case TIMESTAMPOID:

361 {

365

367

372 else

374 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

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

376 }

377 break;

378 case TIMESTAMPTZOID:

379 {

382 int tz;

384 const char *tzn = NULL;

385

387

388

389

390

391

392

393

394 if (tzp)

395 {

396 tz = *tzp;

398 }

399

400

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

405 {

406 if (tzp)

407 tm.tm_isdst = 1;

408

410 }

411 else

413 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

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

415 }

416 break;

417 default:

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

419 return NULL;

420 }

421

422 return buf;

423}

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

1712 if (i == len)

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

1761

1762

1763 entry = palloc(sizeof(*entry));

1766 state->stack = entry;

1767

1769}

1770

1773{

1776

1777 if (state->unique)

1779

1780 entry = state->stack;

1781 state->stack = entry->parent;

1784}

1785

1788{

1791

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

1846 {

1847 if (throw_error)

1849 (errcode(ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE),

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

1851

1852 return false;

1853 }

1854

1855 if (check_unique_keys)

1857

1858 return true;

1859}

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)