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 bool *path_nulls, int path_len,

483 int op_type);

486 int level,

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;

754 state->result = palloc(256 * sizeof(char *));

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

1048 tpath = palloc(npath * sizeof(char *));

1049 ipath = palloc(npath * sizeof(int));

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;

1121 state->pathok = palloc0(sizeof(bool) * npath);

1122 state->array_cur_index = palloc(sizeof(int) * npath);

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{

1685 bool *path_nulls = palloc0(path_len * sizeof(bool));

1686

1689

1691

1695

1696 pfree(path_nulls);

1697

1699}

1700

1701static void

1703{

1705

1707

1708 while (num-- > 0)

1710}

1711

1712

1713

1714

1715

1716

1717

1718

1719

1720static void

1723{

1724

1725

1726

1727

1728

1729

1732

1733

1734

1735

1736

1737

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

1739 {

1740 char *c,

1741 *badp;

1742 int lindex;

1743

1744 if (path_nulls[i])

1745 break;

1746

1747

1748

1749

1750

1752 errno = 0;

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

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

1755 {

1756

1758 newkey.val.string.val = c;

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

1760

1763

1765 }

1766 else

1767 {

1768

1770

1772

1774 }

1775 }

1776

1777

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

1779 {

1781 }

1782 else

1784

1785

1786

1787

1788

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

1790 {

1791 if (path_nulls[i])

1792 break;

1793

1796 else

1798 }

1799}

1800

1801

1802

1803

1804static text *

1806{

1807 switch (v->type)

1808 {

1810 return NULL;

1811

1813 return v->val.boolean ?

1816

1819 v->val.string.len);

1820

1822 {

1824

1827

1829 }

1830

1832 {

1834

1837 v->val.binary.len);

1838

1840 }

1841

1842 default:

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

1844 return NULL;

1845 }

1846}

1847

1848

1849

1850

1853{

1858

1861

1862#if 0

1863 state->count = 0;

1864#endif

1865

1871

1873

1875}

1876

1879{

1881

1884 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

1888 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

1890

1892}

1893

1894

1895

1896

1897

1898

1901{

1903

1904

1907 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

1909

1911}

1912

1915{

1917

1918

1921 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

1923

1925}

1926

1929{

1931

1932

1934 _state->count++;

1935

1937}

1938

1939

1940

1941

1942

1943

1944

1945

1946

1947

1948

1951{

1953}

1954

1957{

1959}

1960

1963{

1965}

1966

1969{

1971}

1972

1975{

1979 tmp_cxt;

1980 bool skipNested = false;

1984

1987 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

1990

1993

1995 "jsonb_each temporary cxt",

1997

1999

2001 {

2002 skipNested = true;

2003

2005 {

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

2009

2010

2012

2014

2015

2016

2017

2018

2021

2023

2024 if (as_text)

2025 {

2027 {

2028

2029 nulls[1] = true;

2031 }

2032 else

2034 }

2035 else

2036 {

2037

2039

2041 }

2042

2044

2045

2048 }

2049 }

2050

2052

2054}

2055

2056

2059{

2065

2068

2070

2074

2080

2081 state->normalize_results = as_text;

2082 state->next_scalar = false;

2085 "json_each temporary cxt",

2087

2089

2092

2094}

2095

2096

2099{

2101

2102

2104 {

2105

2106

2107

2108

2109

2112 else

2114 }

2115

2117}

2118

2121{

2124 int len;

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

2129

2130

2133

2134

2136

2138

2140 {

2141 nulls[1] = true;

2143 }

2145 {

2148 }

2149 else

2150 {

2154 }

2155

2157

2159

2160

2163

2165}

2166

2169{

2171

2172

2175 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

2177

2179}

2180

2183{

2185

2186

2189 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

2191

2192

2195

2197}

2198

2199

2200

2201

2202

2203

2204

2205

2206

2209{

2211}

2212

2215{

2217}

2218

2221 bool as_text)

2222{

2226 tmp_cxt;

2227 bool skipNested = false;

2231

2234 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

2238 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

2240

2242

2244

2246 "jsonb_array_elements temporary cxt",

2248

2250

2252 {

2253 skipNested = true;

2254

2256 {

2258 bool nulls[1] = {false};

2259

2260

2262

2263 if (as_text)

2264 {

2266 {

2267

2268 nulls[0] = true;

2270 }

2271 else

2273 }

2274 else

2275 {

2276

2278

2280 }

2281

2283

2284

2287 }

2288 }

2289

2291

2293}

2294

2297{

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

2299}

2300

2303{

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

2305}

2306

2309{

2315

2316

2318

2321

2326

2332

2334 state->normalize_results = as_text;

2335 state->next_scalar = false;

2336 state->lex = &lex;

2338 "json_array_elements temporary cxt",

2340

2342

2345

2347}

2348

2351{

2353

2354

2356 {

2357

2358

2359

2360

2361

2364 else

2366 }

2367

2369}

2370

2373{

2376 int len;

2380 bool nulls[1] = {false};

2381

2382

2385

2386

2388

2390 {

2391 nulls[0] = true;

2393 }

2395 {

2398 }

2399 else

2400 {

2404 }

2405

2407

2409

2410

2413

2415}

2416

2419{

2421

2422

2425 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

2428

2430}

2431

2434{

2436

2437

2440 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

2443

2444

2447

2449}

2450

2451

2452

2453

2454

2455

2456

2457

2458

2459

2460

2461

2462

2465{

2467 false, true, NULL);

2468}

2469

2470

2471

2472

2473

2474

2475

2478{

2480

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

2483

2485}

2486

2489{

2491 false, false, NULL);

2492}

2493

2496{

2498 true, true, NULL);

2499}

2500

2503{

2505 true, false, NULL);

2506}

2507

2508

2509static void

2511{

2512 if (ndim <= 0)

2513 {

2516 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

2517 errmsg("expected JSON array"),

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

2519 else

2521 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

2523 return;

2524 }

2525 else

2526 {

2528 int i;

2529

2531

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

2533

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

2536

2539 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

2540 errmsg("expected JSON array"),

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

2543 else

2545 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

2546 errmsg("expected JSON array"),

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

2548 indices.data)));

2549 return;

2550 }

2551}

2552

2553

2554

2555

2556

2557

2558

2559static bool

2561{

2562 int i;

2563

2565

2566 if (ndims <= 0)

2567 {

2569

2571 return false;

2572 }

2573

2574 ctx->ndims = ndims;

2575 ctx->dims = palloc(sizeof(int) * ndims);

2577

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

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

2580

2581 return true;

2582}

2583

2584

2585

2586

2587

2588

2589static bool

2591{

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

2593

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

2595 ctx->dims[ndim] = dim;

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

2598 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

2599 errmsg("malformed JSON array"),

2600 errdetail("Multidimensional arrays must have "

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

2602

2603

2604 ctx->sizes[ndim] = 0;

2605

2606

2607 if (ndim > 0)

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

2609

2610 return true;

2611}

2612

2613

2614

2615

2616

2617static bool

2619{

2621 bool element_isnull;

2622

2623

2628 jsv, &element_isnull, ctx->escontext,

2629 false);

2630

2632 return false;

2633

2636

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

2639

2640 return true;

2641}

2642

2643

2646{

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

2649

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

2651 {

2654 }

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

2656 {

2658

2661 }

2662

2664}

2665

2666

2669{

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

2673

2674 if (ctx->ndims <= 0)

2675 {

2678 }

2679

2680 if (ndim < ctx->ndims)

2681 {

2682

2685 }

2686

2688}

2689

2690

2693{

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

2696

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

2698 {

2699

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

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

2702 state->element_scalar = NULL;

2703 }

2704

2706}

2707

2708

2711{

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

2715

2717

2718 if (ndim == ctx->ndims)

2719 {

2721

2724

2725 if (isnull)

2726 {

2730 }

2731 else if (state->element_scalar)

2732 {

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

2735 }

2736 else

2737 {

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

2741 }

2742

2743

2746 }

2747

2749}

2750

2751

2754{

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

2758

2759 if (ctx->ndims <= 0)

2760 {

2763 }

2764 else if (ndim < ctx->ndims)

2765 {

2767

2770 }

2771

2772 if (ndim == ctx->ndims)

2773 {

2774

2776

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

2778 }

2779

2781}

2782

2783

2784

2785

2786

2787

2788static bool

2790{

2793

2796 state.ctx = ctx;

2797

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

2805

2807 {

2808

2810 }

2811

2813

2815}

2816

2817

2818

2819

2820

2821

2822

2823

2824static bool

2826 JsonbValue *jbv,

2827 int ndim)

2828{

2834

2836

2837

2840 {

2842

2844 return false;

2845 }

2846

2848

2851

2853

2854

2855

2856

2857

2858

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

2864 {

2866 return false;

2867 }

2868

2871

2872

2874 {

2875

2876

2877

2878

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

2880 {

2882 return false;

2883 }

2884 else

2885 {

2886

2888 return false;

2889

2890

2892

2894 return false;

2895 }

2896

2898 }

2899

2901

2902

2905

2906 return true;

2907}

2908

2909

2910

2911

2912

2913

2916 const char *colname,

2919 bool *isnull,

2920 Node *escontext)

2921{

2924 int *lbs;

2925 int i;

2926

2927 ctx.aio = aio;

2928 ctx.mcxt = mcxt;

2932 ctx.ndims = 0;

2933 ctx.dims = NULL;

2934 ctx.sizes = NULL;

2936

2938 {

2939

2943 {

2944 *isnull = true;

2945 return (Datum) 0;

2946 }

2947 }

2948 else

2949 {

2950

2952 {

2953 *isnull = true;

2954 return (Datum) 0;

2955 }

2957 }

2958

2960

2962

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

2964 lbs[i] = 1;

2965

2967 ctx.acxt, true);

2968

2972

2973 *isnull = false;

2974 return result;

2975}

2976

2977

2978

2979

2980

2981static bool

2983{

2985

2987 {

2988

2994 "populate_composite",

2995 escontext);

2997 }

2998 else

2999 {

3001

3004 {

3006 }

3007 else

3008 {

3009 bool is_scalar;

3010

3015 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

3016 is_scalar

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

3018 "populate_composite")

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

3020 "populate_composite")));

3021 }

3022 }

3023

3025}

3026

3027

3028static void

3030{

3034 {

3038

3041

3042

3046

3048 }

3049}

3050

3051

3052

3053

3054

3055

3056

3059 Oid typid,

3060 const char *colname,

3064 bool *isnull,

3065 Node *escontext)

3066{

3068

3069

3071

3072 if (*isnull)

3073 result = (Datum) 0;

3074 else

3075 {

3078

3079

3081 {

3082 *isnull = true;

3083 return (Datum) 0;

3084 }

3085

3086

3088 defaultval, mcxt, &jso, escontext);

3089

3091 {

3092 *isnull = true;

3093 return (Datum) 0;

3094 }

3096

3098 }

3099

3100

3101

3102

3103

3104

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

3106 {

3108 escontext))

3109 {

3110 *isnull = true;

3111 return (Datum) 0;

3112 }

3113 }

3114

3115 return result;

3116}

3117

3118

3119

3120

3121

3122

3123

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

3127{

3129 char *str = NULL;

3130 const char *json = NULL;

3131

3133 {

3135

3138

3139

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

3142 {

3144

3146 if (len >= 0)

3148 else

3151 }

3152 else if (len >= 0)

3153 {

3154

3156 memcpy(str, json, len);

3158 }

3159 else

3160 {

3161

3163 }

3164 }

3165 else

3166 {

3168

3171 else if (typid == JSONBOID)

3172 {

3174

3176 }

3177

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

3179 {

3180

3181

3182

3183

3185

3187 }

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

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

3197 jbv->val.binary.len);

3198 else

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

3200 }

3201

3203 escontext, &res))

3204 {

3205 res = (Datum) 0;

3206 *isnull = true;

3207 }

3208

3209

3210 if (str != json)

3212

3213 return res;

3214}

3215

3218 Oid typid,

3219 const char *colname,

3222 bool *isnull,

3223 Node *escontext,

3224 bool omit_quotes)

3225{

3227

3228 if (*isnull)

3229 res = (Datum) 0;

3230 else

3231 {

3235 jsv, isnull, escontext, omit_quotes);

3237 }

3238

3240 escontext))

3241 {

3242 *isnull = true;

3243 return (Datum) 0;

3244 }

3245

3246 return res;

3247}

3248

3249

3250static void

3252 Oid typid,

3255 bool need_scalar)

3256{

3259

3260 column->typid = typid;

3261 column->typmod = typmod;

3262

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

3266

3268

3269 if (type->typtype == TYPTYPE_DOMAIN)

3270 {

3271

3272

3273

3274

3275 Oid base_typid;

3276 int32 base_typmod = typmod;

3277

3279 if (get_typtype(base_typid) == TYPTYPE_COMPOSITE)

3280 {

3281

3288 }

3289 else

3290 {

3291

3298 }

3299 }

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

3301 {

3308 }

3309 else if (IsTrueArrayType(type))

3310 {

3315

3317 }

3318 else

3319 {

3321 need_scalar = true;

3322 }

3323

3324

3325 if (need_scalar)

3326 {

3327 Oid typioproc;

3328

3331 }

3332

3334}

3335

3336

3337

3338

3339

3340

3341

3342

3343

3348 bool *isnull, bool omit_quotes,

3349 Node *escontext)

3350{

3353

3354 jsv.is_json = json_type == JSONOID;

3355

3356 if (*isnull)

3357 {

3360 else

3362 }

3364 {

3366

3370

3371 }

3372 else

3373 {

3375

3377

3378 if (omit_quotes)

3379 {

3381

3382

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

3385 jbv.val.string.val = str;

3386 }

3387 else

3388 {

3389

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

3393 }

3394 }

3395

3396 if (*cache == NULL)

3398

3401 escontext, omit_quotes);

3402}

3403

3404

3407 Oid typid,

3409 const char *colname,

3411 Datum defaultval,

3413 bool *isnull,

3414 Node *escontext,

3415 bool omit_scalar_quotes)

3416{

3418

3420

3421

3422

3423

3424

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

3427

3429

3430 typcat = col->typcat;

3431

3432

3438

3439

3440 if (*isnull &&

3443 return (Datum) 0;

3444

3445 switch (typcat)

3446 {

3449 isnull, escontext, omit_scalar_quotes);

3450

3453 isnull, escontext);

3454

3458 colname, mcxt,

3461 : NULL,

3462 jsv, isnull,

3463 escontext);

3464

3467 jsv, isnull, escontext, omit_scalar_quotes);

3468

3469 default:

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

3471 return (Datum) 0;

3472 }

3473}

3474

3477{

3482

3484 data->record_typmod = 0;

3485 data->ncolumns = ncolumns;

3487

3488 return data;

3489}

3490

3491static bool

3493{

3495

3497 {

3500

3503 hashentry->val;

3505

3506 return hashentry != NULL;

3507 }

3508 else

3509 {

3512 NULL);

3513

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

3515 }

3516}

3517

3518

3525 Node *escontext)

3526{

3529 bool *nulls;

3531 int ncolumns = tupdesc->natts;

3532 int i;

3533

3534

3535

3536

3537

3538

3540 return defaultval;

3541

3542

3543 if (record == NULL ||

3544 record->ncolumns != ncolumns)

3546

3547

3550 {

3555 record->ncolumns = ncolumns;

3556 }

3557

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

3560

3561 if (defaultval)

3562 {

3564

3565

3569 tuple.t_data = defaultval;

3570

3571

3573 }

3574 else

3575 {

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

3577 {

3579 nulls[i] = true;

3580 }

3581 }

3582

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

3584 {

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

3588 bool found;

3589

3590

3591 if (att->attisdropped)

3592 {

3593 nulls[i] = true;

3594 continue;

3595 }

3596

3598

3599

3600

3601

3602

3603

3604

3605

3606

3607 if (defaultval && !found)

3608 continue;

3609

3611 att->atttypid,

3612 att->atttypmod,

3613 colname,

3614 mcxt,

3616 &field,

3617 &nulls[i],

3618 escontext,

3619 false);

3620 }

3621

3623

3626

3628}

3629

3630

3631

3632

3633

3634

3635static void

3639{

3647 (errcode(ERRCODE_DATATYPE_MISMATCH),

3648

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

3651}

3652

3653

3654

3655

3656

3657

3658

3659

3660

3661static void

3665{

3668

3671 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

3672

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

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

3676 "or call the function in the FROM clause "

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

3678

3681

3682

3685

3686

3692}

3693

3694

3695

3696

3697

3700 bool is_json, bool have_record_arg,

3701 Node *escontext)

3702{

3703 int json_arg_num = have_record_arg ? 1 : 0;

3707 bool isnull;

3711

3712

3713

3714

3715

3716

3717 if (!cache)

3718 {

3721 cache->fn_mcxt = fnmcxt;

3722

3723 if (have_record_arg)

3725 else

3727 }

3728

3729

3730 if (!have_record_arg)

3731 rec = NULL;

3733 {

3735

3736

3737

3738

3739

3740 if (cache->argtype == RECORDOID)

3741 {

3744 }

3745 }

3746 else

3747 {

3748 rec = NULL;

3749

3750

3751

3752

3753

3754 if (cache->argtype == RECORDOID)

3755 {

3757

3759 }

3760 }

3761

3762

3764 {

3765 if (rec)

3767 else

3769 }

3770

3772

3773 if (is_json)

3774 {

3776

3780

3781 }

3782 else

3783 {

3785

3787

3788

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

3792 }

3793

3794 isnull = false;

3796 NULL, fnmcxt, rec, &jsv, &isnull,

3797 escontext);

3799

3801}

3802

3803

3804

3805

3806

3807

3808

3809

3810static HTAB *

3812 Node *escontext)

3813{

3818

3822 tab = hash_create("json object hashtable",

3823 100,

3826

3829

3831 state->hash = tab;

3834

3840

3842 {

3844 tab = NULL;

3845 }

3846

3848

3849 return tab;

3850}

3851

3854{

3856

3859

3860

3862

3865 {

3866

3868 }

3869 else

3870 {

3871

3873 }

3874

3876}

3877

3880{

3883 bool found;

3884

3885

3886

3887

3890

3891

3892

3893

3894

3895

3896

3897

3900

3902

3903

3904

3905

3906

3907

3910

3912 {

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

3915

3918 hashentry->val = val;

3919 }

3920 else

3921 {

3922

3924 }

3925

3927}

3928

3931{

3933

3936 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

3938

3940}

3941

3944{

3946

3949 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

3951

3953 {

3955

3957 }

3958

3960}

3961

3962

3963

3964

3965

3966

3967

3968

3969

3970

3971

3972

3975{

3977 false, true);

3978}

3979

3982{

3984 false, false);

3985}

3986

3989{

3991 true, true);

3992}

3993

3996{

3998 true, false);

3999}

4000

4001static void

4003{

4007

4008

4010

4011

4016 obj,

4017 NULL);

4018

4019

4025 NULL);

4026

4027

4031 tuple.t_data = tuphead;

4032

4034}

4035

4036

4037

4038

4039

4042 bool is_json, bool have_record_arg)

4043{

4044 int json_arg_num = have_record_arg ? 1 : 0;

4050

4052

4055 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

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

4057

4060 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

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

4062

4064

4065

4066

4067

4068

4069

4070 if (!cache)

4071 {

4075

4076 if (have_record_arg)

4078 else

4080 }

4081

4082

4083 if (!have_record_arg)

4084 rec = NULL;

4086 {

4088

4089

4090

4091

4092

4093 if (cache->argtype == RECORDOID)

4094 {

4097 }

4098 }

4099 else

4100 {

4101 rec = NULL;

4102

4103

4104

4105

4106

4107 if (cache->argtype == RECORDOID)

4108 {

4110

4112 }

4113 }

4114

4115

4118

4119

4120

4121

4122

4124

4126

4127

4133

4135 state->cache = cache;

4136 state->rec = rec;

4137

4138 if (is_json)

4139 {

4143

4145

4147

4156

4157 state->lex = &lex;

4158

4160

4162 state->lex = NULL;

4163 }

4164 else

4165 {

4169 bool skipNested = false;

4171

4174 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

4177

4179

4181 {

4182 skipNested = true;

4183

4185 {

4187

4191 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

4194

4197

4199 }

4200 }

4201 }

4202

4203

4204

4205

4206

4207

4210

4212}

4213

4216{

4220

4221

4222 if (lex_level == 0)

4224 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

4227

4228

4229 if (lex_level > 1)

4231

4232

4237 100,

4240

4242}

4243

4246{

4249

4250

4253

4256

4257

4259

4260

4263

4265}

4266

4269{

4271

4275 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

4278

4280}

4281

4284{

4285

4287}

4288

4291{

4293

4296 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

4299

4302

4304}

4305

4308{

4310

4313

4315

4318 {

4320 }

4321 else

4322 {

4324 }

4325

4327}

4328

4331{

4334 bool found;

4335

4336

4337

4338

4341

4342

4343

4344

4345

4346

4347

4348

4351

4353

4354

4355

4356

4357

4358

4361

4363 {

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

4366

4369 hashentry->val = val;

4370 }

4371 else

4372 {

4373

4375 }

4376

4378}

4379

4380

4381

4382

4383

4384

4385

4386

4387

4388

4391{

4393

4395

4397}

4398

4401{

4403

4405

4407}

4408

4411{

4413

4415

4417}

4418

4421{

4423

4425

4427}

4428

4431{

4433

4434 if (isnull)

4435 {

4436

4437

4438

4439

4440

4443 }

4444

4447

4448

4449

4450

4451

4453

4455

4457}

4458

4461{

4463

4464

4466 {

4469 }

4470

4471

4474 {

4476 }

4477

4479}

4480

4483{

4485

4487 {

4491 }

4492

4495 else

4497

4499}

4500

4501

4502

4503

4506{

4512

4515

4518 state->skip_next_null = false;

4519 state->strip_in_arrays = strip_in_arrays;

4520

4529

4531

4533 state->strval->len));

4534}

4535

4536

4537

4538

4541{

4543 bool strip_in_arrays = false;

4548 k;

4550 bool last_was_key = false;

4551

4554

4557

4559

4561 {

4563

4565 {

4566

4567 k = v;

4568 last_was_key = true;

4569 continue;

4570 }

4571

4572 if (last_was_key)

4573 {

4574

4575 last_was_key = false;

4576

4577

4579 continue;

4580

4581

4583 }

4584

4585

4586 if (strip_in_arrays)

4588 continue;

4589

4592 else

4594 }

4595

4596 Assert(res != NULL);

4597

4599}

4600

4601

4602

4603

4604

4605

4608{

4611

4613

4615}

4616

4617

4618

4619

4620

4621

4624{

4630 *it2;

4631

4632

4633

4634

4635

4636

4637

4639 {

4644 }

4645

4648

4650

4651 Assert(res != NULL);

4652

4654}

4655

4656

4657

4658

4659

4660

4661

4662

4665{

4673 *res = NULL;

4674 bool skipNested = false;

4676

4679 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

4681

4684

4686

4688 {

4689 skipNested = true;

4690

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

4694 {

4695

4698

4699 continue;

4700 }

4701

4703 }

4704

4705 Assert(res != NULL);

4706

4708}

4709

4710

4711

4712

4713

4714

4715

4718{

4721 Datum *keys_elems;

4722 bool *keys_nulls;

4723 int keys_len;

4727 *res = NULL;

4728 bool skipNested = false;

4730

4733 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

4735

4738 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

4740

4743

4745

4746 if (keys_len == 0)

4748

4750

4752 {

4753 skipNested = true;

4754

4756 {

4757 int i;

4758 bool found = false;

4759

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

4761 {

4762 char *keyptr;

4763 int keylen;

4764

4765 if (keys_nulls[i])

4766 continue;

4767

4768

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

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

4773 {

4774 found = true;

4775 break;

4776 }

4777 }

4778 if (found)

4779 {

4780

4783

4784 continue;

4785 }

4786 }

4787

4789 }

4790

4791 Assert(res != NULL);

4792

4794}

4795

4796

4797

4798

4799

4800

4801

4802

4805{

4811 n;

4813 *res = NULL;

4815

4818 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

4820

4823 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

4825

4828

4830

4833 n = v.val.array.nElems;

4834

4835 if (idx < 0)

4836 {

4838 idx = n;

4839 else

4841 }

4842

4843 if (idx >= n)

4845

4847

4849 {

4851 {

4852 if (i++ == idx)

4853 continue;

4854 }

4855

4857 }

4858

4859 Assert(res != NULL);

4860

4862}

4863

4864

4865

4866

4869{

4876 Datum *path_elems;

4877 bool *path_nulls;

4878 int path_len;

4881

4883

4886 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

4888

4891 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

4893

4896

4898

4899 if (path_len == 0)

4901

4903

4904 res = setPath(&it, path_elems, path_nulls, path_len, &st,

4906

4907 Assert(res != NULL);

4908

4910}

4911

4912

4913

4914

4915

4918{

4919

4920

4921

4922

4923 text *handle_null;

4924 char *handle_val;

4925

4928

4929

4932 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

4934

4935

4938

4941

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

4943 {

4945 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

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

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

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

4949 return (Datum) 0;

4950 }

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

4952 {

4954

4956

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

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

4960 }

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

4962 {

4964 }

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

4966 {

4968

4970 }

4971 else

4972 {

4974 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

4976 return (Datum) 0;

4977 }

4978}

4979

4980

4981

4982

4985{

4989 Datum *path_elems;

4990 bool *path_nulls;

4991 int path_len;

4994

4997 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

4999

5002 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

5004

5007

5009

5010 if (path_len == 0)

5012

5014

5015 res = setPath(&it, path_elems, path_nulls, path_len, &st,

5017

5018 Assert(res != NULL);

5019

5021}

5022

5023

5024

5025

5028{

5035 Datum *path_elems;

5036 bool *path_nulls;

5037 int path_len;

5040

5042

5045 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

5047

5050 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

5052

5054

5055 if (path_len == 0)

5057

5059

5060 res = setPath(&it, path_elems, path_nulls, path_len, &st, 0, &newval,

5062

5063 Assert(res != NULL);

5064

5066}

5067

5068

5069

5070

5071

5072

5073

5074

5078{

5080 v2,

5081 *res = NULL;

5083 r2,

5084 rk1,

5085 rk2;

5086

5089

5090

5091

5092

5093

5095 {

5096

5097

5098

5099

5100

5101

5105

5106

5107

5108

5109

5110

5113 }

5115 {

5116

5117

5118

5120

5122 {

5125 }

5126

5128 {

5131 }

5132

5134 }

5136 {

5137

5138

5139

5141

5143

5147

5150 }

5151 else

5152 {

5153

5154

5155

5158

5160

5163

5167

5169 }

5170

5171 return res;

5172}

5173

5174

5175

5176

5177

5178

5179

5180

5181

5182

5183

5184

5185

5186

5187

5188

5189

5190

5191

5192

5193

5194

5195

5196

5197

5198

5199

5200

5201

5202

5205 bool *path_nulls, int path_len,

5207{

5211

5213

5214 if (path_nulls[level])

5216 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

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

5218 level + 1)));

5219

5221

5222 switch (r)

5223 {

5225

5226

5227

5228

5229

5230

5231

5233 v.val.array.rawScalar)

5235 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

5236 errmsg("cannot replace existing key"),

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

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

5239

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

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

5246 break;

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

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

5254 break;

5257

5258

5259

5260

5261

5262

5263

5266 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

5267 errmsg("cannot replace existing key"),

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

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

5270

5272 break;

5273 default:

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

5275 res = NULL;

5276 break;

5277 }

5278

5279 return res;

5280}

5281

5282

5283

5284

5285static void

5289{

5290 text *pathelem = NULL;

5291 int i;

5293 v;

5294 bool done = false;

5295

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

5297 done = true;

5298 else

5299 {

5300

5302 }

5303

5304

5306 (level == path_len - 1))

5307 {

5309

5313

5316 }

5317

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

5319 {

5321

5323

5324 if (!done &&

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

5328 {

5329 done = true;

5330

5331 if (level == path_len - 1)

5332 {

5333

5334

5335

5336

5339 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

5340 errmsg("cannot replace existing key"),

5341 errhint("Try using the function jsonb_set "

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

5343

5346 {

5349 }

5350 }

5351 else

5352 {

5354 setPath(it, path_elems, path_nulls, path_len,

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

5356 }

5357 }

5358 else

5359 {

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

5362 {

5364

5368

5371 }

5372

5377 {

5378 int walking_level = 1;

5379

5380 while (walking_level != 0)

5381 {

5383

5385 ++walking_level;

5387 --walking_level;

5388

5390 }

5391 }

5392 }

5393 }

5394

5395

5396

5397

5398

5399

5400

5401

5402

5403

5404

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

5406 {

5408

5412

5414 (void) push_path(st, level, path_elems, path_nulls,

5416

5417

5418 }

5419}

5420

5421

5422

5423

5424static void

5428{

5430 int idx,

5431 i;

5432 bool done = false;

5433

5434

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

5436 {

5438 char *badp;

5439

5440 errno = 0;

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

5444 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

5446 level + 1, c)));

5447 }

5448 else

5449 idx = nelems;

5450

5451 if (idx < 0)

5452 {

5454 {

5455

5456

5457

5458

5461 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

5463 level + 1, idx)));

5464 else

5466 }

5467 else

5469 }

5470

5471

5472

5473

5474

5476 {

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

5478 idx = nelems;

5479 }

5480

5481

5482

5483

5484

5485

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

5488 {

5490

5493

5495

5496 done = true;

5497 }

5498

5499

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

5501 {

5503

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

5505 {

5506 done = true;

5507

5508 if (level == path_len - 1)

5509 {

5511

5514

5515

5516

5517

5518

5519

5522

5525 }

5526 else

5527 (void) setPath(it, path_elems, path_nulls, path_len,

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

5529 }

5530 else

5531 {

5533

5535

5537 {

5538 int walking_level = 1;

5539

5540 while (walking_level != 0)

5541 {

5543

5545 ++walking_level;

5547 --walking_level;

5548

5550 }

5551 }

5552 }

5553 }

5554

5556 {

5557

5558

5559

5560

5563

5565 done = true;

5566 }

5567

5568

5569

5570

5571

5572

5573

5574

5575

5576

5577

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

5579 {

5580 if (idx > 0)

5582

5583 (void) push_path(st, level, path_elems, path_nulls,

5585

5586

5587 }

5588}

5589

5590

5591

5592

5593

5594

5597{

5602

5604

5606

5607

5608

5609

5610

5611

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

5615

5617 {

5620 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

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

5623

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

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

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

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

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

5639 else

5641 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

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

5645 }

5646

5647

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

5650

5651

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

5655

5656 return flags;

5657}

5658

5659

5660

5661

5662

5663void

5666{

5670

5672

5673

5674

5675

5676

5678 {

5680 {

5683

5684 continue;

5685 }

5687 {

5688

5689 continue;

5690 }

5691

5692

5693 switch (v.type)

5694 {

5698 break;

5701 {

5702 char *val;

5703

5706

5709 }

5710 break;

5713 {

5714 if (v.val.boolean)

5716 else

5718 }

5719 break;

5720 default:

5721

5722 break;

5723 }

5724 }

5725}

5726

5727

5728

5729

5730

5731void

5734{

5738

5741 state->action_state = action_state;

5742 state->flags = flags;

5743

5747

5750}

5751

5752

5753

5754

5755

5758{

5760

5761 switch (tokentype)

5762 {

5766 break;

5770 break;

5775 break;

5776 default:

5777

5778 break;

5779 }

5780

5782}

5783

5786{

5788

5790 {

5792

5794 }

5795

5797}

5798

5799

5800

5801

5802

5803

5804

5808{

5811 *res = NULL;

5815 bool is_scalar = false;

5816

5819

5821 {

5823 {

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

5825

5830 }

5831 else

5832 {

5836 }

5837 }

5838

5840 res->val.array.rawScalar = is_scalar;

5841

5843}

5844

5845

5846

5847

5848

5849

5850

5851

5855{

5859

5862 state->action = transform_action;

5863 state->action_state = action_state;

5864

5873

5876

5878}

5879

5880

5881

5882

5883

5884

5887{

5889

5891

5893}

5894

5897{

5899

5901

5903}

5904

5907{

5909

5911

5913}

5914

5917{

5919

5921

5923}

5924

5927{

5929

5932

5933

5934

5935

5936

5939

5941}

5942

5945{

5947

5950

5952}

5953

5956{

5958

5960 {

5962

5964 }

5965 else

5967

5969}

5970

5973{

5976

5978

5979

5981

5984

5985 if (throw_error)

5987

5989}

5990

5991

5992

5993

5994

5995

5996

5997

5998void

6001{

6002 bool typisvarlena;

6003

6004

6006

6008

6009 switch (typoid)

6010 {

6011 case BOOLOID:

6012 *outfuncoid = F_BOOLOUT;

6014 break;

6015

6016 case INT2OID:

6017 case INT4OID:

6018 case INT8OID:

6019 case FLOAT4OID:

6020 case FLOAT8OID:

6021 case NUMERICOID:

6024 break;

6025

6026 case DATEOID:

6027 *outfuncoid = F_DATE_OUT;

6029 break;

6030

6031 case TIMESTAMPOID:

6032 *outfuncoid = F_TIMESTAMP_OUT;

6034 break;

6035

6036 case TIMESTAMPTZOID:

6037 *outfuncoid = F_TIMESTAMPTZ_OUT;

6039 break;

6040

6041 case JSONOID:

6044 break;

6045

6046 case JSONBOID:

6049 break;

6050

6051 default:

6052

6054 || typoid == ANYCOMPATIBLEARRAYOID || typoid == RECORDARRAYOID)

6055 {

6056 *outfuncoid = F_ARRAY_OUT;

6058 }

6059 else if (type_is_rowtype(typoid))

6060 {

6061 *outfuncoid = F_RECORD_OUT;

6063 }

6064 else

6065 {

6066

6067

6068

6069

6070

6073 {

6074 Oid castfunc;

6076

6079 &castfunc);

6081 {

6082 *outfuncoid = castfunc;

6084 }

6085 else

6086 {

6087

6089 }

6090 }

6091 else

6092 {

6093

6095 }

6096 }

6097 break;

6098 }

6099}

Datum idx(PG_FUNCTION_ARGS)

#define PG_GETARG_ARRAYTYPE_P(n)

bool array_contains_nulls(ArrayType *array)

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

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

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

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

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)

void hash_destroy(HTAB *hashp)

HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)

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

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, fmNodePtr 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_)

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

JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)

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 JsonbValue * IteratorConcat(JsonbIterator **it1, JsonbIterator **it2, JsonbParseState **state)

Datum json_each_text(PG_FUNCTION_ARGS)

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)

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

Datum jsonb_pretty(PG_FUNCTION_ARGS)

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

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

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)

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

struct JsonHashEntry JsonHashEntry

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

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)

static JsonParseErrorType sn_object_start(void *state)

static JsonParseErrorType sn_array_start(void *state)

static bool populate_array_check_dimension(PopulateArrayContext *ctx, int ndim)

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

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

static JsonParseErrorType sn_array_end(void *state)

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)

static void push_null_elements(JsonbParseState **ps, int num)

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

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 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 void setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls, int path_len, JsonbParseState **st, int level, JsonbValue *newval, uint32 npairs, int op_type)

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)

void * palloc0(Size size)

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

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 *pg_restrict str, char **pg_restrict endptr, int base)

StringInfo makeStringInfo(void)

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

union ColumnIOData::@24 io

CompositeIOData composite

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::@25::@26 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)

#define VARSIZE_ANY_EXHDR(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)