PostgreSQL Source Code: src/common/jsonapi.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14#ifndef FRONTEND

16#else

18#endif

19

23

24#ifdef JSONAPI_USE_PQEXPBUFFER

26#else

29#endif

30

31

32

33

34

35#ifdef JSONAPI_USE_PQEXPBUFFER

36

37#define STRDUP(s) strdup(s)

38#define ALLOC(size) malloc(size)

39#define ALLOC0(size) calloc(1, size)

40#define REALLOC realloc

41#define FREE(s) free(s)

42

43#define jsonapi_appendStringInfo appendPQExpBuffer

44#define jsonapi_appendBinaryStringInfo appendBinaryPQExpBuffer

45#define jsonapi_appendStringInfoChar appendPQExpBufferChar

46

47#define jsonapi_appendStringInfoCharMacro appendPQExpBufferChar

48#define jsonapi_makeStringInfo createPQExpBuffer

49#define jsonapi_initStringInfo initPQExpBuffer

50#define jsonapi_resetStringInfo resetPQExpBuffer

51#define jsonapi_termStringInfo termPQExpBuffer

52#define jsonapi_destroyStringInfo destroyPQExpBuffer

53

54#else

55

56#define STRDUP(s) pstrdup(s)

57#define ALLOC(size) palloc(size)

58#define ALLOC0(size) palloc0(size)

59#define REALLOC repalloc

60

61#ifdef FRONTEND

62#define FREE pfree

63#else

64

65

66

67

68

69#define FREE(s) do { \

70 void *__v = (s); \

71 if (__v) \

72 pfree(__v); \

73} while (0)

74#endif

75

76#define jsonapi_appendStringInfo appendStringInfo

77#define jsonapi_appendBinaryStringInfo appendBinaryStringInfo

78#define jsonapi_appendStringInfoChar appendStringInfoChar

79#define jsonapi_appendStringInfoCharMacro appendStringInfoCharMacro

80#define jsonapi_makeStringInfo makeStringInfo

81#define jsonapi_initStringInfo initStringInfo

82#define jsonapi_resetStringInfo resetStringInfo

83#define jsonapi_termStringInfo(s) pfree((s)->data)

84#define jsonapi_destroyStringInfo destroyStringInfo

85

86#endif

87

88

89

90

91

92

93typedef enum

94{

105

106

107

108

109

110

111

112

114{

120};

121

123{

135};

136

137

138

139

140

141

142

143

145{

149

154};

155

156

157

158

159

160

161

163{

168};

169

170

171

172

173#define JSON_NUM_TERMINALS 13

174#define JSON_NUM_NONTERMINALS 5

175#define JSON_NT_OFFSET JSON_NT_JSON

176

177#define OFS(NT) (NT) - JSON_NT_OFFSET

178

179#define IS_SEM(x) ((x) & 0x40)

180#define IS_NT(x) ((x) & 0x20)

181

182

183

184

185

187

188

190

191

193

194

196

197

199

200

202

203

205

206

208

209

211

212

214

215

217

218

220

221

222

223

224

225

226

227

228

229

230

231

232

233typedef struct

234{

238

239#define TD_ENTRY(PROD) { sizeof(PROD) - 1, (PROD) }

240

242{

243

251

260

263

266

269};

270

271

273

276 bool *num_err, size_t *total_len);

285

286

288{

289 NULL, NULL, NULL, NULL, NULL,

290 NULL, NULL, NULL, NULL, NULL

291};

292

293

296

297

298

299

300

301

302

303

306{

308}

309

310

311

312

313

314

315

318{

321 else

323}

324

325

326#define JSON_ALPHANUMERIC_CHAR(c) \

327 (((c) >= 'a' && (c) <= 'z') || \

328 ((c) >= 'A' && (c) <= 'Z') || \

329 ((c) >= '0' && (c) <= '9') || \

330 (c) == '_' || \

331 IS_HIGHBIT_SET(c))

332

333

334

335

336

337

338bool

340{

341 bool numeric_error;

342 size_t total_len;

344

345 if (len <= 0)

346 return false;

347

348

349

350

351

352

353

354 if (*str == '-')

355 {

358 }

359 else

360 {

363 }

364

366

368

369 return (!numeric_error) && (total_len == dummy_lex.input_length);

370}

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

393 size_t len, int encoding, bool need_escapes)

394{

395 if (lex == NULL)

396 {

398 if (!lex)

401 }

402 else

404

411 if (need_escapes)

412 {

413

414

415

416

417

420 }

421

422 return lex;

423}

424

425

426

427

428

429#define JS_STACK_CHUNK_SIZE 64

430#define JS_MAX_PROD_LEN 10

431#define JSON_TD_MAX_STACK 6400

432

433static bool

435{

436 void *pstack,

437 *prediction,

438 *fnames,

439 *fnull;

440

446

447#ifdef JSONAPI_USE_PQEXPBUFFER

449 || !pstack

450 || !prediction

451 || !fnames

452 || !fnull)

453 {

455 FREE(pstack);

456 FREE(prediction);

457 FREE(fnames);

459

461 return false;

462 }

463#endif

464

466 lex->pstack = pstack;

471

472

473

474

475

476

479

481 return true;

482}

483

484

485

486

487

488

489

490

491

492

493

494

495

496

499 bool need_escapes)

500{

501 if (lex == NULL)

502 {

504 if (!lex)

506

508 }

509 else

511

514

516 {

518 {

521 }

522

523

524 return lex;

525 }

526

528 if (need_escapes)

529 {

530

531

532

533

534

537 }

538

539 return lex;

540}

541

544{

546 {

547

548

549

550

552 return;

553 }

554

555 if (owned_by_context)

557 else

558 lex->flags &= ~JSONLEX_CTX_OWNS_TOKENS;

559}

560

561static inline bool

563{

565 {

566 size_t new_stack_size;

567 char *new_prediction;

568 char **new_fnames;

569 bool *new_fnull;

570

572

575#ifdef JSONAPI_USE_PQEXPBUFFER

576 if (!new_prediction)

577 return false;

578#endif

580

582 new_stack_size * sizeof(char *));

583#ifdef JSONAPI_USE_PQEXPBUFFER

584 if (!new_fnames)

585 return false;

586#endif

588

589 new_fnull = REALLOC(lex->pstack->fnull, new_stack_size * sizeof(bool));

590#ifdef JSONAPI_USE_PQEXPBUFFER

591 if (!new_fnull)

592 return false;

593#endif

595

597 }

598

600

602 {

603

604

605

606

608 }

609

610 return true;

611}

612

613static inline void

615{

616 set_fname(lex, NULL);

618}

619

620static inline void

622{

625}

626

627static inline char

629{

632}

633

634static inline char

636{

639}

640

641static inline bool

643{

645}

646

647static inline void

649{

651 {

652

653

654

655

657 }

658

660}

661

662static inline char *

664{

666}

667

668static inline void

670{

672}

673

674static inline bool

676{

678}

679

680

681

682

683

684

685

686

689{

691

693 return;

694

697

700

702 {

706

708 {

709 int i;

710

711

714 }

715

720 }

721

724 else

725 *lex = empty;

726}

727

728

729

730

731

732

733

734

735

736

737

738

739

740

741

742

743

746{

747#ifdef FORCE_JSON_PSTACK

748

749

750

751

752

755

757

758#else

759

762

767

768

771 return result;

772

774

775

776 switch (tok)

777 {

780 break;

783 break;

784 default:

785 result = parse_scalar(lex, sem);

786 }

787

790

791 return result;

792#endif

793}

794

795

796

797

798

799

800

801

802

805{

807 int count;

809

812

813

814

815

816

817

819 copylex.need_escapes = false;

821

822 count = 0;

826 return result;

828 {

829 while (1)

830 {

831 count++;

834 return result;

836 break;

839 return result;

840 }

841 }

845 return result;

846

847 *elements = count;

849}

850

851

852

853

854

855

856

857

858

859

860

861

862

863

864

865

866

867

871 const char *json,

872 size_t len,

873 bool is_last)

874{

879

884

889

890

893 return result;

894

896

897

898

900 {

902

904 }

905

907 {

910

911

912

913

914 if (top == tok)

915 {

916

917

918

919

921 {

924 return result;

926 }

927 }

929 {

930

931

932

933

934

936 }

937 else if (IS_SEM(top))

938 {

939

940

941

942

943

944

945

946 switch (top)

947 {

949 {

951

954

955 if (ostart != NULL)

956 {

959 return result;

960 }

961

964 }

965 break;

967 {

969

971 if (oend != NULL)

972 {

975 return result;

976 }

977 }

978 break;

980 {

982

985

986 if (astart != NULL)

987 {

990 return result;

991 }

992

995 }

996 break;

998 {

1000

1002 if (aend != NULL)

1003 {

1006 return result;

1007 }

1008 }

1009 break;

1011 {

1012

1013

1014

1015

1016

1017 char *fname = NULL;

1020

1021 if ((ostart != NULL || oend != NULL) && lex->need_escapes)

1022 {

1024 if (fname == NULL)

1026 }

1028 }

1029 break;

1031 {

1032

1033

1034

1035

1038

1040

1041 if (ostart != NULL)

1042 {

1044

1045 result = (*ostart) (sem->semstate, fname, isnull);

1047 return result;

1048 }

1049 }

1050 break;

1052 {

1054

1055 if (oend != NULL)

1056 {

1059

1060 result = (*oend) (sem->semstate, fname, isnull);

1062 return result;

1063 }

1064 }

1065 break;

1067 {

1070

1072

1073 if (astart != NULL)

1074 {

1075 result = (*astart) (sem->semstate, isnull);

1077 return result;

1078 }

1079 }

1080 break;

1082 {

1084

1085 if (aend != NULL)

1086 {

1088

1089 result = (*aend) (sem->semstate, isnull);

1091 return result;

1092 }

1093 }

1094 break;

1096 {

1098

1100

1101 if (sfunc != NULL)

1102 {

1103

1104

1105

1106

1107

1108

1109

1110

1112 {

1114 {

1118 }

1119 }

1120 else

1121 {

1123

1127

1130 }

1132 }

1133 }

1134 break;

1136 {

1137

1138

1139

1140

1141

1142

1143

1145

1146 if (sfunc != NULL)

1147 {

1149

1150

1151

1152

1153

1154

1155

1159

1161 return result;

1162 }

1163 }

1164 break;

1165 default:

1166

1167 break;

1168 }

1169 }

1170 else

1171 {

1172

1173

1174

1175

1176

1177

1178

1179

1180 switch (top)

1181 {

1185 else

1186 {

1189 }

1190 break;

1199 break;

1203 break;

1207 break;

1212 else

1214 break;

1217 break;

1220 break;

1223 break;

1226 break;

1229 break;

1232 break;

1233 default:

1235 }

1237 }

1238 }

1239

1241}

1242

1243

1244

1245

1246

1247

1248

1249

1250

1251

1254{

1255 char *val = NULL;

1259

1260

1265

1266

1267 if (sfunc == NULL)

1269

1270

1272 {

1274 {

1276 if (val == NULL)

1278 }

1279 }

1280 else

1281 {

1283

1285 if (val == NULL)

1287

1290 }

1291

1292

1295 {

1297 return result;

1298 }

1299

1300

1301

1302

1303

1305

1308

1309 return result;

1310}

1311

1314{

1315

1316

1317

1318

1319

1320

1321 char *fname = NULL;

1324 bool isnull;

1327

1330 if ((ostart != NULL || oend != NULL) && lex->need_escapes)

1331 {

1332

1334 if (fname == NULL)

1336 }

1339 {

1340 FREE(fname);

1341 return result;

1342 }

1343

1346 {

1347 FREE(fname);

1348 return result;

1349 }

1350

1353

1354 if (ostart != NULL)

1355 {

1356 result = (*ostart) (sem->semstate, fname, isnull);

1358 goto ofield_cleanup;

1359 }

1360

1361 switch (tok)

1362 {

1365 break;

1368 break;

1369 default:

1371 }

1373 goto ofield_cleanup;

1374

1375 if (oend != NULL)

1376 {

1377 result = (*oend) (sem->semstate, fname, isnull);

1379 goto ofield_cleanup;

1380 }

1381

1382ofield_cleanup:

1384 FREE(fname);

1385 return result;

1386}

1387

1390{

1391

1392

1393

1394

1399

1400#ifndef FRONTEND

1401

1402

1403

1404

1405

1407#endif

1408

1409 if (ostart != NULL)

1410 {

1413 return result;

1414 }

1415

1416

1417

1418

1419

1420

1421

1423

1427 return result;

1428

1430 switch (tok)

1431 {

1435 {

1438 break;

1440 }

1441 break;

1443 break;

1444 default:

1445

1447 }

1449 return result;

1450

1453 return result;

1454

1456

1457 if (oend != NULL)

1458 {

1461 return result;

1462 }

1463

1465}

1466

1469{

1474 bool isnull;

1475

1477

1478 if (astart != NULL)

1479 {

1480 result = (*astart) (sem->semstate, isnull);

1482 return result;

1483 }

1484

1485

1486 switch (tok)

1487 {

1490 break;

1493 break;

1494 default:

1496 }

1497

1499 return result;

1500

1501 if (aend != NULL)

1502 {

1503 result = (*aend) (sem->semstate, isnull);

1505 return result;

1506 }

1507

1509}

1510

1513{

1514

1515

1516

1517

1521

1522#ifndef FRONTEND

1524#endif

1525

1526 if (astart != NULL)

1527 {

1530 return result;

1531 }

1532

1533

1534

1535

1536

1537

1538

1540

1543 {

1545

1547 {

1550 break;

1552 }

1553 }

1555 return result;

1556

1559 return result;

1560

1562

1563 if (aend != NULL)

1564 {

1567 return result;

1568 }

1569

1571}

1572

1573

1574

1575

1576

1577

1578

1579

1580

1581

1582

1583

1584

1585

1586

1587

1590{

1591 const char *s;

1594

1597

1599 {

1601 {

1602

1603

1604

1605

1609 }

1610

1611#ifdef JSONAPI_USE_PQEXPBUFFER

1612

1615#endif

1616 }

1617

1619

1621 {

1622

1623

1624

1625

1627 size_t added = 0;

1628 bool tok_done = false;

1631

1632 if (ptok->data[0] == '"')

1633 {

1634

1635

1636

1637

1638 int escapes = 0;

1639

1640 for (int i = ptok->len - 1; i > 0; i--)

1641 {

1642

1643 if (ptok->data[i] == '\\')

1644 escapes++;

1645 else

1646 break;

1647 }

1648

1650 {

1652

1654 added++;

1655 if (c == '"' && escapes % 2 == 0)

1656 {

1657 tok_done = true;

1658 break;

1659 }

1660 if (c == '\\')

1661 escapes++;

1662 else

1663 escapes = 0;

1664 }

1665 }

1666 else

1667 {

1668

1669 char c = ptok->data[0];

1670

1671 if (c == '-' || (c >= '0' && c <= '9'))

1672 {

1673

1674

1675 bool numend = false;

1676

1677 for (size_t i = 0; i < lex->input_length && !numend; i++)

1678 {

1679 char cc = lex->input[i];

1680

1681 switch (cc)

1682 {

1683 case '+':

1684 case '-':

1685 case 'e':

1686 case 'E':

1687 case '0':

1688 case '1':

1689 case '2':

1690 case '3':

1691 case '4':

1692 case '5':

1693 case '6':

1694 case '7':

1695 case '8':

1696 case '9':

1697 {

1699 added++;

1700 }

1701 break;

1702 default:

1703 numend = true;

1704 }

1705 }

1706 }

1707

1708

1709

1710

1711

1712

1714 {

1715 char cc = lex->input[i];

1716

1718 {

1720 added++;

1721 }

1722 else

1723 {

1724 tok_done = true;

1725 break;

1726 }

1727 }

1730 {

1731 tok_done = true;

1732 }

1733 }

1734

1735 if (!tok_done)

1736 {

1737

1739

1742

1743

1747 }

1748

1749

1750

1751

1752

1753 lex->input += added;

1755

1764

1765 partial_result = json_lex(&dummy_lex);

1766

1767

1768

1769

1770

1771

1772

1775

1776

1777

1778

1779

1781

1782

1783

1784

1785

1789 {

1790

1792 {

1795 }

1796

1798 }

1799 return partial_result;

1800

1801 }

1802

1803

1804 while (s < end && (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r'))

1805 {

1806 if (*s++ == '\n')

1807 {

1810 }

1811 }

1813

1814

1815 if (s >= end)

1816 {

1821 }

1822 else

1823 {

1824 switch (*s)

1825 {

1826

1827 case '{':

1831 break;

1832 case '}':

1836 break;

1837 case '[':

1841 break;

1842 case ']':

1846 break;

1847 case ',':

1851 break;

1852 case ':':

1856 break;

1857 case '"':

1858

1861 return result;

1863 break;

1864 case '-':

1865

1868 return result;

1870 break;

1871 case '0':

1872 case '1':

1873 case '2':

1874 case '3':

1875 case '4':

1876 case '5':

1877 case '6':

1878 case '7':

1879 case '8':

1880 case '9':

1881

1884 return result;

1886 break;

1887 default:

1888 {

1889 const char *p;

1890

1891

1892

1893

1894

1895

1896

1897

1898

1899

1901 ;

1902

1903

1904

1905

1906

1907

1908 if (p == s)

1909 {

1913 }

1914

1917 {

1920 }

1921

1922

1923

1924

1925

1926

1929 if (p - s == 4)

1930 {

1931 if (memcmp(s, "true", 4) == 0)

1933 else if (memcmp(s, "null", 4) == 0)

1935 else

1937 }

1938 else if (p - s == 5 && memcmp(s, "false", 5) == 0)

1940 else

1942 }

1943 }

1944 }

1945

1948 else

1950}

1951

1952

1953

1954

1955

1956

1957

1958

1959

1960

1961

1962

1965{

1966 const char *s;

1968 int hi_surrogate = -1;

1969

1970

1971#define FAIL_OR_INCOMPLETE_AT_CHAR_START(code) \

1972 do { \

1973 if (lex->incremental && !lex->inc_state->is_last_chunk) \

1974 { \

1975 jsonapi_appendBinaryStringInfo(&lex->inc_state->partial_token, \

1976 lex->token_start, \

1977 end - lex->token_start); \

1978 return JSON_INCOMPLETE; \

1979 } \

1980 lex->token_terminator = s; \

1981 return code; \

1982 } while (0)

1983#define FAIL_AT_CHAR_END(code) \

1984 do { \

1985 ptrdiff_t remaining = end - s; \

1986 int charlen; \

1987 charlen = pg_encoding_mblen_or_incomplete(lex->input_encoding, \

1988 s, remaining); \

1989 lex->token_terminator = (charlen <= remaining) ? s + charlen : end; \

1990 return code; \

1991 } while (0)

1992

1994 {

1995#ifdef JSONAPI_USE_PQEXPBUFFER

1996

1997 if (lex->strval == NULL)

1999#endif

2001 }

2002

2005 for (;;)

2006 {

2007 s++;

2008

2009 if (s >= end)

2011 else if (*s == '"')

2012 break;

2013 else if (*s == '\\')

2014 {

2015

2016 s++;

2017 if (s >= end)

2019 else if (*s == 'u')

2020 {

2021 int i;

2022 int ch = 0;

2023

2024 for (i = 1; i <= 4; i++)

2025 {

2026 s++;

2027 if (s >= end)

2029 else if (*s >= '0' && *s <= '9')

2030 ch = (ch * 16) + (*s - '0');

2031 else if (*s >= 'a' && *s <= 'f')

2032 ch = (ch * 16) + (*s - 'a') + 10;

2033 else if (*s >= 'A' && *s <= 'F')

2034 ch = (ch * 16) + (*s - 'A') + 10;

2035 else

2037 }

2039 {

2040

2041

2042

2044 {

2045 if (hi_surrogate != -1)

2047 hi_surrogate = ch;

2048 continue;

2049 }

2051 {

2052 if (hi_surrogate == -1)

2055 hi_surrogate = -1;

2056 }

2057

2058 if (hi_surrogate != -1)

2060

2061

2062

2063

2064

2065

2066 if (ch == 0)

2067 {

2068

2070 }

2071

2072

2073

2074

2075

2076

2077

2078#ifndef FRONTEND

2079 {

2081

2085 }

2086#else

2088 {

2089

2090 char utf8str[5];

2091 int utf8len;

2092

2094 utf8len = pg_utf_mblen((unsigned char *) utf8str);

2096 }

2097 else if (ch <= 0x007f)

2098 {

2099

2101 }

2102 else

2104#endif

2105 }

2106 }

2108 {

2109 if (hi_surrogate != -1)

2111

2112 switch (*s)

2113 {

2114 case '"':

2115 case '\\':

2116 case '/':

2118 break;

2119 case 'b':

2121 break;

2122 case 'f':

2124 break;

2125 case 'n':

2127 break;

2128 case 'r':

2130 break;

2131 case 't':

2133 break;

2134 default:

2135

2136

2137

2138

2139

2140

2143 }

2144 }

2145 else if (strchr("\"\\/bfnrt", *s) == NULL)

2146 {

2147

2148

2149

2150

2151

2152

2153

2156 }

2157 }

2158 else

2159 {

2160 const char *p = s;

2161

2162 if (hi_surrogate != -1)

2164

2165

2166

2167

2168

2169 while (p < end - sizeof(Vector8) &&

2174

2175 for (; p < end; p++)

2176 {

2177 if (*p == '\\' || *p == '"')

2178 break;

2179 else if ((unsigned char) *p <= 31)

2180 {

2181

2182

2183

2184

2185

2188 }

2189 }

2190

2193

2194

2195

2196

2197

2198 s = p - 1;

2199 }

2200 }

2201

2202 if (hi_surrogate != -1)

2203 {

2206 }

2207

2208#ifdef JSONAPI_USE_PQEXPBUFFER

2211#endif

2212

2213

2217

2218#undef FAIL_OR_INCOMPLETE_AT_CHAR_START

2219#undef FAIL_AT_CHAR_END

2220}

2221

2222

2223

2224

2225

2226

2227

2228

2229

2230

2231

2232

2233

2234

2235

2236

2237

2238

2239

2240

2241

2242

2243

2244

2245

2246

2247

2248

2249

2252 bool *num_err, size_t *total_len)

2253{

2254 bool error = false;

2256

2257

2258

2259

2260

2261 if (len < lex->input_length && *s == '0')

2262 {

2263 s++;

2265 }

2266 else if (len < lex->input_length && *s >= '1' && *s <= '9')

2267 {

2268 do

2269 {

2270 s++;

2272 } while (len < lex->input_length && *s >= '0' && *s <= '9');

2273 }

2274 else

2276

2277

2278 if (len < lex->input_length && *s == '.')

2279 {

2280 s++;

2284 else

2285 {

2286 do

2287 {

2288 s++;

2290 } while (len < lex->input_length && *s >= '0' && *s <= '9');

2291 }

2292 }

2293

2294

2295 if (len < lex->input_length && (*s == 'e' || *s == 'E'))

2296 {

2297 s++;

2299 if (len < lex->input_length && (*s == '+' || *s == '-'))

2300 {

2301 s++;

2303 }

2306 else

2307 {

2308 do

2309 {

2310 s++;

2312 } while (len < lex->input_length && *s >= '0' && *s <= '9');

2313 }

2314 }

2315

2316

2317

2318

2319

2320

2323

2324 if (total_len != NULL)

2325 *total_len = len;

2326

2329 {

2332 if (num_err != NULL)

2333 *num_err = error;

2334

2336 }

2337 else if (num_err != NULL)

2338 {

2339

2340 *num_err = error;

2341 }

2342 else

2343 {

2344

2347

2350 }

2351

2353}

2354

2355

2356

2357

2358

2359

2362{

2363

2366

2367

2368 switch (ctx)

2369 {

2388 }

2389

2390

2391

2392

2393

2395 return JSON_SUCCESS;

2396}

2397

2398

2399

2400

2401

2402

2403

2406{

2408 {

2409

2410 return _("out of memory");

2411 }

2412

2415 else

2417

2418

2419

2420

2421

2422#define json_token_error(lex, format) \

2423 jsonapi_appendStringInfo((lex)->errormsg, _(format), \

2424 (int) ((lex)->token_terminator - (lex)->token_start), \

2425 (lex)->token_start);

2426

2428 {

2431

2432 break;

2435 return _("Recursive descent parser cannot use incremental lexer.");

2436 else

2437 return _("Incremental parser requires incremental lexer.");

2439 return (_("JSON nested too deep, maximum permitted depth is 6400."));

2441 json_token_error(lex, "Escape sequence \"\\%.*s\" is invalid.");

2442 break;

2445 _("Character with value 0x%02x must be escaped."),

2447 break;

2449 json_token_error(lex, "Expected end of input, but found \"%.*s\".");

2450 break;

2452 json_token_error(lex, "Expected array element or \"]\", but found \"%.*s\".");

2453 break;

2455 json_token_error(lex, "Expected \",\" or \"]\", but found \"%.*s\".");

2456 break;

2458 json_token_error(lex, "Expected \":\", but found \"%.*s\".");

2459 break;

2461 json_token_error(lex, "Expected JSON value, but found \"%.*s\".");

2462 break;

2464 return _("The input string ended unexpectedly.");

2466 json_token_error(lex, "Expected string or \"}\", but found \"%.*s\".");

2467 break;

2469 json_token_error(lex, "Expected \",\" or \"}\", but found \"%.*s\".");

2470 break;

2472 json_token_error(lex, "Expected string, but found \"%.*s\".");

2473 break;

2476 break;

2478

2479 break;

2481 return _("\\u0000 cannot be converted to text.");

2483 return _("\"\\u\" must be followed by four hexadecimal digits.");

2485

2486 return _("Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8.");

2488

2489

2490

2491

2492

2493

2494#ifndef FRONTEND

2495 return psprintf(_("Unicode escape value could not be translated to the server's encoding %s."),

2497#else

2499 break;

2500#endif

2502 return _("Unicode high surrogate must not follow a high surrogate.");

2504 return _("Unicode low surrogate must follow a high surrogate.");

2506

2507 break;

2508 }

2509#undef json_token_error

2510

2511

2513 {

2514

2515

2516

2517

2518

2520 "unexpected json parse error type: %d",

2522 }

2523

2524#ifdef JSONAPI_USE_PQEXPBUFFER

2526 return _("out of memory while constructing error description");

2527#endif

2528

2530}

Assert(PointerIsAligned(start, uint64))

JsonParseErrorType pg_parse_json_incremental(JsonLexContext *lex, const JsonSemAction *sem, const char *json, size_t len, bool is_last)

#define JSON_TD_MAX_STACK

@ JSON_PARSE_OBJECT_LABEL

@ JSON_PARSE_OBJECT_START

@ JSON_PARSE_OBJECT_COMMA

JsonLexContext * makeJsonLexContextIncremental(JsonLexContext *lex, int encoding, bool need_escapes)

static void set_fnull(JsonLexContext *lex, bool fnull)

#define JSON_NUM_TERMINALS

static char JSON_PROD_MORE_KEY_PAIRS[]

bool IsValidJsonNumber(const char *str, size_t len)

#define jsonapi_destroyStringInfo

static JsonParseErrorType json_lex_string(JsonLexContext *lex)

#define JSON_ALPHANUMERIC_CHAR(c)

static char JSON_PROD_KEY_PAIRS[]

#define JSON_NUM_NONTERMINALS

static char JSON_PROD_SCALAR_STRING[]

JsonParseErrorType pg_parse_json(JsonLexContext *lex, const JsonSemAction *sem)

static bool inc_lex_level(JsonLexContext *lex)

static char JSON_PROD_ARRAY_ELEMENTS[]

static bool have_prediction(JsonParserStack *pstack)

static void set_fname(JsonLexContext *lex, char *fname)

static char JSON_PROD_SCALAR_NUMBER[]

#define json_token_error(lex, format)

static char next_prediction(JsonParserStack *pstack)

static void push_prediction(JsonParserStack *pstack, td_entry entry)

static JsonLexContext failed_oom

#define jsonapi_appendStringInfoCharMacro

static char * get_fname(JsonLexContext *lex)

static char JSON_PROD_GOAL[]

#define jsonapi_makeStringInfo

static JsonTokenType lex_peek(JsonLexContext *lex)

static char JSON_PROD_EPSILON[]

static JsonParseErrorType parse_object(JsonLexContext *lex, const JsonSemAction *sem)

#define jsonapi_initStringInfo

JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json, size_t len, int encoding, bool need_escapes)

#define JS_STACK_CHUNK_SIZE

void setJsonLexContextOwnsTokens(JsonLexContext *lex, bool owned_by_context)

static char JSON_PROD_SCALAR_NULL[]

static bool allocate_incremental_state(JsonLexContext *lex)

#define jsonapi_resetStringInfo

static JsonParseErrorType report_parse_error(JsonParseContext ctx, JsonLexContext *lex)

static JsonParseErrorType lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)

static JsonIncrementalState failed_inc_oom

static JsonParseErrorType json_lex_number(JsonLexContext *lex, const char *s, bool *num_err, size_t *total_len)

static char JSON_PROD_MORE_ARRAY_ELEMENTS[]

const JsonSemAction nullSemAction

static td_entry td_parser_table[JSON_NUM_NONTERMINALS][JSON_NUM_TERMINALS]

static JsonParseErrorType parse_scalar(JsonLexContext *lex, const JsonSemAction *sem)

static char pop_prediction(JsonParserStack *pstack)

static JsonParseErrorType parse_object_field(JsonLexContext *lex, const JsonSemAction *sem)

#define jsonapi_termStringInfo(s)

#define jsonapi_appendBinaryStringInfo

static char JSON_PROD_SCALAR_FALSE[]

static bool get_fnull(JsonLexContext *lex)

JsonParseErrorType json_lex(JsonLexContext *lex)

#define jsonapi_appendStringInfoChar

static char JSON_PROD_OBJECT[]

#define jsonapi_appendStringInfo

char * json_errdetail(JsonParseErrorType error, JsonLexContext *lex)

JsonParseErrorType json_count_array_elements(JsonLexContext *lex, int *elements)

static JsonParseErrorType parse_array(JsonLexContext *lex, const JsonSemAction *sem)

static JsonParseErrorType parse_array_element(JsonLexContext *lex, const JsonSemAction *sem)

void freeJsonLexContext(JsonLexContext *lex)

@ JSON_NT_MORE_ARRAY_ELEMENTS

static char JSON_PROD_ARRAY[]

#define FAIL_OR_INCOMPLETE_AT_CHAR_START(code)

static char JSON_PROD_SCALAR_TRUE[]

#define FAIL_AT_CHAR_END(code)

static void dec_lex_level(JsonLexContext *lex)

JsonParseErrorType(* json_struct_action)(void *state)

JsonParseErrorType(* json_aelem_action)(void *state, bool isnull)

#define JSONLEX_FREE_STRVAL

#define jsonapi_StrValType

@ JSON_EXPECTED_ARRAY_FIRST

@ JSON_UNICODE_HIGH_SURROGATE

@ JSON_EXPECTED_OBJECT_FIRST

@ JSON_UNICODE_CODE_POINT_ZERO

@ JSON_INVALID_LEXER_TYPE

@ JSON_UNICODE_ESCAPE_FORMAT

@ JSON_UNICODE_UNTRANSLATABLE

@ JSON_EXPECTED_OBJECT_NEXT

@ JSON_EXPECTED_ARRAY_NEXT

@ JSON_UNICODE_HIGH_ESCAPE

@ JSON_UNICODE_LOW_SURROGATE

JsonParseErrorType(* json_ofield_action)(void *state, char *fname, bool isnull)

#define JSONLEX_FREE_STRUCT

@ JSON_TOKEN_OBJECT_START

#define JSONLEX_CTX_OWNS_TOKENS

JsonParseErrorType(* json_scalar_action)(void *state, char *token, JsonTokenType tokentype)

bool pg_unicode_to_server_noerror(pg_wchar c, unsigned char *s)

const char * GetDatabaseEncodingName(void)

static bool pg_lfind8_le(uint8 key, uint8 *base, uint32 nelem)

static bool pg_lfind8(uint8 key, uint8 *base, uint32 nelem)

static unsigned char * unicode_to_utf8(pg_wchar c, unsigned char *utf8string)

#define MAX_UNICODE_EQUIVALENT_STRING

static pg_wchar surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)

static bool is_utf16_surrogate_first(pg_wchar c)

static bool is_utf16_surrogate_second(pg_wchar c)

#define PQExpBufferBroken(str)

#define PQExpBufferDataBroken(buf)

char * psprintf(const char *fmt,...)

void check_stack_depth(void)

void appendStringInfoString(StringInfo str, const char *s)

jsonapi_StrValType partial_token

const char * prev_token_terminator

struct jsonapi_StrValType * strval

struct jsonapi_StrValType * errormsg

JsonIncrementalState * inc_state

const char * token_terminator

json_struct_action array_end

json_struct_action object_start

json_ofield_action object_field_start

json_aelem_action array_element_start

json_scalar_action scalar

json_aelem_action array_element_end

json_struct_action array_start

json_struct_action object_end

json_ofield_action object_field_end