PostgreSQL Source Code: src/backend/utils/adt/jsonfuncs.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

16

17#include <limits.h>

18

33#include "utils/fmgroids.h"

42

43

44#define JB_PATH_CREATE 0x0001

45#define JB_PATH_DELETE 0x0002

46#define JB_PATH_REPLACE 0x0004

47#define JB_PATH_INSERT_BEFORE 0x0008

48#define JB_PATH_INSERT_AFTER 0x0010

49#define JB_PATH_CREATE_OR_INSERT \

50 (JB_PATH_INSERT_BEFORE | JB_PATH_INSERT_AFTER | JB_PATH_CREATE)

51#define JB_PATH_FILL_GAPS 0x0020

52#define JB_PATH_CONSISTENT_POSITION 0x0040

53

54

56{

63

64

66{

69

70 void *action_state;

71 uint32 flags;

72

74

75

77{

81

82 void *action_state;

84

85

87{

93 int npath;

94 char **path_names;

96 bool *pathok;

98

100

101

103{

107

108

110{

120

121

123{

134

135

137{

145

146

148{

153

154

156{

160

161

164

165

167{

172

173

175{

176

177

178

179

182

185

186 void *domain_info;

188

189

191{

195 void *domain_info;

197

198

200{

207

208

209

210

212{

217

218 union

219 {

223 } io;

224

225};

226

227

229{

234};

235

236

238{

239 Oid argtype;

240 ColumnIOData c;

243

244

246{

257

258

260{

265 const char *colname;

266 int *dims;

267 int *sizes;

268 int ndims;

271

272

274{

277 const char *element_start;

279

282

283

285{

291

292

294{

296 union

297 {

298 struct

299 {

300 const char *str;

301 int len;

304

308

310{

312 union

313 {

318

319

320#define JsValueIsNull(jsv) \

321 ((jsv)->is_json ? \

322 (!(jsv)->val.json.str || (jsv)->val.json.type == JSON_TOKEN_NULL) : \

323 (!(jsv)->val.jsonb || (jsv)->val.jsonb->type == jbvNull))

324

325#define JsValueIsString(jsv) \

326 ((jsv)->is_json ? (jsv)->val.json.type == JSON_TOKEN_STRING \

327 : ((jsv)->val.jsonb && (jsv)->val.jsonb->type == jbvString))

328

329#define JsObjectIsEmpty(jso) \

330 ((jso)->is_json \

331 ? hash_get_num_entries((jso)->val.json_hash) == 0 \

332 : ((jso)->val.jsonb_cont == NULL || \

333 JsonContainerSize((jso)->val.jsonb_cont) == 0))

334

335#define JsObjectFree(jso) \

336 do { \

337 if ((jso)->is_json) \

338 hash_destroy((jso)->val.json_hash); \

339 } while (0)

340

342

343

347

348

358

359

361static text *get_worker(text *json, char **tpath, int *ipath, int npath,

362 bool normalize_results);

365

366

370

371

374 bool as_text);

375

376

381

382

384 bool as_text);

386 bool as_text);

387

388

393

394

396 Node *escontext);

397

398

404

405

410

411

419

420

428

429

431 bool is_json, bool have_record_arg);

433 bool is_json, bool have_record_arg,

434 Node *escontext);

435

436

450 Node *escontext);

452 bool *isnull, Node *escontext, bool omit_quotes);

457 JsValue *jsv, bool *isnull, Node *escontext,

458 bool omit_scalar_quotes);

464 int ndim);

471 bool *isnull,

472 Node *escontext);

475 Node *escontext, bool omit_quotes);

476

477

481 const bool *path_nulls, int path_len,

483 int op_type);

485 const bool *path_nulls, int path_len, JsonbInState *st,

486 int level,

489 const bool *path_nulls, int path_len, JsonbInState *st,

490 int level,

492

493

496

497

505

506

507

508

509

510

511

512

513

514

515

516

517

518bool

520 Node *escontext)

521{

523

526 {

528 return false;

529 }

530 return true;

531}

532

533

534

535

536

537

538

541{

542

543

544

545

547

552 need_escapes);

553}

554

555

556

557

558

559

560

561

562

563

564

565

566

569{

572

574 {

577 bool skipNested = false;

581

584 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

585 errmsg("cannot call %s on a scalar",

586 "jsonb_object_keys")));

589 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

590 errmsg("cannot call %s on an array",

591 "jsonb_object_keys")));

592

595

597

599 state->result_count = 0;

600 state->sent_count = 0;

602

604

606 {

607 skipNested = true;

608

610 {

611 char *cstr;

612

613 cstr = palloc(v.val.string.len + 1 * sizeof(char));

614 memcpy(cstr, v.val.string.val, v.val.string.len);

615 cstr[v.val.string.len] = '\0';

616 state->result[state->result_count++] = cstr;

617 }

618 }

619

622 }

623

626

628 {

629 char *nxt = state->result[state->sent_count++];

630

632 }

633

635}

636

637

638

639

640void

642 Node *escontext)

643{

648 (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),

649 errmsg("unsupported Unicode escape sequence"),

653 {

654

656 elog(ERROR, "JSON semantic action function did not provide error information");

657 }

658 else

660 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

661 errmsg("invalid input syntax for type %s", "json"),

664}

665

666

667

668

669

670

671

672

673

674

675

676static int

678{

679 const char *context_start;

680 const char *context_end;

681 const char *line_start;

682 char *ctxt;

683 int ctxtlen;

684 const char *prefix;

685 const char *suffix;

686

687

689 context_start = line_start;

691 Assert(context_end >= context_start);

692

693

694 while (context_end - context_start >= 50)

695 {

696

698 context_start += pg_mblen(context_start);

699 else

700 context_start++;

701 }

702

703

704

705

706

707

708 if (context_start - line_start <= 3)

709 context_start = line_start;

710

711

712 ctxtlen = context_end - context_start;

713 ctxt = palloc(ctxtlen + 1);

714 memcpy(ctxt, context_start, ctxtlen);

715 ctxt[ctxtlen] = '\0';

716

717

718

719

720

721 prefix = (context_start > line_start) ? "..." : "";

724 *context_end != '\n' && *context_end != '\r') ? "..." : "";

725

726 return errcontext("JSON data, line %d: %s%s%s",

728}

729

730

733{

736

738 {

743

746

749

751 state->result_size = 256;

752 state->result_count = 0;

753 state->sent_count = 0;

755

760

761

763

764

767

770 }

771

774

776 {

777 char *nxt = state->result[state->sent_count++];

778

780 }

781

783}

784

787{

789

790

793

794

796 {

798 _state->result = (char **)

800 }

801

802

804

806}

807

810{

812

813

816 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

817 errmsg("cannot call %s on an array",

818 "json_object_keys")));

819

821}

822

825{

827

828

831 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

832 errmsg("cannot call %s on a scalar",

833 "json_object_keys")));

834

836}

837

838

839

840

841

842

843

844

847{

851 text *result;

852

853 result = get_worker(json, &fnamestr, NULL, 1, false);

854

855 if (result != NULL)

857 else

859}

860

863{

868

871

875 &vbuf);

876

877 if (v != NULL)

879

881}

882

885{

889 text *result;

890

891 result = get_worker(json, &fnamestr, NULL, 1, true);

892

893 if (result != NULL)

895 else

897}

898

901{

906

909

913 &vbuf);

914

917

919}

920

923{

926 text *result;

927

929

930 if (result != NULL)

932 else

934}

935

938{

942

945

946

948 {

950

953 else

955 }

956

958 if (v != NULL)

960

962}

963

966{

969 text *result;

970

972

973 if (result != NULL)

975 else

977}

978

981{

985

988

989

991 {

993

996 else

998 }

999

1001

1004

1006}

1007

1010{

1012}

1013

1016{

1018}

1019

1020

1021

1022

1025{

1028 text *result;

1029 Datum *pathtext;

1030 bool *pathnulls;

1031 int npath;

1032 char **tpath;

1033 int *ipath;

1034 int i;

1035

1036

1037

1038

1039

1040

1041

1042

1045

1047

1050

1051 for (i = 0; i < npath; i++)

1052 {

1055

1056

1057

1058

1059

1060

1061 if (*tpath[i] != '\0')

1062 {

1063 int ind;

1064 char *endptr;

1065

1066 errno = 0;

1068 if (endptr == tpath[i] || *endptr != '\0' || errno != 0)

1069 ipath[i] = INT_MIN;

1070 else

1071 ipath[i] = ind;

1072 }

1073 else

1074 ipath[i] = INT_MIN;

1075 }

1076

1077 result = get_worker(json, tpath, ipath, npath, as_text);

1078

1079 if (result != NULL)

1081 else

1083}

1084

1085

1086

1087

1088

1089

1090

1091

1092

1093

1094

1095

1096

1097

1098

1099

1100

1101

1102static text *

1104 char **tpath,

1105 int *ipath,

1106 int npath,

1107 bool normalize_results)

1108{

1111

1113

1115

1116

1117 state->normalize_results = normalize_results;

1118 state->npath = npath;

1119 state->path_names = tpath;

1120 state->path_indexes = ipath;

1123

1124 if (npath > 0)

1125 state->pathok[0] = true;

1126

1128

1129

1130

1131

1132

1134 if (npath == 0)

1135 {

1140 }

1141 if (tpath != NULL)

1142 {

1145 }

1146 if (ipath != NULL)

1147 {

1151 }

1152

1155

1156 return state->tresult;

1157}

1158

1161{

1164

1165 if (lex_level == 0 && _state->npath == 0)

1166 {

1167

1168

1169

1170

1171

1173 }

1174

1176}

1177

1180{

1183

1184 if (lex_level == 0 && _state->npath == 0)

1185 {

1186

1189

1191 }

1192

1194}

1195

1198{

1200 bool get_next = false;

1202

1203 if (lex_level <= _state->npath &&

1204 _state->pathok[lex_level - 1] &&

1206 _state->path_names[lex_level - 1] != NULL &&

1207 strcmp(fname, _state->path_names[lex_level - 1]) == 0)

1208 {

1209 if (lex_level < _state->npath)

1210 {

1211

1212 _state->pathok[lex_level] = true;

1213 }

1214 else

1215 {

1216

1217 get_next = true;

1218 }

1219 }

1220

1221 if (get_next)

1222 {

1223

1226

1229 {

1230

1232 }

1233 else

1234 {

1235

1237 }

1238 }

1239

1241}

1242

1245{

1247 bool get_last = false;

1249

1250

1251 if (lex_level <= _state->npath &&

1252 _state->pathok[lex_level - 1] &&

1254 _state->path_names[lex_level - 1] != NULL &&

1255 strcmp(fname, _state->path_names[lex_level - 1]) == 0)

1256 {

1257 if (lex_level < _state->npath)

1258 {

1259

1260 _state->pathok[lex_level] = false;

1261 }

1262 else

1263 {

1264

1265 get_last = true;

1266 }

1267 }

1268

1269

1270 if (get_last && _state->result_start != NULL)

1271 {

1272

1273

1274

1275

1276

1279 else

1280 {

1283

1285 }

1286

1287

1289 }

1290

1292}

1293

1296{

1299

1300 if (lex_level < _state->npath)

1301 {

1302

1304

1305

1308 {

1309

1311 int nelements;

1312

1316

1317 if (-_state->path_indexes[lex_level] <= nelements)

1318 _state->path_indexes[lex_level] += nelements;

1319 }

1320 }

1321 else if (lex_level == 0 && _state->npath == 0)

1322 {

1323

1324

1325

1326

1327

1329 }

1330

1332}

1333

1336{

1339

1340 if (lex_level == 0 && _state->npath == 0)

1341 {

1342

1345

1347 }

1348

1350}

1351

1354{

1356 bool get_next = false;

1358

1359

1360 if (lex_level <= _state->npath)

1362

1363 if (lex_level <= _state->npath &&

1364 _state->pathok[lex_level - 1] &&

1367 {

1368 if (lex_level < _state->npath)

1369 {

1370

1371 _state->pathok[lex_level] = true;

1372 }

1373 else

1374 {

1375

1376 get_next = true;

1377 }

1378 }

1379

1380

1381 if (get_next)

1382 {

1385

1388 {

1390 }

1391 else

1392 {

1394 }

1395 }

1396

1398}

1399

1402{

1404 bool get_last = false;

1406

1407

1408 if (lex_level <= _state->npath &&

1409 _state->pathok[lex_level - 1] &&

1412 {

1413 if (lex_level < _state->npath)

1414 {

1415

1416 _state->pathok[lex_level] = false;

1417 }

1418 else

1419 {

1420

1421 get_last = true;

1422 }

1423 }

1424

1425

1426 if (get_last && _state->result_start != NULL)

1427 {

1430 else

1431 {

1434

1436 }

1437

1439 }

1440

1442}

1443

1446{

1449

1450

1451 if (lex_level == 0 && _state->npath == 0)

1452 {

1454 {

1455

1457 }

1459 {

1461 }

1462 else

1463 {

1464

1465

1466

1467

1468

1471

1473 }

1474 }

1475

1477 {

1478

1480

1482 }

1483

1485}

1486

1489{

1491}

1492

1495{

1497}

1498

1501{

1504 Datum *pathtext;

1505 bool *pathnulls;

1506 bool isnull;

1507 int npath;

1509

1510

1511

1512

1513

1514

1515

1516

1519

1521

1523

1524 if (isnull)

1526 else

1528}

1529

1532{

1535 int i;

1536 bool have_object = false,

1537 have_array = false;

1538

1539 *isnull = false;

1540

1541

1543 have_object = true;

1545 have_array = true;

1546 else

1547 {

1549

1550 if (npath <= 0)

1552 }

1553

1554

1555

1556

1557

1558

1559

1560

1561

1562 if (npath <= 0 && jbvp == NULL)

1563 {

1564 if (as_text)

1565 {

1567 container,

1569 }

1570 else

1571 {

1572

1574 }

1575 }

1576

1577 for (i = 0; i < npath; i++)

1578 {

1579 if (have_object)

1580 {

1582

1586 NULL);

1587 }

1588 else if (have_array)

1589 {

1590 int lindex;

1593 char *endptr;

1594

1595 errno = 0;

1596 lindex = strtoint(indextext, &endptr, 10);

1597 if (endptr == indextext || *endptr != '\0' || errno != 0)

1598 {

1599 *isnull = true;

1601 }

1602

1603 if (lindex >= 0)

1604 {

1606 }

1607 else

1608 {

1609

1611

1612

1614 elog(ERROR, "not a jsonb array");

1615

1617

1618 if (lindex == INT_MIN || -lindex > nelements)

1619 {

1620 *isnull = true;

1622 }

1623 else

1624 index = nelements + lindex;

1625 }

1626

1628 }

1629 else

1630 {

1631

1632 *isnull = true;

1634 }

1635

1636 if (jbvp == NULL)

1637 {

1638 *isnull = true;

1640 }

1641 else if (i == npath - 1)

1642 break;

1643

1645 {

1646 container = jbvp->val.binary.data;

1650 }

1651 else

1652 {

1654 have_object = false;

1655 have_array = false;

1656 }

1657 }

1658

1659 if (as_text)

1660 {

1662 {

1663 *isnull = true;

1665 }

1666

1668 }

1669 else

1670 {

1672

1673

1675 }

1676}

1677

1681{

1684 bool *path_nulls = palloc0_array(bool, path_len);

1685

1688

1690

1694

1695 pfree(path_nulls);

1696

1698}

1699

1700static void

1702{

1704

1706

1707 while (num-- > 0)

1709}

1710

1711

1712

1713

1714

1715

1716

1717

1718

1719static void

1722{

1723

1724

1725

1726

1727

1728

1731

1732

1733

1734

1735

1736

1737 for (int i = level + 1; i < path_len; i++)

1738 {

1739 char *c,

1740 *badp;

1741 int lindex;

1742

1743 if (path_nulls[i])

1744 break;

1745

1746

1747

1748

1749

1751 errno = 0;

1752 lindex = strtoint(c, &badp, 10);

1753 if (badp == c || *badp != '\0' || errno != 0)

1754 {

1755

1757 newkey.val.string.val = c;

1758 newkey.val.string.len = strlen(c);

1759

1762

1764 }

1765 else

1766 {

1767

1769

1771

1773 }

1774 }

1775

1776

1777 if (tpath[(path_len - level) - 1] == jbvArray)

1779 else

1781

1782

1783

1784

1785

1786 for (int i = path_len - 1; i > level; i--)

1787 {

1788 if (path_nulls[i])

1789 break;

1790

1793 else

1795 }

1796}

1797

1798

1799

1800

1801static text *

1803{

1804 switch (v->type)

1805 {

1807 return NULL;

1808

1810 return v->val.boolean ?

1813

1816 v->val.string.len);

1817

1819 {

1821

1824

1826 }

1827

1829 {

1831

1834 v->val.binary.len);

1835

1837 }

1838

1839 default:

1840 elog(ERROR, "unrecognized jsonb type: %d", (int) v->type);

1841 return NULL;

1842 }

1843}

1844

1845

1846

1847

1850{

1855

1858

1859#if 0

1860 state->count = 0;

1861#endif

1862

1868

1870

1872}

1873

1876{

1878

1881 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1882 errmsg("cannot get array length of a scalar")));

1885 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1886 errmsg("cannot get array length of a non-array")));

1887

1889}

1890

1891

1892

1893

1894

1895

1898{

1900

1901

1904 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1905 errmsg("cannot get array length of a non-array")));

1906

1908}

1909

1912{

1914

1915

1918 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1919 errmsg("cannot get array length of a scalar")));

1920

1922}

1923

1926{

1928

1929

1931 _state->count++;

1932

1934}

1935

1936

1937

1938

1939

1940

1941

1942

1943

1944

1945

1948{

1950}

1951

1954{

1956}

1957

1960{

1962}

1963

1966{

1968}

1969

1972{

1976 tmp_cxt;

1977 bool skipNested = false;

1981

1984 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1985 errmsg("cannot call %s on a non-object",

1987

1990

1992 "jsonb_each temporary cxt",

1994

1996

1998 {

1999 skipNested = true;

2000

2002 {

2005 bool nulls[2] = {false, false};

2006

2007

2009

2011

2012

2013

2014

2015

2018

2020

2021 if (as_text)

2022 {

2024 {

2025

2026 nulls[1] = true;

2028 }

2029 else

2031 }

2032 else

2033 {

2034

2036

2038 }

2039

2041

2042

2045 }

2046 }

2047

2049

2051}

2052

2053

2056{

2062

2065

2067

2071

2077

2078 state->normalize_results = as_text;

2079 state->next_scalar = false;

2082 "json_each temporary cxt",

2084

2086

2089

2091}

2092

2093

2096{

2098

2099

2101 {

2102

2103

2104

2105

2106

2109 else

2111 }

2112

2114}

2115

2118{

2121 int len;

2125 bool nulls[2] = {false, false};

2126

2127

2130

2131

2133

2135

2137 {

2138 nulls[1] = true;

2140 }

2142 {

2145 }

2146 else

2147 {

2151 }

2152

2154

2156

2157

2160

2162}

2163

2166{

2168

2169

2172 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

2173 errmsg("cannot deconstruct an array as an object")));

2174

2176}

2177

2180{

2182

2183

2186 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

2187 errmsg("cannot deconstruct a scalar")));

2188

2189

2192

2194}

2195

2196

2197

2198

2199

2200

2201

2202

2203

2206{

2208}

2209

2212{

2214}

2215

2218 bool as_text)

2219{

2223 tmp_cxt;

2224 bool skipNested = false;

2228

2231 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

2232 errmsg("cannot extract elements from a scalar")));

2235 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

2236 errmsg("cannot extract elements from an object")));

2237

2239

2241

2243 "jsonb_array_elements temporary cxt",

2245

2247

2249 {

2250 skipNested = true;

2251

2253 {

2255 bool nulls[1] = {false};

2256

2257

2259

2260 if (as_text)

2261 {

2263 {

2264

2265 nulls[0] = true;

2267 }

2268 else

2270 }

2271 else

2272 {

2273

2275

2277 }

2278

2280

2281

2284 }

2285 }

2286

2288

2290}

2291

2294{

2295 return elements_worker(fcinfo, "json_array_elements", false);

2296}

2297

2300{

2301 return elements_worker(fcinfo, "json_array_elements_text", true);

2302}

2303

2306{

2312

2313

2315

2318

2323

2329

2331 state->normalize_results = as_text;

2332 state->next_scalar = false;

2333 state->lex = &lex;

2335 "json_array_elements temporary cxt",

2337

2339

2342

2344}

2345

2348{

2350

2351

2353 {

2354

2355

2356

2357

2358

2361 else

2363 }

2364

2366}

2367

2370{

2373 int len;

2377 bool nulls[1] = {false};

2378

2379

2382

2383

2385

2387 {

2388 nulls[0] = true;

2390 }

2392 {

2395 }

2396 else

2397 {

2401 }

2402

2404

2406

2407

2410

2412}

2413

2416{

2418

2419

2422 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

2423 errmsg("cannot call %s on a non-array",

2425

2427}

2428

2431{

2433

2434

2437 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

2438 errmsg("cannot call %s on a scalar",

2440

2441

2444

2446}

2447

2448

2449

2450

2451

2452

2453

2454

2455

2456

2457

2458

2459

2462{

2464 false, true, NULL);

2465}

2466

2467

2468

2469

2470

2471

2472

2475{

2477

2479 false, true, (Node *) &escontext);

2480

2482}

2483

2486{

2488 false, false, NULL);

2489}

2490

2493{

2495 true, true, NULL);

2496}

2497

2500{

2502 true, false, NULL);

2503}

2504

2505

2506static void

2508{

2509 if (ndim <= 0)

2510 {

2513 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

2514 errmsg("expected JSON array"),

2515 errhint("See the value of key \"%s\".", ctx->colname)));

2516 else

2518 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

2519 errmsg("expected JSON array")));

2520 return;

2521 }

2522 else

2523 {

2525 int i;

2526

2528

2529 Assert(ctx->ndims > 0 && ndim < ctx->ndims);

2530

2531 for (i = 0; i < ndim; i++)

2533

2536 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

2537 errmsg("expected JSON array"),

2538 errhint("See the array element %s of key \"%s\".",

2540 else

2542 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

2543 errmsg("expected JSON array"),

2544 errhint("See the array element %s.",

2545 indices.data)));

2546 return;

2547 }

2548}

2549

2550

2551

2552

2553

2554

2555

2556static bool

2558{

2559 int i;

2560

2562

2563 if (ndims <= 0)

2564 {

2566

2568 return false;

2569 }

2570

2571 ctx->ndims = ndims;

2574

2575 for (i = 0; i < ndims; i++)

2576 ctx->dims[i] = -1;

2577

2578 return true;

2579}

2580

2581

2582

2583

2584

2585

2586static bool

2588{

2589 int dim = ctx->sizes[ndim];

2590

2591 if (ctx->dims[ndim] == -1)

2592 ctx->dims[ndim] = dim;

2593 else if (ctx->dims[ndim] != dim)

2595 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

2596 errmsg("malformed JSON array"),

2597 errdetail("Multidimensional arrays must have "

2598 "sub-arrays with matching dimensions.")));

2599

2600

2601 ctx->sizes[ndim] = 0;

2602

2603

2604 if (ndim > 0)

2605 ctx->sizes[ndim - 1]++;

2606

2607 return true;

2608}

2609

2610

2611

2612

2613

2614static bool

2616{

2618 bool element_isnull;

2619

2620

2625 jsv, &element_isnull, ctx->escontext,

2626 false);

2627

2629 return false;

2630

2633

2635 ctx->sizes[ndim - 1]++;

2636

2637 return true;

2638}

2639

2640

2643{

2645 int ndim = state->lex->lex_level;

2646

2647 if (state->ctx->ndims <= 0)

2648 {

2651 }

2652 else if (ndim < state->ctx->ndims)

2653 {

2655

2658 }

2659

2661}

2662

2663

2666{

2669 int ndim = state->lex->lex_level;

2670

2671 if (ctx->ndims <= 0)

2672 {

2675 }

2676

2677 if (ndim < ctx->ndims)

2678 {

2679

2682 }

2683

2685}

2686

2687

2690{

2692 int ndim = state->lex->lex_level;

2693

2694 if (state->ctx->ndims <= 0 || ndim == state->ctx->ndims)

2695 {

2696

2697 state->element_start = state->lex->token_start;

2698 state->element_type = state->lex->token_type;

2699 state->element_scalar = NULL;

2700 }

2701

2703}

2704

2705

2708{

2711 int ndim = state->lex->lex_level;

2712

2714

2715 if (ndim == ctx->ndims)

2716 {

2718

2721

2722 if (isnull)

2723 {

2727 }

2728 else if (state->element_scalar)

2729 {

2731 jsv.val.json.len = -1;

2732 }

2733 else

2734 {

2737 state->element_start) * sizeof(char);

2738 }

2739

2740

2743 }

2744

2746}

2747

2748

2751{

2754 int ndim = state->lex->lex_level;

2755

2756 if (ctx->ndims <= 0)

2757 {

2760 }

2761 else if (ndim < ctx->ndims)

2762 {

2764

2767 }

2768

2769 if (ndim == ctx->ndims)

2770 {

2771

2773

2774 Assert(state->element_type == tokentype);

2775 }

2776

2778}

2779

2780

2781

2782

2783

2784

2785static bool

2787{

2790

2793 state.ctx = ctx;

2794

2795 memset(&sem, 0, sizeof(sem));

2802

2804 {

2805

2807 }

2808

2810

2812}

2813

2814

2815

2816

2817

2818

2819

2820

2821static bool

2823 JsonbValue *jbv,

2824 int ndim)

2825{

2831

2833

2834

2837 {

2839

2841 return false;

2842 }

2843

2845

2848

2850

2851

2852

2853

2854

2855

2856 if (ctx->ndims <= 0 &&

2861 {

2863 return false;

2864 }

2865

2868

2869

2871 {

2872

2873

2874

2875

2876 if (ctx->ndims > 0 && ndim >= ctx->ndims)

2877 {

2879 return false;

2880 }

2881 else

2882 {

2883

2885 return false;

2886

2887

2889

2891 return false;

2892 }

2893

2895 }

2896

2898

2899

2902

2903 return true;

2904}

2905

2906

2907

2908

2909

2910

2913 const char *colname,

2916 bool *isnull,

2917 Node *escontext)

2918{

2921 int *lbs;

2922 int i;

2923

2924 ctx.aio = aio;

2925 ctx.mcxt = mcxt;

2929 ctx.ndims = 0;

2930 ctx.dims = NULL;

2931 ctx.sizes = NULL;

2933

2935 {

2936

2940 {

2941 *isnull = true;

2942 return (Datum) 0;

2943 }

2944 }

2945 else

2946 {

2947

2949 {

2950 *isnull = true;

2951 return (Datum) 0;

2952 }

2954 }

2955

2957

2959

2960 for (i = 0; i < ctx.ndims; i++)

2961 lbs[i] = 1;

2962

2964 ctx.acxt, true);

2965

2969

2970 *isnull = false;

2971 return result;

2972}

2973

2974

2975

2976

2977

2978static bool

2980{

2982

2984 {

2985

2991 "populate_composite",

2992 escontext);

2994 }

2995 else

2996 {

2998

3001 {

3003 }

3004 else

3005 {

3006 bool is_scalar;

3007

3012 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

3013 is_scalar

3014 ? errmsg("cannot call %s on a scalar",

3015 "populate_composite")

3016 : errmsg("cannot call %s on an array",

3017 "populate_composite")));

3018 }

3019 }

3020

3022}

3023

3024

3025static void

3027{

3031 {

3035

3038

3039

3043

3045 }

3046}

3047

3048

3049

3050

3051

3052

3053

3056 Oid typid,

3057 const char *colname,

3061 bool *isnull,

3062 Node *escontext)

3063{

3065

3066

3068

3069 if (*isnull)

3070 result = (Datum) 0;

3071 else

3072 {

3075

3076

3078 {

3079 *isnull = true;

3080 return (Datum) 0;

3081 }

3082

3083

3085 defaultval, mcxt, &jso, escontext);

3086

3088 {

3089 *isnull = true;

3090 return (Datum) 0;

3091 }

3093

3095 }

3096

3097

3098

3099

3100

3101

3102 if (typid != io->base_typid && typid != RECORDOID)

3103 {

3105 escontext))

3106 {

3107 *isnull = true;

3108 return (Datum) 0;

3109 }

3110 }

3111

3112 return result;

3113}

3114

3115

3116

3117

3118

3119

3120

3123 bool *isnull, Node *escontext, bool omit_quotes)

3124{

3126 char *str = NULL;

3127 const char *json = NULL;

3128

3130 {

3132

3135

3136

3137 if ((typid == JSONOID || typid == JSONBOID) &&

3139 {

3141

3143 if (len >= 0)

3145 else

3148 }

3149 else if (len >= 0)

3150 {

3151

3153 memcpy(str, json, len);

3155 }

3156 else

3157 {

3158

3160 }

3161 }

3162 else

3163 {

3165

3168 else if (typid == JSONBOID)

3169 {

3171

3173 }

3174

3175 else if (typid == JSONOID && jbv->type != jbvBinary)

3176 {

3177

3178

3179

3180

3182

3184 }

3185 else if (jbv->type == jbvString)

3188 str = pstrdup(jbv->val.boolean ? "true" : "false");

3194 jbv->val.binary.len);

3195 else

3196 elog(ERROR, "unrecognized jsonb type: %d", (int) jbv->type);

3197 }

3198

3200 escontext, &res))

3201 {

3202 res = (Datum) 0;

3203 *isnull = true;

3204 }

3205

3206

3207 if (str != json)

3209

3210 return res;

3211}

3212

3215 Oid typid,

3216 const char *colname,

3219 bool *isnull,

3220 Node *escontext,

3221 bool omit_quotes)

3222{

3224

3225 if (*isnull)

3226 res = (Datum) 0;

3227 else

3228 {

3232 jsv, isnull, escontext, omit_quotes);

3234 }

3235

3237 escontext))

3238 {

3239 *isnull = true;

3240 return (Datum) 0;

3241 }

3242

3243 return res;

3244}

3245

3246

3247static void

3249 Oid typid,

3252 bool need_scalar)

3253{

3256

3257 column->typid = typid;

3258 column->typmod = typmod;

3259

3262 elog(ERROR, "cache lookup failed for type %u", typid);

3263

3265

3266 if (type->typtype == TYPTYPE_DOMAIN)

3267 {

3268

3269

3270

3271

3272 Oid base_typid;

3273 int32 base_typmod = typmod;

3274

3276 if (get_typtype(base_typid) == TYPTYPE_COMPOSITE)

3277 {

3278

3285 }

3286 else

3287 {

3288

3295 }

3296 }

3297 else if (type->typtype == TYPTYPE_COMPOSITE || typid == RECORDOID)

3298 {

3305 }

3306 else if (IsTrueArrayType(type))

3307 {

3312

3314 }

3315 else

3316 {

3318 need_scalar = true;

3319 }

3320

3321

3322 if (need_scalar)

3323 {

3324 Oid typioproc;

3325

3328 }

3329

3331}

3332

3333

3334

3335

3336

3337

3338

3339

3340

3345 bool *isnull, bool omit_quotes,

3346 Node *escontext)

3347{

3350

3351 jsv.is_json = json_type == JSONOID;

3352

3353 if (*isnull)

3354 {

3357 else

3359 }

3361 {

3363

3367

3368 }

3369 else

3370 {

3372

3374

3375 if (omit_quotes)

3376 {

3378

3379

3381 jbv.val.string.len = strlen(str);

3382 jbv.val.string.val = str;

3383 }

3384 else

3385 {

3386

3388 jbv.val.binary.data = &jsonb->root;

3390 }

3391 }

3392

3393 if (*cache == NULL)

3395

3398 escontext, omit_quotes);

3399}

3400

3401

3404 Oid typid,

3406 const char *colname,

3408 Datum defaultval,

3410 bool *isnull,

3411 Node *escontext,

3412 bool omit_scalar_quotes)

3413{

3415

3417

3418

3419

3420

3421

3422 if (col->typid != typid || col->typmod != typmod)

3424

3426

3427 typcat = col->typcat;

3428

3429

3435

3436

3437 if (*isnull &&

3440 return (Datum) 0;

3441

3442 switch (typcat)

3443 {

3446 isnull, escontext, omit_scalar_quotes);

3447

3450 isnull, escontext);

3451

3455 colname, mcxt,

3458 : NULL,

3459 jsv, isnull,

3460 escontext);

3461

3464 jsv, isnull, escontext, omit_scalar_quotes);

3465

3466 default:

3467 elog(ERROR, "unrecognized type category '%c'", typcat);

3468 return (Datum) 0;

3469 }

3470}

3471

3474{

3479

3481 data->record_typmod = 0;

3482 data->ncolumns = ncolumns;

3484

3485 return data;

3486}

3487

3488static bool

3490{

3492

3494 {

3497

3500 hashentry->val;

3502

3503 return hashentry != NULL;

3504 }

3505 else

3506 {

3509 NULL);

3510

3511 return jsv->val.jsonb != NULL;

3512 }

3513}

3514

3515

3522 Node *escontext)

3523{

3526 bool *nulls;

3528 int ncolumns = tupdesc->natts;

3529 int i;

3530

3531

3532

3533

3534

3535

3537 return defaultval;

3538

3539

3540 if (record == NULL ||

3541 record->ncolumns != ncolumns)

3543

3544

3547 {

3552 record->ncolumns = ncolumns;

3553 }

3554

3556 nulls = (bool *) palloc(ncolumns * sizeof(bool));

3557

3558 if (defaultval)

3559 {

3561

3562

3566 tuple.t_data = defaultval;

3567

3568

3570 }

3571 else

3572 {

3573 for (i = 0; i < ncolumns; ++i)

3574 {

3576 nulls[i] = true;

3577 }

3578 }

3579

3580 for (i = 0; i < ncolumns; ++i)

3581 {

3583 char *colname = NameStr(att->attname);

3585 bool found;

3586

3587

3588 if (att->attisdropped)

3589 {

3590 nulls[i] = true;

3591 continue;

3592 }

3593

3595

3596

3597

3598

3599

3600

3601

3602

3603

3604 if (defaultval && !found)

3605 continue;

3606

3608 att->atttypid,

3609 att->atttypmod,

3610 colname,

3611 mcxt,

3613 &field,

3614 &nulls[i],

3615 escontext,

3616 false);

3617 }

3618

3620

3623

3625}

3626

3627

3628

3629

3630

3631

3632static void

3636{

3644 (errcode(ERRCODE_DATATYPE_MISMATCH),

3645

3646 errmsg("first argument of %s must be a row type",

3648}

3649

3650

3651

3652

3653

3654

3655

3656

3657

3658static void

3662{

3665

3668 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

3669

3670 errmsg("could not determine row type for result of %s",

3672 errhint("Provide a non-null record argument, "

3673 "or call the function in the FROM clause "

3674 "using a column definition list.")));

3675

3678

3679

3682

3683

3689}

3690

3691

3692

3693

3694

3697 bool is_json, bool have_record_arg,

3698 Node *escontext)

3699{

3700 int json_arg_num = have_record_arg ? 1 : 0;

3704 bool isnull;

3708

3709

3710

3711

3712

3713

3714 if (!cache)

3715 {

3718 cache->fn_mcxt = fnmcxt;

3719

3720 if (have_record_arg)

3722 else

3724 }

3725

3726

3727 if (!have_record_arg)

3728 rec = NULL;

3730 {

3732

3733

3734

3735

3736

3737 if (cache->argtype == RECORDOID)

3738 {

3741 }

3742 }

3743 else

3744 {

3745 rec = NULL;

3746

3747

3748

3749

3750

3751 if (cache->argtype == RECORDOID)

3752 {

3754

3756 }

3757 }

3758

3759

3761 {

3762 if (rec)

3764 else

3766 }

3767

3769

3770 if (is_json)

3771 {

3773

3777

3778 }

3779 else

3780 {

3782

3784

3785

3787 jbv.val.binary.data = &jb->root;

3789 }

3790

3791 isnull = false;

3793 NULL, fnmcxt, rec, &jsv, &isnull,

3794 escontext);

3796

3798}

3799

3800

3801

3802

3803

3804

3805

3806

3807static HTAB *

3809 Node *escontext)

3810{

3815

3819 tab = hash_create("json object hashtable",

3820 100,

3823

3826

3828 state->hash = tab;

3831

3837

3839 {

3841 tab = NULL;

3842 }

3843

3845

3846 return tab;

3847}

3848

3851{

3853

3856

3857

3859

3862 {

3863

3865 }

3866 else

3867 {

3868

3870 }

3871

3873}

3874

3877{

3880 bool found;

3881

3882

3883

3884

3887

3888

3889

3890

3891

3892

3893

3894

3897

3899

3900

3901

3902

3903

3904

3907

3909 {

3911 char *val = palloc((len + 1) * sizeof(char));

3912

3915 hashentry->val = val;

3916 }

3917 else

3918 {

3919

3921 }

3922

3924}

3925

3928{

3930

3933 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

3935

3937}

3938

3941{

3943

3946 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

3948

3950 {

3952

3954 }

3955

3957}

3958

3959

3960

3961

3962

3963

3964

3965

3966

3967

3968

3969

3972{

3974 false, true);

3975}

3976

3979{

3981 false, false);

3982}

3983

3986{

3988 true, true);

3989}

3990

3993{

3995 true, false);

3996}

3997

3998static void

4000{

4004

4005

4007

4008

4013 obj,

4014 NULL);

4015

4016

4022 NULL);

4023

4024

4028 tuple.t_data = tuphead;

4029

4031}

4032

4033

4034

4035

4036

4039 bool is_json, bool have_record_arg)

4040{

4041 int json_arg_num = have_record_arg ? 1 : 0;

4047

4049

4052 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

4053 errmsg("set-valued function called in context that cannot accept a set")));

4054

4057 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

4058 errmsg("materialize mode required, but it is not allowed in this context")));

4059

4061

4062

4063

4064

4065

4066

4067 if (!cache)

4068 {

4072

4073 if (have_record_arg)

4075 else

4077 }

4078

4079

4080 if (!have_record_arg)

4081 rec = NULL;

4083 {

4085

4086

4087

4088

4089

4090 if (cache->argtype == RECORDOID)

4091 {

4094 }

4095 }

4096 else

4097 {

4098 rec = NULL;

4099

4100

4101

4102

4103

4104 if (cache->argtype == RECORDOID)

4105 {

4107

4109 }

4110 }

4111

4112

4115

4116

4117

4118

4119

4121

4123

4124

4130

4132 state->cache = cache;

4133 state->rec = rec;

4134

4135 if (is_json)

4136 {

4140

4142

4144

4153

4154 state->lex = &lex;

4155

4157

4159 state->lex = NULL;

4160 }

4161 else

4162 {

4166 bool skipNested = false;

4168

4171 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4172 errmsg("cannot call %s on a non-array",

4174

4176

4178 {

4179 skipNested = true;

4180

4182 {

4184

4188 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4189 errmsg("argument of %s must be an array of objects",

4191

4194

4196 }

4197 }

4198 }

4199

4200

4201

4202

4203

4204

4207

4209}

4210

4213{

4217

4218

4219 if (lex_level == 0)

4221 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4222 errmsg("cannot call %s on an object",

4224

4225

4226 if (lex_level > 1)

4228

4229

4234 100,

4237

4239}

4240

4243{

4246

4247

4250

4253

4254

4256

4257

4260

4262}

4263

4266{

4268

4272 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4273 errmsg("argument of %s must be an array of objects",

4275

4277}

4278

4281{

4282

4284}

4285

4288{

4290

4293 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4294 errmsg("cannot call %s on a scalar",

4296

4299

4301}

4302

4305{

4307

4310

4312

4315 {

4317 }

4318 else

4319 {

4321 }

4322

4324}

4325

4328{

4331 bool found;

4332

4333

4334

4335

4338

4339

4340

4341

4342

4343

4344

4345

4348

4350

4351

4352

4353

4354

4355

4358

4360 {

4362 char *val = palloc((len + 1) * sizeof(char));

4363

4366 hashentry->val = val;

4367 }

4368 else

4369 {

4370

4372 }

4373

4375}

4376

4377

4378

4379

4380

4381

4382

4383

4384

4385

4388{

4390

4392

4394}

4395

4398{

4400

4402

4404}

4405

4408{

4410

4412

4414}

4415

4418{

4420

4422

4424}

4425

4428{

4430

4431 if (isnull)

4432 {

4433

4434

4435

4436

4437

4440 }

4441

4444

4445

4446

4447

4448

4450

4452

4454}

4455

4458{

4460

4461

4463 {

4466 }

4467

4468

4471 {

4473 }

4474

4476}

4477

4480{

4482

4484 {

4488 }

4489

4492 else

4494

4496}

4497

4498

4499

4500

4503{

4510

4514

4516 state->strval = &strbuf;

4517 state->skip_next_null = false;

4518 state->strip_in_arrays = strip_in_arrays;

4519

4528

4530

4532 state->strval->len));

4533}

4534

4535

4536

4537

4540{

4542 bool strip_in_arrays = false;

4546 k;

4548 bool last_was_key = false;

4549

4552

4555

4557

4559 {

4561

4563 {

4564

4565 k = v;

4566 last_was_key = true;

4567 continue;

4568 }

4569

4570 if (last_was_key)

4571 {

4572

4573 last_was_key = false;

4574

4575

4577 continue;

4578

4579

4581 }

4582

4583

4584 if (strip_in_arrays)

4586 continue;

4587

4590 else

4592 }

4593

4595}

4596

4597

4598

4599

4600

4601

4604{

4607

4610

4612}

4613

4614

4615

4616

4617

4618

4621{

4626 *it2;

4627

4628

4629

4630

4631

4632

4633

4635 {

4640 }

4641

4644

4646

4648}

4649

4650

4651

4652

4653

4654

4655

4656

4659{

4667 bool skipNested = false;

4669

4672 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4673 errmsg("cannot delete from scalar")));

4674

4677

4679

4681 {

4682 skipNested = true;

4683

4686 memcmp(keyptr, v.val.string.val, keylen) == 0))

4687 {

4688

4691

4692 continue;

4693 }

4694

4696 }

4697

4699}

4700

4701

4702

4703

4704

4705

4706

4709{

4712 Datum *keys_elems;

4713 bool *keys_nulls;

4714 int keys_len;

4718 bool skipNested = false;

4720

4723 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

4724 errmsg("wrong number of array subscripts")));

4725

4728 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4729 errmsg("cannot delete from scalar")));

4730

4733

4735

4736 if (keys_len == 0)

4738

4740

4742 {

4743 skipNested = true;

4744

4746 {

4747 int i;

4748 bool found = false;

4749

4750 for (i = 0; i < keys_len; i++)

4751 {

4752 char *keyptr;

4753 int keylen;

4754

4755 if (keys_nulls[i])

4756 continue;

4757

4758

4761 if (keylen == v.val.string.len &&

4762 memcmp(keyptr, v.val.string.val, keylen) == 0)

4763 {

4764 found = true;

4765 break;

4766 }

4767 }

4768 if (found)

4769 {

4770

4773

4774 continue;

4775 }

4776 }

4777

4779 }

4780

4782}

4783

4784

4785

4786

4787

4788

4789

4790

4793{

4799 n;

4802

4805 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4806 errmsg("cannot delete from scalar")));

4807

4810 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4811 errmsg("cannot delete from object using integer index")));

4812

4815

4817

4820 n = v.val.array.nElems;

4821

4822 if (idx < 0)

4823 {

4825 idx = n;

4826 else

4828 }

4829

4830 if (idx >= n)

4832

4834

4836 {

4838 {

4839 if (i++ == idx)

4840 continue;

4841 }

4842

4844 }

4845

4847}

4848

4849

4850

4851

4854{

4860 Datum *path_elems;

4861 bool *path_nulls;

4862 int path_len;

4865

4867

4870 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

4871 errmsg("wrong number of array subscripts")));

4872

4875 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4876 errmsg("cannot set path in scalar")));

4877

4880

4882

4883 if (path_len == 0)

4885

4887

4888 setPath(&it, path_elems, path_nulls, path_len, &st,

4890

4892}

4893

4894

4895

4896

4897

4900{

4901

4902

4903

4904

4905 text *handle_null;

4906 char *handle_val;

4907

4910

4911

4914 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4915 errmsg("null_value_treatment must be \"delete_key\", \"return_target\", \"use_json_null\", or \"raise_exception\"")));

4916

4917

4920

4923

4924 if (strcmp(handle_val, "raise_exception") == 0)

4925 {

4927 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

4928 errmsg("JSON value must not be null"),

4929 errdetail("Exception was raised because null_value_treatment is \"raise_exception\"."),

4930 errhint("To avoid, either change the null_value_treatment argument or ensure that an SQL NULL is not passed.")));

4931 return (Datum) 0;

4932 }

4933 else if (strcmp(handle_val, "use_json_null") == 0)

4934 {

4936

4938

4939 fcinfo->args[2].value = newval;

4940 fcinfo->args[2].isnull = false;

4942 }

4943 else if (strcmp(handle_val, "delete_key") == 0)

4944 {

4946 }

4947 else if (strcmp(handle_val, "return_target") == 0)

4948 {

4950

4952 }

4953 else

4954 {

4956 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4957 errmsg("null_value_treatment must be \"delete_key\", \"return_target\", \"use_json_null\", or \"raise_exception\"")));

4958 return (Datum) 0;

4959 }

4960}

4961

4962

4963

4964

4967{

4970 Datum *path_elems;

4971 bool *path_nulls;

4972 int path_len;

4975

4978 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

4979 errmsg("wrong number of array subscripts")));

4980

4983 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

4984 errmsg("cannot delete path in scalar")));

4985

4988

4990

4991 if (path_len == 0)

4993

4995

4996 setPath(&it, path_elems, path_nulls, path_len, &st,

4998

5000}

5001

5002

5003

5004

5007{

5013 Datum *path_elems;

5014 bool *path_nulls;

5015 int path_len;

5018

5020

5023 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

5024 errmsg("wrong number of array subscripts")));

5025

5028 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

5029 errmsg("cannot set path in scalar")));

5030

5032

5033 if (path_len == 0)

5035

5037

5038 setPath(&it, path_elems, path_nulls, path_len, &st, 0, &newval,

5040

5042}

5043

5044

5045

5046

5047

5048

5049

5050

5051static void

5054{

5056 v2;

5058 r2,

5059 rk1,

5060 rk2;

5061

5064

5065

5066

5067

5068

5070 {

5071

5072

5073

5074

5075

5076

5080

5081

5082

5083

5084

5085

5088 }

5090 {

5091

5092

5093

5095

5097 {

5100 }

5101

5103 {

5106 }

5107

5109 }

5111 {

5112

5113

5114

5116

5118

5122

5125 }

5126 else

5127 {

5128

5129

5130

5133

5135

5138

5142

5144 }

5145}

5146

5147

5148

5149

5150

5151

5152

5153

5154

5155

5156

5157

5158

5159

5160

5161

5162

5163

5164

5165

5166

5167

5168

5169

5170

5171

5172

5173

5174

5175

5176static void

5178 const bool *path_nulls, int path_len,

5180{

5183

5185

5186 if (path_nulls[level])

5188 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

5189 errmsg("path element at position %d is null",

5190 level + 1)));

5191

5193

5194 switch (r)

5195 {

5197

5198

5199

5200

5201

5202

5203

5205 v.val.array.rawScalar)

5207 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

5208 errmsg("cannot replace existing key"),

5209 errdetail("The path assumes key is a composite object, "

5210 "but it is a scalar value.")));

5211

5213 setPathArray(it, path_elems, path_nulls, path_len, st, level,

5214 newval, v.val.array.nElems, op_type);

5218 break;

5221 setPathObject(it, path_elems, path_nulls, path_len, st, level,

5222 newval, v.val.object.nPairs, op_type);

5226 break;

5229

5230

5231

5232

5233

5234

5235

5238 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

5239 errmsg("cannot replace existing key"),

5240 errdetail("The path assumes key is a composite object, "

5241 "but it is a scalar value.")));

5242

5244 break;

5245 default:

5246 elog(ERROR, "unrecognized iterator result: %d", (int) r);

5247 break;

5248 }

5249}

5250

5251

5252

5253

5254static void

5258{

5259 text *pathelem = NULL;

5260 int i;

5262 v;

5263 bool done = false;

5264

5265 if (level >= path_len || path_nulls[level])

5266 done = true;

5267 else

5268 {

5269

5271 }

5272

5273

5275 (level == path_len - 1))

5276 {

5278

5282

5285 }

5286

5287 for (i = 0; i < npairs; i++)

5288 {

5290

5292

5293 if (!done &&

5296 k.val.string.len) == 0)

5297 {

5298 done = true;

5299

5300 if (level == path_len - 1)

5301 {

5302

5303

5304

5305

5308 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

5309 errmsg("cannot replace existing key"),

5310 errhint("Try using the function jsonb_set "

5311 "to replace key value.")));

5312

5315 {

5318 }

5319 }

5320 else

5321 {

5323 setPath(it, path_elems, path_nulls, path_len,

5324 st, level + 1, newval, op_type);

5325 }

5326 }

5327 else

5328 {

5330 level == path_len - 1 && i == npairs - 1)

5331 {

5333

5337

5340 }

5341

5346 {

5347 int walking_level = 1;

5348

5349 while (walking_level != 0)

5350 {

5352

5354 ++walking_level;

5356 --walking_level;

5357

5359 }

5360 }

5361 }

5362 }

5363

5364

5365

5366

5367

5368

5369

5370

5371

5372

5373

5374 if (!done && (op_type & JB_PATH_FILL_GAPS) && (level < path_len - 1))

5375 {

5377

5381

5383 push_path(st, level, path_elems, path_nulls, path_len, newval);

5384

5385

5386 }

5387}

5388

5389

5390

5391

5392static void

5396{

5398 int idx,

5399 i;

5400 bool done = false;

5401

5402

5403 if (level < path_len && !path_nulls[level])

5404 {

5406 char *badp;

5407

5408 errno = 0;

5410 if (badp == c || *badp != '\0' || errno != 0)

5412 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

5413 errmsg("path element at position %d is not an integer: \"%s\"",

5414 level + 1, c)));

5415 }

5416 else

5417 idx = nelems;

5418

5419 if (idx < 0)

5420 {

5422 {

5423

5424

5425

5426

5429 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

5430 errmsg("path element at position %d is out of range: %d",

5431 level + 1, idx)));

5432 else

5434 }

5435 else

5437 }

5438

5439

5440

5441

5442

5444 {

5445 if (idx > 0 && idx > nelems)

5446 idx = nelems;

5447 }

5448

5449

5450

5451

5452

5453

5454 if ((idx == INT_MIN || nelems == 0) && (level == path_len - 1) &&

5456 {

5458

5461

5463

5464 done = true;

5465 }

5466

5467

5468 for (i = 0; i < nelems; i++)

5469 {

5471

5472 if (i == idx && level < path_len)

5473 {

5474 done = true;

5475

5476 if (level == path_len - 1)

5477 {

5479

5482

5483

5484

5485

5486

5487

5490

5493 }

5494 else

5495 setPath(it, path_elems, path_nulls, path_len,

5496 st, level + 1, newval, op_type);

5497 }

5498 else

5499 {

5501

5503

5505 {

5506 int walking_level = 1;

5507

5508 while (walking_level != 0)

5509 {

5511

5513 ++walking_level;

5515 --walking_level;

5516

5518 }

5519 }

5520 }

5521 }

5522

5524 {

5525

5526

5527

5528

5531

5533 done = true;

5534 }

5535

5536

5537

5538

5539

5540

5541

5542

5543

5544

5545

5546 if (!done && (op_type & JB_PATH_FILL_GAPS) && (level < path_len - 1))

5547 {

5548 if (idx > 0)

5550

5551 push_path(st, level, path_elems, path_nulls, path_len, newval);

5552

5553

5554 }

5555}

5556

5557

5558

5559

5560

5561

5564{

5569

5571

5573

5574

5575

5576

5577

5578

5581 errmsg("wrong flag type, only arrays and scalars are allowed")));

5582

5584 {

5587 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

5588 errmsg("flag array element is not a string"),

5589 errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\".")));

5590

5591 if (v.val.string.len == 3 &&

5594 else if (v.val.string.len == 3 &&

5597 else if (v.val.string.len == 6 &&

5600 else if (v.val.string.len == 7 &&

5603 else if (v.val.string.len == 7 &&

5606 else

5608 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

5609 errmsg("wrong flag in flag array: \"%s\"",

5611 errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\".")));

5612 }

5613

5614

5616 elog(ERROR, "unexpected end of flag array");

5617

5618

5621 elog(ERROR, "unexpected end of flag array");

5622

5623 return flags;

5624}

5625

5626

5627

5628

5629

5630void

5633{

5637

5639

5640

5641

5642

5643

5645 {

5647 {

5650

5651 continue;

5652 }

5654 {

5655

5656 continue;

5657 }

5658

5659

5660 switch (v.type)

5661 {

5665 break;

5668 {

5669 char *val;

5670

5673

5676 }

5677 break;

5680 {

5681 if (v.val.boolean)

5683 else

5685 }

5686 break;

5687 default:

5688

5689 break;

5690 }

5691 }

5692}

5693

5694

5695

5696

5697

5698void

5701{

5705

5708 state->action_state = action_state;

5709 state->flags = flags;

5710

5714

5717}

5718

5719

5720

5721

5722

5725{

5727

5728 switch (tokentype)

5729 {

5733 break;

5737 break;

5742 break;

5743 default:

5744

5745 break;

5746 }

5747

5749}

5750

5753{

5755

5757 {

5759

5761 }

5762

5764}

5765

5766

5767

5768

5769

5770

5771

5775{

5781 bool is_scalar = false;

5782

5785

5787 {

5789 {

5790 out = transform_action(action_state, v.val.string.val, v.val.string.len);

5791

5796 }

5797 else

5798 {

5802 }

5803 }

5804

5806 st.result->val.array.rawScalar = is_scalar;

5807

5809}

5810

5811

5812

5813

5814

5815

5816

5817

5821{

5826

5828

5830 state->strval = &strbuf;

5831 state->action = transform_action;

5832 state->action_state = action_state;

5833

5842

5845

5847}

5848

5849

5850

5851

5852

5853

5856{

5858

5860

5862}

5863

5866{

5868

5870

5872}

5873

5876{

5878

5880

5882}

5883

5886{

5888

5890

5892}

5893

5896{

5898

5901

5902

5903

5904

5905

5908

5910}

5911

5914{

5916

5919

5921}

5922

5925{

5927

5929 {

5931

5933 }

5934 else

5936

5938}

5939

5942{

5945

5947

5948

5950

5953

5954 if (throw_error)

5956

5958}

5959

5960

5961

5962

5963

5964

5965

5966

5967void

5970{

5971 bool typisvarlena;

5972

5973

5975

5977

5978 switch (typoid)

5979 {

5980 case BOOLOID:

5981 *outfuncoid = F_BOOLOUT;

5983 break;

5984

5985 case INT2OID:

5986 case INT4OID:

5987 case INT8OID:

5988 case FLOAT4OID:

5989 case FLOAT8OID:

5990 case NUMERICOID:

5993 break;

5994

5995 case DATEOID:

5996 *outfuncoid = F_DATE_OUT;

5998 break;

5999

6000 case TIMESTAMPOID:

6001 *outfuncoid = F_TIMESTAMP_OUT;

6003 break;

6004

6005 case TIMESTAMPTZOID:

6006 *outfuncoid = F_TIMESTAMPTZ_OUT;

6008 break;

6009

6010 case JSONOID:

6013 break;

6014

6015 case JSONBOID:

6018 break;

6019

6020 default:

6021

6023 || typoid == ANYCOMPATIBLEARRAYOID || typoid == RECORDARRAYOID)

6024 {

6025 *outfuncoid = F_ARRAY_OUT;

6027 }

6028 else if (type_is_rowtype(typoid))

6029 {

6030 *outfuncoid = F_RECORD_OUT;

6032 }

6033 else

6034 {

6035

6036

6037

6038

6039

6042 {

6043 Oid castfunc;

6045

6048 &castfunc);

6050 {

6051 *outfuncoid = castfunc;

6053 }

6054 else

6055 {

6056

6058 }

6059 }

6060 else

6061 {

6062

6064 }

6065 }

6066 break;

6067 }

6068}

Datum idx(PG_FUNCTION_ARGS)

#define PG_GETARG_ARRAYTYPE_P(n)

ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)

bool array_contains_nulls(const ArrayType *array)

Datum makeMdArrayResult(ArrayBuildState *astate, int ndims, int *dims, int *lbs, MemoryContext rcontext, bool release)

ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)

void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)

Datum numeric_out(PG_FUNCTION_ARGS)

static Datum values[MAXATTR]

#define CStringGetTextDatum(s)

#define TextDatumGetCString(d)

#define unconstify(underlying_type, expr)

#define IS_HIGHBIT_SET(ch)

#define FLEXIBLE_ARRAY_MEMBER

#define MemSet(start, val, len)

#define OidIsValid(objectId)

bool domain_check_safe(Datum value, bool isnull, Oid domainType, void **extra, MemoryContext mcxt, Node *escontext)

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)

void hash_destroy(HTAB *hashp)

int errdetail_internal(const char *fmt,...)

int errdetail(const char *fmt,...)

int errhint(const char *fmt,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereturn(context, dummy_value,...)

#define errsave(context,...)

#define ereport(elevel,...)

Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple)

@ SFRM_Materialize_Random

#define palloc_object(type)

#define palloc_array(type, count)

#define palloc0_array(type, count)

#define palloc0_object(type)

struct varlena * pg_detoast_datum_packed(struct varlena *datum)

void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)

bool InputFunctionCallSafe(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod, Node *escontext, Datum *result)

Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)

#define PG_GETARG_TEXT_PP(n)

#define DatumGetHeapTupleHeader(X)

#define DatumGetTextPP(X)

#define DirectFunctionCall1(func, arg1)

#define PG_GETARG_HEAPTUPLEHEADER(n)

#define PG_RETURN_TEXT_P(x)

#define PG_RETURN_INT32(x)

#define PG_GETARG_INT32(n)

#define PG_GETARG_BOOL(n)

#define PG_RETURN_DATUM(x)

#define PG_RETURN_POINTER(x)

#define PG_GETARG_TEXT_P(n)

void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)

TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)

#define SRF_IS_FIRSTCALL()

#define SRF_PERCALL_SETUP()

#define SRF_RETURN_NEXT(_funcctx, _result)

#define SRF_FIRSTCALL_INIT()

#define SRF_RETURN_DONE(_funcctx)

#define MAT_SRF_USE_EXPECTED_DESC

Assert(PointerIsAligned(start, uint64))

HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)

void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)

#define HeapTupleIsValid(tuple)

static int32 HeapTupleHeaderGetTypMod(const HeapTupleHeaderData *tup)

static uint32 HeapTupleHeaderGetDatumLength(const HeapTupleHeaderData *tup)

static void * GETSTRUCT(const HeapTupleData *tuple)

static Oid HeapTupleHeaderGetTypeId(const HeapTupleHeaderData *tup)

static uint32 pg_abs_s32(int32 a)

if(TABLE==NULL||TABLE_index==NULL)

static void ItemPointerSetInvalid(ItemPointerData *pointer)

void escape_json_text(StringInfo buf, const text *txt)

void escape_json_with_len(StringInfo buf, const char *str, int len)

void escape_json(StringInfo buf, const char *str)

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

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

JsonParseErrorType json_lex(JsonLexContext *lex)

char * json_errdetail(JsonParseErrorType error, JsonLexContext *lex)

JsonParseErrorType json_count_array_elements(JsonLexContext *lex, int *elements)

void freeJsonLexContext(JsonLexContext *lex)

@ JSON_UNICODE_CODE_POINT_ZERO

@ JSON_UNICODE_UNTRANSLATABLE

@ JSON_UNICODE_HIGH_ESCAPE

@ JSON_TOKEN_OBJECT_START

char * JsonbUnquote(Jsonb *jb)

Datum jsonb_in(PG_FUNCTION_ARGS)

char * JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)

char * JsonbToCStringIndent(StringInfo out, JsonbContainer *in, int estimated_len)

#define JsonContainerIsScalar(jc)

#define JsonContainerIsArray(jc)

#define JsonContainerSize(jc)

#define JB_ROOT_IS_OBJECT(jbp_)

static Datum JsonbPGetDatum(const Jsonb *p)

#define IsAJsonbScalar(jsonbval)

#define PG_RETURN_JSONB_P(x)

#define JB_ROOT_IS_ARRAY(jbp_)

#define PG_GETARG_JSONB_P(x)

#define JsonContainerIsObject(jc)

static Jsonb * DatumGetJsonbP(Datum d)

#define JB_ROOT_IS_SCALAR(jbp_)

#define JB_ROOT_COUNT(jbp_)

void pushJsonbValue(JsonbInState *pstate, JsonbIteratorToken seq, JsonbValue *jbval)

JsonbValue * getKeyJsonValueFromContainer(JsonbContainer *container, const char *keyVal, int keyLen, JsonbValue *res)

JsonbIterator * JsonbIteratorInit(JsonbContainer *container)

void JsonbToJsonbValue(Jsonb *jsonb, JsonbValue *val)

JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)

JsonbValue * getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)

Jsonb * JsonbValueToJsonb(JsonbValue *val)

Datum jsonb_populate_recordset(PG_FUNCTION_ARGS)

JsonLexContext * makeJsonLexContext(JsonLexContext *lex, text *json, bool need_escapes)

static JsonParseErrorType get_array_element_end(void *state, bool isnull)

static Datum elements_worker(FunctionCallInfo fcinfo, const char *funcname, bool as_text)

static JsonParseErrorType hash_array_start(void *state)

Datum jsonb_object_keys(PG_FUNCTION_ARGS)

static JsonParseErrorType populate_recordset_array_start(void *state)

static JsonParseErrorType transform_string_values_array_start(void *state)

static JsonParseErrorType get_object_field_start(void *state, char *fname, bool isnull)

static JsonParseErrorType elements_object_start(void *state)

static JsonParseErrorType transform_string_values_object_field_start(void *state, char *fname, bool isnull)

Datum jsonb_array_elements(PG_FUNCTION_ARGS)

static JsonParseErrorType iterate_values_object_field_start(void *state, char *fname, bool isnull)

struct PopulateArrayContext PopulateArrayContext

static void IteratorConcat(JsonbIterator **it1, JsonbIterator **it2, JsonbInState *state)

Datum json_each_text(PG_FUNCTION_ARGS)

static void push_path(JsonbInState *st, int level, const Datum *path_elems, const bool *path_nulls, int path_len, JsonbValue *newval)

Datum json_populate_recordset(PG_FUNCTION_ARGS)

static JsonParseErrorType populate_array_scalar(void *_state, char *token, JsonTokenType tokentype)

text * transform_json_string_values(text *json, void *action_state, JsonTransformStringValuesAction transform_action)

Datum jsonb_delete(PG_FUNCTION_ARGS)

struct TransformJsonStringValuesState TransformJsonStringValuesState

Datum json_populate_type(Datum json_val, Oid json_type, Oid typid, int32 typmod, void **cache, MemoryContext mcxt, bool *isnull, bool omit_quotes, Node *escontext)

Datum jsonb_delete_array(PG_FUNCTION_ARGS)

Datum jsonb_pretty(PG_FUNCTION_ARGS)

static void setPathArray(JsonbIterator **it, const Datum *path_elems, const bool *path_nulls, int path_len, JsonbInState *st, int level, JsonbValue *newval, uint32 nelems, int op_type)

struct DomainIOData DomainIOData

static JsonParseErrorType transform_string_values_array_end(void *state)

static JsonParseErrorType populate_recordset_object_start(void *state)

static RecordIOData * allocate_record_info(MemoryContext mcxt, int ncolumns)

static JsonParseErrorType iterate_values_scalar(void *state, char *token, JsonTokenType tokentype)

static text * JsonbValueAsText(JsonbValue *v)

Datum jsonb_insert(PG_FUNCTION_ARGS)

static JsonParseErrorType get_object_start(void *state)

static JsonParseErrorType populate_recordset_object_field_start(void *state, char *fname, bool isnull)

static JsonParseErrorType populate_recordset_object_field_end(void *state, char *fname, bool isnull)

static JsonParseErrorType populate_array_object_start(void *_state)

#define JsObjectIsEmpty(jso)

static void get_record_type_from_argument(FunctionCallInfo fcinfo, const char *funcname, PopulateRecordCache *cache)

Datum json_array_element(PG_FUNCTION_ARGS)

Datum jsonb_delete_idx(PG_FUNCTION_ARGS)

static JsonParseErrorType sn_object_end(void *state)

#define JB_PATH_CREATE_OR_INSERT

Datum jsonb_populate_record_valid(PG_FUNCTION_ARGS)

Datum json_array_elements_text(PG_FUNCTION_ARGS)

struct EachState EachState

static JsonParseErrorType hash_scalar(void *state, char *token, JsonTokenType tokentype)

static JsonParseErrorType sn_array_element_start(void *state, bool isnull)

static Datum populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, bool is_json, bool have_record_arg, Node *escontext)

static HTAB * get_json_object_as_hash(const char *json, int len, const char *funcname, Node *escontext)

static bool populate_array_json(PopulateArrayContext *ctx, const char *json, int len)

struct StripnullState StripnullState

struct IterateJsonStringValuesState IterateJsonStringValuesState

#define JsValueIsString(jsv)

static JsonParseErrorType populate_recordset_object_end(void *state)

static Datum populate_record_field(ColumnIOData *col, Oid typid, int32 typmod, const char *colname, MemoryContext mcxt, Datum defaultval, JsValue *jsv, bool *isnull, Node *escontext, bool omit_scalar_quotes)

Datum jsonb_delete_path(PG_FUNCTION_ARGS)

struct CompositeIOData CompositeIOData

static JsonParseErrorType each_object_field_end(void *state, char *fname, bool isnull)

Datum jsonb_object_field_text(PG_FUNCTION_ARGS)

static Datum each_worker(FunctionCallInfo fcinfo, bool as_text)

static JsonParseErrorType get_array_start(void *state)

static JsonParseErrorType each_scalar(void *state, char *token, JsonTokenType tokentype)

static int report_json_context(JsonLexContext *lex)

Datum json_strip_nulls(PG_FUNCTION_ARGS)

struct JsonHashEntry JsonHashEntry

Datum json_array_elements(PG_FUNCTION_ARGS)

Datum jsonb_concat(PG_FUNCTION_ARGS)

struct ArrayIOData ArrayIOData

static JsonParseErrorType okeys_array_start(void *state)

Datum json_object_field_text(PG_FUNCTION_ARGS)

uint32 parse_jsonb_index_flags(Jsonb *jb)

Datum jsonb_extract_path_text(PG_FUNCTION_ARGS)

Datum json_each(PG_FUNCTION_ARGS)

static JsonParseErrorType alen_scalar(void *state, char *token, JsonTokenType tokentype)

Datum jsonb_set_element(Jsonb *jb, const Datum *path, int path_len, JsonbValue *newval)

static JsonParseErrorType sn_object_start(void *state)

static JsonParseErrorType sn_array_start(void *state)

static bool populate_array_check_dimension(PopulateArrayContext *ctx, int ndim)

static Datum each_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, bool as_text)

static JsonParseErrorType sn_array_end(void *state)

static void setPathObject(JsonbIterator **it, const Datum *path_elems, const bool *path_nulls, int path_len, JsonbInState *st, int level, JsonbValue *newval, uint32 npairs, int op_type)

Datum json_to_recordset(PG_FUNCTION_ARGS)

static JsonParseErrorType get_scalar(void *state, char *token, JsonTokenType tokentype)

#define JB_PATH_CONSISTENT_POSITION

static bool populate_array_assign_ndims(PopulateArrayContext *ctx, int ndims)

JsonTokenType json_get_first_token(text *json, bool throw_error)

Datum jsonb_set(PG_FUNCTION_ARGS)

#define JsValueIsNull(jsv)

static void update_cached_tupdesc(CompositeIOData *io, MemoryContext mcxt)

struct ColumnIOData ColumnIOData

void iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state, JsonIterateStringValuesAction action)

static JsonParseErrorType populate_array_element_end(void *_state, bool isnull)

Datum jsonb_set_lax(PG_FUNCTION_ARGS)

static JsonParseErrorType elements_array_element_end(void *state, bool isnull)

static JsonParseErrorType sn_object_field_start(void *state, char *fname, bool isnull)

Datum jsonb_each_text(PG_FUNCTION_ARGS)

static JsonParseErrorType elements_scalar(void *state, char *token, JsonTokenType tokentype)

struct ScalarIOData ScalarIOData

static JsonParseErrorType each_object_field_start(void *state, char *fname, bool isnull)

Datum jsonb_strip_nulls(PG_FUNCTION_ARGS)

struct OkeysState OkeysState

struct PopulateArrayState PopulateArrayState

struct PopulateRecordCache PopulateRecordCache

Datum jsonb_extract_path(PG_FUNCTION_ARGS)

void json_categorize_type(Oid typoid, bool is_jsonb, JsonTypeCategory *tcategory, Oid *outfuncoid)

static Datum populate_array(ArrayIOData *aio, const char *colname, MemoryContext mcxt, JsValue *jsv, bool *isnull, Node *escontext)

static JsonParseErrorType okeys_object_field_start(void *state, char *fname, bool isnull)

Datum jsonb_get_element(Jsonb *jb, const Datum *path, int npath, bool *isnull, bool as_text)

Datum json_array_length(PG_FUNCTION_ARGS)

struct JHashState JHashState

void json_errsave_error(JsonParseErrorType error, JsonLexContext *lex, Node *escontext)

struct ElementsState ElementsState

Datum jsonb_array_length(PG_FUNCTION_ARGS)

Datum jsonb_object_field(PG_FUNCTION_ARGS)

static Datum elements_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, bool as_text)

void iterate_json_values(text *json, uint32 flags, void *action_state, JsonIterateStringValuesAction action)

Datum jsonb_populate_record(PG_FUNCTION_ARGS)

Datum json_extract_path(PG_FUNCTION_ARGS)

static void push_null_elements(JsonbInState *ps, int num)

Datum json_extract_path_text(PG_FUNCTION_ARGS)

static JsonParseErrorType elements_array_element_start(void *state, bool isnull)

static void get_record_type_from_query(FunctionCallInfo fcinfo, const char *funcname, PopulateRecordCache *cache)

Datum json_populate_record(PG_FUNCTION_ARGS)

static JsonParseErrorType populate_recordset_array_element_start(void *state, bool isnull)

#define JB_PATH_FILL_GAPS

Jsonb * transform_jsonb_string_values(Jsonb *jsonb, void *action_state, JsonTransformStringValuesAction transform_action)

static JsonParseErrorType transform_string_values_object_end(void *state)

static bool JsValueToJsObject(JsValue *jsv, JsObject *jso, Node *escontext)

Datum json_object_field(PG_FUNCTION_ARGS)

static JsonParseErrorType okeys_scalar(void *state, char *token, JsonTokenType tokentype)

static Datum get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)

static void populate_array_report_expected_array(PopulateArrayContext *ctx, int ndim)

static JsonParseErrorType get_object_end(void *state)

static Datum populate_composite(CompositeIOData *io, Oid typid, const char *colname, MemoryContext mcxt, HeapTupleHeader defaultval, JsValue *jsv, bool *isnull, Node *escontext)

Datum jsonb_to_record(PG_FUNCTION_ARGS)

Datum jsonb_array_element(PG_FUNCTION_ARGS)

Datum json_object_keys(PG_FUNCTION_ARGS)

struct AlenState AlenState

#define JB_PATH_INSERT_BEFORE

static JsonParseErrorType populate_recordset_scalar(void *state, char *token, JsonTokenType tokentype)

static JsonParseErrorType get_object_field_end(void *state, char *fname, bool isnull)

bool pg_parse_json_or_errsave(JsonLexContext *lex, const JsonSemAction *sem, Node *escontext)

static Datum get_path_all(FunctionCallInfo fcinfo, bool as_text)

static Datum populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, bool is_json, bool have_record_arg)

static HeapTupleHeader populate_record(TupleDesc tupdesc, RecordIOData **record_p, HeapTupleHeader defaultval, MemoryContext mcxt, JsObject *obj, Node *escontext)

static void setPath(JsonbIterator **it, const Datum *path_elems, const bool *path_nulls, int path_len, JsonbInState *st, int level, JsonbValue *newval, int op_type)

static JsonParseErrorType alen_object_start(void *state)

static bool JsObjectGetField(JsObject *obj, char *field, JsValue *jsv)

static bool populate_array_element(PopulateArrayContext *ctx, int ndim, JsValue *jsv)

static JsonParseErrorType populate_array_element_start(void *_state, bool isnull)

static JsonParseErrorType populate_array_array_end(void *_state)

static void prepare_column_cache(ColumnIOData *column, Oid typid, int32 typmod, MemoryContext mcxt, bool need_scalar)

static JsonParseErrorType get_array_end(void *state)

Datum jsonb_to_recordset(PG_FUNCTION_ARGS)

static JsonParseErrorType sn_scalar(void *state, char *token, JsonTokenType tokentype)

#define JB_PATH_INSERT_AFTER

Datum jsonb_each(PG_FUNCTION_ARGS)

static JsonParseErrorType get_array_element_start(void *state, bool isnull)

static JsonParseErrorType hash_object_field_end(void *state, char *fname, bool isnull)

static void populate_recordset_record(PopulateRecordsetState *state, JsObject *obj)

#define JsObjectFree(jso)

struct PopulateRecordsetState PopulateRecordsetState

static JsonParseErrorType transform_string_values_object_start(void *state)

static JsonParseErrorType transform_string_values_array_element_start(void *state, bool isnull)

static JsonParseErrorType alen_array_element_start(void *state, bool isnull)

static Datum populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv, bool *isnull, Node *escontext, bool omit_quotes)

static bool populate_array_dim_jsonb(PopulateArrayContext *ctx, JsonbValue *jbv, int ndim)

Datum jsonb_array_element_text(PG_FUNCTION_ARGS)

@ TYPECAT_COMPOSITE_DOMAIN

Datum json_to_record(PG_FUNCTION_ARGS)

static JsonParseErrorType each_array_start(void *state)

Datum json_array_element_text(PG_FUNCTION_ARGS)

static Datum populate_domain(DomainIOData *io, Oid typid, const char *colname, MemoryContext mcxt, JsValue *jsv, bool *isnull, Node *escontext, bool omit_quotes)

static JsonParseErrorType transform_string_values_scalar(void *state, char *token, JsonTokenType tokentype)

static JsonParseErrorType hash_object_field_start(void *state, char *fname, bool isnull)

Datum jsonb_array_elements_text(PG_FUNCTION_ARGS)

static text * get_worker(text *json, char **tpath, int *ipath, int npath, bool normalize_results)

#define pg_parse_json_or_ereport(lex, sem)

text *(* JsonTransformStringValuesAction)(void *state, char *elem_value, int elem_len)

void(* JsonIterateStringValuesAction)(void *state, char *elem_value, int elem_len)

Oid get_element_type(Oid typid)

bool type_is_rowtype(Oid typid)

void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)

void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)

char get_typtype(Oid typid)

Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)

Oid getBaseType(Oid typid)

int GetDatabaseEncoding(void)

int pg_mblen(const char *mbstr)

void * MemoryContextAlloc(MemoryContext context, Size size)

void MemoryContextReset(MemoryContext context)

void * MemoryContextAllocZero(MemoryContext context, Size size)

char * pstrdup(const char *in)

void * repalloc(void *pointer, Size size)

void pfree(void *pointer)

MemoryContext CurrentMemoryContext

char * pnstrdup(const char *in, Size len)

void MemoryContextDelete(MemoryContext context)

#define AllocSetContextCreate

#define ALLOCSET_DEFAULT_SIZES

#define SOFT_ERROR_OCCURRED(escontext)

#define IsA(nodeptr, _type_)

static Datum NumericGetDatum(Numeric X)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

CoercionPathType find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId, CoercionContext ccontext, Oid *funcid)

FormData_pg_attribute * Form_pg_attribute

static char buf[DEFAULT_XLOG_SEG_SIZE]

FormData_pg_type * Form_pg_type

int pg_strncasecmp(const char *s1, const char *s2, size_t n)

static Datum PointerGetDatum(const void *X)

static Datum BoolGetDatum(bool X)

static Datum ObjectIdGetDatum(Oid X)

static char * DatumGetCString(Datum X)

static Pointer DatumGetPointer(Datum X)

static Datum CStringGetDatum(const char *X)

static chr element(struct vars *v, const chr *startp, const chr *endp)

void check_stack_depth(void)

int strtoint(const char *restrict str, char **restrict endptr, int base)

void appendStringInfo(StringInfo str, const char *fmt,...)

void appendStringInfoString(StringInfo str, const char *s)

void initStringInfo(StringInfo str)

#define appendStringInfoCharMacro(str, ch)

ColumnIOData * element_info

CompositeIOData composite

union ColumnIOData::@26 io

const char * result_start

Tuplestorestate * tuple_store

Tuplestorestate * tuple_store

const char * function_name

const char * result_start

MemoryContext ecxt_per_query_memory

MemoryContext multi_call_memory_ctx

const char * result_start

JsonIterateStringValuesAction action

const char * save_json_start

const char * function_name

JsonTokenType saved_token_type

JsonbContainer * jsonb_cont

struct JsValue::@27::@28 json

const char * prev_token_terminator

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

JsonTokenType element_type

PopulateArrayContext * ctx

const char * element_start

const char * save_json_start

const char * function_name

Tuplestorestate * tuple_store

PopulateRecordCache * cache

JsonTokenType saved_token_type

ColumnIOData columns[FLEXIBLE_ARRAY_MEMBER]

SetFunctionReturnMode returnMode

Tuplestorestate * setResult

JsonTransformStringValuesAction action

void ReleaseSysCache(HeapTuple tuple)

HeapTuple SearchSysCache1(int cacheId, Datum key1)

#define FirstNormalObjectId

void FreeTupleDesc(TupleDesc tupdesc)

TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)

#define ReleaseTupleDesc(tupdesc)

static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)

Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)

void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)

void tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)

TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)

static Size VARSIZE_ANY_EXHDR(const void *PTR)

static Size VARSIZE(const void *PTR)

static char * VARDATA_ANY(const void *PTR)

text * cstring_to_text_with_len(const char *s, int len)

text * cstring_to_text(const char *s)

char * text_to_cstring(const text *t)