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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

61

78

79

80

81

83{

87

88

89typedef JsonbValue *(*JsonPathGetVarCallback) (void *vars, char *varName, int varNameLen,

90 JsonbValue *baseObject, int *baseObjectId);

92

93

94

95

97{

98 void *vars;

100

104

106

108 bool laxMode;

109

111

112

113

114 bool throwErrors;

115

118

119

121{

125

126

128{

133

134

136{

141

142#define jperIsError(jper) ((jper) == jperError)

143

144

145

146

148{

152

154{

159

160

161

162

163

164

165

166

168{

172

173

174

175

176

178{

179

181

182

183

184

186

187

188

189

191

192

194

195

198

199

201

202

204

205

207

208

210

211

213

214

217

218

219#define JSON_TABLE_EXEC_CONTEXT_MAGIC 418352867

220

222{

224

225

227

228

229

230

231

234

235

236#define jspStrictAbsenceOfErrors(cxt) (!(cxt)->laxMode)

237#define jspAutoUnwrap(cxt) ((cxt)->laxMode)

238#define jspAutoWrap(cxt) ((cxt)->laxMode)

239#define jspIgnoreStructuralErrors(cxt) ((cxt)->ignoreStructuralErrors)

240#define jspThrowErrors(cxt) ((cxt)->throwErrors)

241

242

243#define RETURN_ERROR(throw_error) \

244do { \

245 if (jspThrowErrors(cxt)) \

246 throw_error; \

247 else \

248 return jperError; \

249} while (0)

250

254 void *param);

256

260 Jsonb *json, bool throwErrors,

284 bool ignoreStructuralErrors, bool unwrapNext);

311 JsonbValue *baseObject, int *baseObjectId);

320 int varNameLength,

322 int *baseObjectId);

327 bool useTz);

349 bool useTz, bool *cast_error);

351 const char *type2);

352

363 Oid typid, int32 typmod, bool *isnull);

369

371{

374 .SetNamespace = NULL,

375 .SetRowFilter = NULL,

376 .SetColumnFilter = NULL,

380};

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

398{

403 bool silent = true;

404

406 {

409 }

410

413 jb, !silent, NULL, tz);

414

417

420

422}

423

426{

428}

429

432{

434}

435

436

437

438

439

440

443{

444

446}

447

448

449

450

451

452

455{

460 bool silent = true;

461

463 {

466 }

467

470 jb, !silent, &found, tz);

471

474

476 {

478

481

484 }

485

486 if (!silent)

488 (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),

489 errmsg("single boolean result is expected")));

490

492}

493

496{

498}

499

502{

504}

505

506

507

508

509

510

513{

514

516}

517

518

519

520

521

522

525{

530

532 {

537 bool silent;

539

542

547

550 jb, !silent, &found, tz);

551

553

555 }

556

559

561

562 if (c == NULL)

564

567

569}

570

573{

575}

576

579{

581}

582

583

584

585

586

587

590{

596

599 jb, !silent, &found, tz);

600

602}

603

606{

608}

609

612{

614}

615

616

617

618

619

620

623{

629

632 jb, !silent, &found, tz);

633

636 else

638}

639

642{

644}

645

648{

650}

651

652

653

654

655

656

657

658

659

660

661

662

663

664

665

666

667

668

669

670

671

672

673

674

675

680 bool useTz)

681{

686

688

691

696 cxt.root = &jbv;

700

704 cxt.useTz = useTz;

705

707 {

708

709

710

711

713

714 res = executeItem(&cxt, &jsp, &jbv, &vals);

715

717 return res;

718

720 }

721

722 res = executeItem(&cxt, &jsp, &jbv, result);

723

725

726 return res;

727}

728

729

730

731

735{

737}

738

739

740

741

742

743

747{

751

754

755 switch (jsp->type)

756 {

762 {

765 bool hasNext = jspGetNext(jsp, &elem);

766

768 {

769

770

771

772

774 break;

775 }

776

777 v = hasNext ? &vbuf : palloc(sizeof(*v));

778

781

783 v, found, hasNext);

785 }

786 break;

787

788

802 {

804

806 break;

807 }

808

812

816

820

824

828

831

834 found);

835

838 {

839 bool hasNext = jspGetNext(jsp, &elem);

840

843 }

848 (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),

849 errmsg("jsonpath wildcard array accessor can only be applied to an array"))));

850 break;

851

854 {

855 bool hasNext = jspGetNext(jsp, &elem);

856

858 elog(ERROR, "invalid jsonb object type: %d", jb->type);

859

861 (cxt, hasNext ? &elem : NULL,

862 jb->val.binary.data, found, 1, 1, 1,

864 }

868 {

871 (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),

872 errmsg("jsonpath wildcard member accessor can only be applied to an object"))));

873 }

874 break;

875

878 {

880 int i;

882 bool singleton = size < 0;

883 bool hasNext = jspGetNext(jsp, &elem);

884

885 if (singleton)

886 size = 1;

887

889

891 {

895 int32 index_from;

898 &to, i);

899

900 res = getArrayIndex(cxt, &from, jb, &index_from);

901

903 break;

904

906 {

908

910 break;

911 }

912 else

913 index_to = index_from;

914

916 (index_from < 0 ||

917 index_from > index_to ||

918 index_to >= size))

920 (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),

921 errmsg("jsonpath array subscript is out of bounds"))));

922

923 if (index_from < 0)

924 index_from = 0;

925

926 if (index_to >= size)

927 index_to = size - 1;

928

930

932 {

934 bool copy;

935

936 if (singleton)

937 {

938 v = jb;

939 copy = true;

940 }

941 else

942 {

945

946 if (v == NULL)

947 continue;

948

949 copy = false;

950 }

951

952 if (!hasNext && !found)

954

956 copy);

957

959 break;

960

961 if (res == jperOk && !found)

962 break;

963 }

964

966 break;

967

968 if (res == jperOk && !found)

969 break;

970 }

971

973 }

975 {

977 (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),

978 errmsg("jsonpath array accessor can only be applied to an array"))));

979 }

980 break;

981

983 {

984 bool hasNext = jspGetNext(jsp, &elem);

985

986

988 {

989 bool savedIgnoreStructuralErrors;

990

994 jb, found, true);

996

997 if (res == jperOk && !found)

998 break;

999 }

1000

1003 (cxt, hasNext ? &elem : NULL,

1004 jb->val.binary.data, found,

1005 1,

1009 break;

1010 }

1011

1014 {

1017

1020

1023

1024 if (v != NULL)

1025 {

1027 v, found, false);

1028

1029

1032 }

1034 {

1036

1039

1041 (errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND), \

1042 errmsg("JSON object does not contain key \"%s\"",

1044 key.val.string.len))));

1045 }

1046 }

1050 {

1053 (errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND),

1054 errmsg("jsonpath member accessor can only be applied to an object"))));

1055 }

1056 break;

1057

1060 found, true);

1061 break;

1062

1064 jb = cxt->root;

1068 break;

1069

1071 {

1073

1076 false);

1077

1082 else

1084 jb, found, true);

1085 break;

1086 }

1087

1089 {

1091

1094 jbv->val.string.len = strlen(jbv->val.string.val);

1095

1097 found, false);

1098 }

1099 break;

1100

1102 {

1104

1105 if (size < 0)

1106 {

1108 {

1111 (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),

1112 errmsg("jsonpath item method .%s() can only be applied to an array",

1114 break;

1115 }

1116

1117 size = 1;

1118 }

1119

1120 jb = palloc(sizeof(*jb));

1121

1124

1125 res = executeNextItem(cxt, jsp, NULL, jb, found, false);

1126 }

1127 break;

1128

1131 found);

1132

1135 found);

1136

1139 found);

1140

1142 {

1144

1147 false);

1148

1150 {

1153 double val;

1155

1157 NULL,

1158 "double precision",

1159 tmp,

1160 (Node *) &escontext);

1161

1164 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1165 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",

1167 if (isinf(val) || isnan(val))

1169 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1170 errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",

1173 }

1175 {

1176

1177 double val;

1178 char *tmp = pnstrdup(jb->val.string.val,

1179 jb->val.string.len);

1181

1183 NULL,

1184 "double precision",

1185 tmp,

1186 (Node *) &escontext);

1187

1190 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1191 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",

1193 if (isinf(val) || isnan(val))

1195 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1196 errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",

1198

1199 jb = &jbv;

1204 }

1205

1208 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1209 errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",

1211

1213 }

1214 break;

1215

1224

1226

1230

1232

1234 {

1237 int last;

1238 bool hasNext = jspGetNext(jsp, &elem);

1239

1241 elog(ERROR, "evaluating jsonpath LAST outside of array subscript");

1242

1243 if (!hasNext && !found)

1244 {

1246 break;

1247 }

1248

1250

1251 lastjbv = hasNext ? &tmpjbv : palloc(sizeof(*lastjbv));

1252

1255

1257 lastjbv, found, hasNext);

1258 }

1259 break;

1260

1262 {

1265

1268 false);

1269

1271 {

1272 bool have_error;

1274

1276 if (have_error)

1278 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1279 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",

1283 "bigint"))));

1284

1287 }

1289 {

1290

1291 char *tmp = pnstrdup(jb->val.string.val,

1292 jb->val.string.len);

1294 bool noerr;

1295

1298 (Node *) &escontext,

1299 &datum);

1300

1303 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1304 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",

1307 }

1308

1311 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1312 errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",

1314

1315 jb = &jbv;

1318 datum));

1319

1321 }

1322 break;

1323

1325 {

1327 bool bval;

1328

1331 false);

1332

1334 {

1335 bval = jb->val.boolean;

1336

1338 }

1340 {

1341 int ival;

1343 bool noerr;

1347

1350 (Node *) &escontext,

1351 &datum);

1352

1355 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1356 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",

1358

1360 if (ival == 0)

1361 bval = false;

1362 else

1363 bval = true;

1364

1366 }

1368 {

1369

1370 char *tmp = pnstrdup(jb->val.string.val,

1371 jb->val.string.len);

1372

1375 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1376 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",

1378

1380 }

1381

1384 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1385 errmsg("jsonpath item method .%s() can only be applied to a boolean, string, or numeric value",

1387

1388 jb = &jbv;

1390 jb->val.boolean = bval;

1391

1393 }

1394 break;

1395

1398 {

1401 char *numstr = NULL;

1402

1405 false);

1406

1408 {

1409 num = jb->val.numeric;

1412 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1413 errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",

1415

1420 }

1422 {

1423

1425 bool noerr;

1427

1428 numstr = pnstrdup(jb->val.string.val, jb->val.string.len);

1429

1432 (Node *) &escontext,

1433 &datum);

1434

1437 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1438 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",

1440

1444 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1445 errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",

1447

1449 }

1450

1453 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1454 errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",

1456

1457

1458

1459

1460

1461

1462

1464 {

1467 int32 precision;

1469 bool have_error;

1470 bool noerr;

1472 Datum datums[2];

1473 char pstr[12];

1474 char sstr[12];

1476

1479 elog(ERROR, "invalid jsonpath item type for .decimal() precision");

1480

1482 &have_error);

1483 if (have_error)

1485 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1486 errmsg("precision of jsonpath item method .%s() is out of range for type integer",

1488

1490 {

1493 elog(ERROR, "invalid jsonpath item type for .decimal() scale");

1494

1496 &have_error);

1497 if (have_error)

1499 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1500 errmsg("scale of jsonpath item method .%s() is out of range for type integer",

1502 }

1503

1504

1505

1506

1507

1508 pg_ltoa(precision, pstr);

1513

1516

1517

1518 Assert(numstr != NULL);

1521 (Node *) &escontext,

1522 &numdatum);

1523

1526 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1527 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",

1529

1531 pfree(arrtypmod);

1532 }

1533

1534 jb = &jbv;

1536 jb->val.numeric = num;

1537

1539 }

1540 break;

1541

1543 {

1546

1549 false);

1550

1552 {

1553 bool have_error;

1555

1557 if (have_error)

1559 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1560 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",

1564

1567 }

1569 {

1570

1571 char *tmp = pnstrdup(jb->val.string.val,

1572 jb->val.string.len);

1574 bool noerr;

1575

1578 (Node *) &escontext,

1579 &datum);

1580

1583 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1584 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",

1587 }

1588

1591 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1592 errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",

1594

1595 jb = &jbv;

1598 datum));

1599

1601 }

1602 break;

1603

1605 {

1607 char *tmp = NULL;

1608

1611

1613 {

1615

1616

1617

1618

1619

1621 jb->val.string.len);

1622 break;

1626 break;

1628 tmp = (jb->val.boolean) ? "true" : "false";

1629 break;

1631 {

1633

1635 jb->val.datetime.value,

1636 jb->val.datetime.typid,

1637 &jb->val.datetime.tz);

1639 }

1640 break;

1646 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

1647 errmsg("jsonpath item method .%s() can only be applied to a boolean, string, numeric, or datetime value",

1649 break;

1650 }

1651

1652 jb = &jbv;

1653 Assert(tmp != NULL);

1654 jb->val.string.val = tmp;

1655 jb->val.string.len = strlen(jb->val.string.val);

1657

1659 }

1660 break;

1661

1662 default:

1663 elog(ERROR, "unrecognized jsonpath item type: %d", jsp->type);

1664 }

1665

1666 return res;

1667}

1668

1669

1670

1671

1675 bool unwrapElements)

1676{

1678 {

1680 elog(ERROR, "invalid jsonb array value type: %d", jb->type);

1681 }

1682

1684 (cxt, jsp, jb->val.binary.data, found, 1, 1, 1,

1685 false, unwrapElements);

1686}

1687

1688

1689

1690

1691

1696{

1698 bool hasNext;

1699

1700 if (cur)

1701 hasNext = next != NULL;

1702 else if (next)

1704 else

1705 {

1706 next = &elem;

1708 }

1709

1710 if (hasNext)

1712

1713 if (found)

1715

1717}

1718

1719

1720

1721

1722

1727{

1729 {

1734

1736 return res;

1737

1740 {

1742

1745 else

1747 }

1748

1750 }

1751

1752 return executeItem(cxt, jsp, jb, found);

1753}

1754

1755

1756

1757

1763{

1766

1770

1771 return res;

1772}

1773

1774

1778{

1783

1784

1786

1787 if (!canHaveNext && jspHasNext(jsp))

1788 elog(ERROR, "boolean jsonpath item cannot have next item");

1789

1790 switch (jsp->type)

1791 {

1795

1798

1799

1800

1801

1802

1803

1806

1807 return res2 == jpbTrue ? res : res2;

1808

1812

1815

1818

1819 return res2 == jpbFalse ? res : res2;

1820

1823

1825

1828

1830

1835

1846

1847 case jpiStartsWith:

1852

1853 case jpiLikeRegex:

1854 {

1855

1856

1857

1858

1859

1860

1862

1865

1868 }

1869

1872

1874 {

1875

1876

1877

1878

1882 false, &vals);

1883

1886

1888 }

1889 else

1890 {

1893 false, NULL);

1894

1897

1899 }

1900

1901 default:

1902 elog(ERROR, "invalid boolean jsonpath item type: %d", jsp->type);

1904 }

1905}

1906

1907

1908

1909

1910

1914{

1917

1922

1923 return res;

1924}

1925

1926

1927

1928

1929

1930

1931

1935 bool ignoreStructuralErrors, bool unwrapNext)

1936{

1941

1943

1944 if (level > last)

1945 return res;

1946

1948

1949

1950

1951

1953 {

1955 {

1958 }

1959

1961 {

1962

1963 if (level >= first ||

1965 v.type != jbvBinary))

1966 {

1967

1968 if (jsp)

1969 {

1970 if (ignoreStructuralErrors)

1971 {

1972 bool savedIgnoreStructuralErrors;

1973

1978 }

1979 else

1981

1983 break;

1984

1985 if (res == jperOk && !found)

1986 break;

1987 }

1988 else if (found)

1990 else

1992 }

1993

1995 {

1997 (cxt, jsp, v.val.binary.data, found,

1998 level + 1, first, last,

1999 ignoreStructuralErrors, unwrapNext);

2000

2002 break;

2003

2004 if (res == jperOk && found == NULL)

2005 break;

2006 }

2007 }

2008 }

2009

2010 return res;

2011}

2012

2013

2014

2015

2016

2017

2018

2019

2020

2021

2022

2027 void *param)

2028{

2034 bool error = false;

2035 bool found = false;

2036

2037

2041

2042 if (rarg)

2043 {

2044

2046 unwrapRightArg, &rseq);

2049 }

2050

2053 {

2056 bool first = true;

2057

2059 if (rarg)

2061 else

2062 rval = NULL;

2063

2064

2065 while (rarg ? (rval != NULL) : first)

2066 {

2068

2070 {

2073

2075 }

2076 else if (res == jpbTrue)

2077 {

2080

2081 found = true;

2082 }

2083

2084 first = false;

2085 if (rarg)

2087 }

2088 }

2089

2090 if (found)

2092

2093 if (error)

2095

2097}

2098

2099

2100

2101

2102

2107{

2115

2117

2118

2119

2120

2121

2124 return jper;

2125

2127

2130 return jper;

2131

2135 (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),

2136 errmsg("left operand of jsonpath operator %s is not a single numeric value",

2138

2142 (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),

2143 errmsg("right operand of jsonpath operator %s is not a single numeric value",

2145

2147 {

2148 res = func(lval->val.numeric, rval->val.numeric, NULL);

2149 }

2150 else

2151 {

2152 bool error = false;

2153

2154 res = func(lval->val.numeric, rval->val.numeric, &error);

2155

2158 }

2159

2160 if (jspGetNext(jsp, &elem) && !found)

2162

2163 lval = palloc(sizeof(*lval));

2165 lval->val.numeric = res;

2166

2167 return executeNextItem(cxt, jsp, &elem, lval, found, false);

2168}

2169

2170

2171

2172

2173

2177{

2184 bool hasNext;

2185

2188

2190 return jper;

2191

2193

2195

2198 {

2200 {

2201 if (!found && !hasNext)

2203 }

2204 else

2205 {

2206 if (!found && !hasNext)

2207 continue;

2208

2210 (errcode(ERRCODE_SQL_JSON_NUMBER_NOT_FOUND),

2211 errmsg("operand of unary jsonpath operator %s is not a numeric value",

2213 }

2214

2215 if (func)

2216 val->val.numeric =

2219

2221

2223 return jper2;

2224

2225 if (jper2 == jperOk)

2226 {

2227 if (!found)

2230 }

2231 }

2232

2233 return jper;

2234}

2235

2236

2237

2238

2239

2240

2243 void *param)

2244{

2247

2250

2251 if (whole->val.string.len >= initial->val.string.len &&

2252 !memcmp(whole->val.string.val,

2253 initial->val.string.val,

2254 initial->val.string.len))

2256

2258}

2259

2260

2261

2262

2263

2264

2267 void *param)

2268{

2270

2273

2274

2275 if (!cxt->regex)

2276 {

2281 &(cxt->cflags), NULL);

2282 }

2283

2285 str->val.string.len,

2286 cxt->cflags, DEFAULT_COLLATION_OID, 0, NULL))

2288

2290}

2291

2292

2293

2294

2295

2300{

2303

2306

2309 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

2310 errmsg("jsonpath item method .%s() can only be applied to a numeric value",

2312

2314

2317

2318 jb = palloc(sizeof(*jb));

2321

2323}

2324

2325

2326

2327

2328

2329

2330

2331

2332

2333

2334

2335

2336

2340{

2343 text *datetime;

2345 Oid typid;

2346 int32 typmod = -1;

2347 int tz = 0;

2348 bool hasNext;

2351 int32 time_precision = -1;

2352

2355 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

2356 errmsg("jsonpath item method .%s() can only be applied to a string",

2358

2360 jb->val.string.len);

2361

2362

2363

2364

2365

2366

2367 collid = DEFAULT_COLLATION_OID;

2368

2369

2370

2371

2372

2374 {

2375 text *template;

2376 char *template_str;

2377 int template_len;

2379

2381

2383 elog(ERROR, "invalid jsonpath item type for .datetime() argument");

2384

2385 template_str = jspGetString(&elem, &template_len);

2386

2388 template_len);

2389

2391 &typid, &typmod, &tz,

2393

2396 else

2398 }

2399 else

2400 {

2401

2402

2403

2404

2405

2406

2407

2408 static const char *fmt_str[] =

2409 {

2410 "yyyy-mm-dd",

2411 "HH24:MI:SS.USTZ",

2412 "HH24:MI:SSTZ",

2413 "HH24:MI:SS.US",

2414 "HH24:MI:SS",

2415 "yyyy-mm-dd HH24:MI:SS.USTZ",

2416 "yyyy-mm-dd HH24:MI:SSTZ",

2417 "yyyy-mm-dd\"T\"HH24:MI:SS.USTZ",

2418 "yyyy-mm-dd\"T\"HH24:MI:SSTZ",

2419 "yyyy-mm-dd HH24:MI:SS.US",

2420 "yyyy-mm-dd HH24:MI:SS",

2421 "yyyy-mm-dd\"T\"HH24:MI:SS.US",

2422 "yyyy-mm-dd\"T\"HH24:MI:SS"

2423 };

2424

2425

2426 static text *fmt_txt[lengthof(fmt_str)] = {0};

2427 int i;

2428

2429

2430

2431

2432

2435 {

2436 bool have_error;

2437

2439

2441 elog(ERROR, "invalid jsonpath item type for %s argument",

2443

2445 &have_error);

2446 if (have_error)

2448 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

2449 errmsg("time precision of jsonpath item method .%s() is out of range for type integer",

2451 }

2452

2453

2455 {

2457

2458 if (!fmt_txt[i])

2459 {

2462

2465 }

2466

2468 &typid, &typmod, &tz,

2469 (Node *) &escontext);

2470

2472 {

2474 break;

2475 }

2476 }

2477

2479 {

2482 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

2483 errmsg("%s format is not recognized: \"%s\"",

2485 errhint("Use a datetime template argument to specify the input data format."))));

2486 else

2488 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

2489 errmsg("%s format is not recognized: \"%s\"",

2491

2492 }

2493 }

2494

2495

2496

2497

2498

2499

2500

2501 switch (jsp->type)

2502 {

2503 case jpiDatetime:

2504 break;

2506 {

2507

2508 switch (typid)

2509 {

2510 case DATEOID:

2511 break;

2512 case TIMEOID:

2513 case TIMETZOID:

2515 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

2516 errmsg("%s format is not recognized: \"%s\"",

2518 break;

2519 case TIMESTAMPOID:

2522 break;

2523 case TIMESTAMPTZOID:

2525 "timestamptz", "date");

2528 break;

2529 default:

2530 elog(ERROR, "type with oid %u not supported", typid);

2531 }

2532

2533 typid = DATEOID;

2534 }

2535 break;

2537 {

2538

2539 switch (typid)

2540 {

2541 case DATEOID:

2543 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

2544 errmsg("%s format is not recognized: \"%s\"",

2546 break;

2547 case TIMEOID:

2548 break;

2549 case TIMETZOID:

2551 "timetz", "time");

2554 break;

2555 case TIMESTAMPOID:

2558 break;

2559 case TIMESTAMPTZOID:

2561 "timestamptz", "time");

2564 break;

2565 default:

2566 elog(ERROR, "type with oid %u not supported", typid);

2567 }

2568

2569

2570 if (time_precision != -1)

2571 {

2573

2574

2576 time_precision);

2580

2581

2582 typmod = time_precision;

2583 }

2584

2585 typid = TIMEOID;

2586 }

2587 break;

2589 {

2590

2591 switch (typid)

2592 {

2593 case DATEOID:

2594 case TIMESTAMPOID:

2596 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

2597 errmsg("%s format is not recognized: \"%s\"",

2599 break;

2600 case TIMEOID:

2602 "time", "timetz");

2605 break;

2606 case TIMETZOID:

2607 break;

2608 case TIMESTAMPTZOID:

2611 break;

2612 default:

2613 elog(ERROR, "type with oid %u not supported", typid);

2614 }

2615

2616

2617 if (time_precision != -1)

2618 {

2620

2621

2623 time_precision);

2627

2628

2629 typmod = time_precision;

2630 }

2631

2632 typid = TIMETZOID;

2633 }

2634 break;

2636 {

2637

2638 switch (typid)

2639 {

2640 case DATEOID:

2643 break;

2644 case TIMEOID:

2645 case TIMETZOID:

2647 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

2648 errmsg("%s format is not recognized: \"%s\"",

2650 break;

2651 case TIMESTAMPOID:

2652 break;

2653 case TIMESTAMPTZOID:

2655 "timestamptz", "timestamp");

2658 break;

2659 default:

2660 elog(ERROR, "type with oid %u not supported", typid);

2661 }

2662

2663

2664 if (time_precision != -1)

2665 {

2668

2669

2671 time_precision);

2674 (Node *) &escontext);

2675 if (escontext.error_occurred)

2677 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

2678 errmsg("time precision of jsonpath item method .%s() is invalid",

2681

2682

2683 typmod = time_precision;

2684 }

2685

2686 typid = TIMESTAMPOID;

2687 }

2688 break;

2690 {

2693

2694

2695 switch (typid)

2696 {

2697 case DATEOID:

2699 "date", "timestamptz");

2700

2701

2702

2703

2704

2711

2714 break;

2715 case TIMEOID:

2716 case TIMETZOID:

2718 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

2719 errmsg("%s format is not recognized: \"%s\"",

2721 break;

2722 case TIMESTAMPOID:

2724 "timestamp", "timestamptz");

2725

2726

2727

2728

2729

2731 &fsec, NULL, NULL) == 0)

2734

2737 break;

2738 case TIMESTAMPTZOID:

2739 break;

2740 default:

2741 elog(ERROR, "type with oid %u not supported", typid);

2742 }

2743

2744

2745 if (time_precision != -1)

2746 {

2749

2750

2752 time_precision);

2755 (Node *) &escontext);

2756 if (escontext.error_occurred)

2758 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

2759 errmsg("time precision of jsonpath item method .%s() is invalid",

2762

2763

2764 typmod = time_precision;

2765 }

2766

2767 typid = TIMESTAMPTZOID;

2768 }

2769 break;

2770 default:

2771 elog(ERROR, "unrecognized jsonpath item type: %d", jsp->type);

2772 }

2773

2774 pfree(datetime);

2775

2777 return res;

2778

2780

2781 if (!hasNext && !found)

2782 return res;

2783

2784 jb = hasNext ? &jbvbuf : palloc(sizeof(*jb));

2785

2787 jb->val.datetime.value = value;

2788 jb->val.datetime.typid = typid;

2789 jb->val.datetime.typmod = typmod;

2790 jb->val.datetime.tz = tz;

2791

2792 return executeNextItem(cxt, jsp, &elem, jb, found, hasNext);

2793}

2794

2795

2796

2797

2798

2799

2800

2801

2802

2803

2804

2805

2806

2807

2808

2809

2810

2811

2812

2813

2814

2815

2816

2817

2821{

2834 bool hasNext;

2835

2838 (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),

2839 errmsg("jsonpath item method .%s() can only be applied to an object",

2841

2842 jbc = jb->val.binary.data;

2843

2845 return jperNotFound;

2846

2848

2850 keystr.val.string.val = "key";

2851 keystr.val.string.len = 3;

2852

2854 valstr.val.string.val = "value";

2855 valstr.val.string.len = 5;

2856

2858 idstr.val.string.val = "id";

2859 idstr.val.string.len = 2;

2860

2861

2865

2868

2870

2872 {

2878

2880 continue;

2881

2883

2884 if (!hasNext && !found)

2885 break;

2886

2889

2890 ps = NULL;

2892

2895

2898

2901

2903

2905

2907

2909

2911

2913

2915 return res;

2916

2917 if (res == jperOk && !found)

2918 break;

2919 }

2920

2921 return res;

2922}

2923

2924

2925

2926

2927

2931{

2934

2936 return jperOk;

2937

2939 {

2941 }

2942 else

2943 {

2946 }

2947

2949}

2950

2951

2952

2953

2954

2955

2956static void

2959{

2960 switch (item->type)

2961 {

2964 break;

2968 break;

2972 break;

2976 &value->val.string.len);

2977 break;

2980 return;

2981 default:

2982 elog(ERROR, "unexpected jsonpath item type");

2983 }

2984}

2985

2986

2987

2988

2991 JsonbValue *baseObject, int *baseObjectId)

2992{

2997 int id = 1;

2998

2999 foreach(lc, vars)

3000 {

3002

3003 if (curvar->namelen == varNameLen &&

3004 strncmp(curvar->name, varName, varNameLen) == 0)

3005 {

3006 var = curvar;

3007 break;

3008 }

3009

3010 id++;

3011 }

3012

3013 if (var == NULL)

3014 {

3015 *baseObjectId = -1;

3016 return NULL;

3017 }

3018

3021 {

3022 *baseObjectId = 0;

3024 }

3025 else

3027

3028 *baseObject = *result;

3029 *baseObjectId = id;

3030

3031 return result;

3032}

3033

3034static int

3036{

3038

3040}

3041

3042

3043

3044

3045

3046

3047static void

3049{

3050 switch (typid)

3051 {

3052 case BOOLOID:

3055 break;

3056 case NUMERICOID:

3058 break;

3059 case INT2OID:

3061 break;

3062 case INT4OID:

3064 break;

3065 case INT8OID:

3067 break;

3068 case FLOAT4OID:

3070 break;

3071 case FLOAT8OID:

3073 break;

3074 case TEXTOID:

3075 case VARCHAROID:

3079 break;

3080 case DATEOID:

3081 case TIMEOID:

3082 case TIMETZOID:

3083 case TIMESTAMPOID:

3084 case TIMESTAMPTZOID:

3086 res->val.datetime.value = val;

3087 res->val.datetime.typid = typid;

3088 res->val.datetime.typmod = typmod;

3089 res->val.datetime.tz = 0;

3090 break;

3091 case JSONBOID:

3092 {

3095

3097 {

3099

3102 }

3103 else

3105 break;

3106 }

3107 case JSONOID:

3108 {

3112

3116

3118 break;

3119 }

3120 default:

3122 errcode(ERRCODE_INVALID_PARAMETER_VALUE),

3123 errmsg("could not convert value of type %s to jsonpath",

3125 }

3126}

3127

3128

3129static void

3131{

3134}

3135

3136

3137

3138

3139static void

3142{

3143 char *varName;

3144 int varNameLength;

3146 int baseObjectId;

3148

3151

3152 if (cxt->vars == NULL ||

3153 (v = cxt->getVar(cxt->vars, varName, varNameLength,

3154 &baseObject, &baseObjectId)) == NULL)

3156 (errcode(ERRCODE_UNDEFINED_OBJECT),

3157 errmsg("could not find jsonpath variable \"%s\"",

3158 pnstrdup(varName, varNameLength))));

3159

3160 if (baseObjectId > 0)

3161 {

3164 }

3165}

3166

3167

3168

3169

3170

3173 JsonbValue *baseObject, int *baseObjectId)

3174{

3178

3180 tmp.val.string.val = varName;

3181 tmp.val.string.len = varNameLength;

3182

3184

3185 if (result == NULL)

3186 {

3187 *baseObjectId = -1;

3188 return NULL;

3189 }

3190

3191 *baseObjectId = 1;

3193

3194 return result;

3195}

3196

3197

3198

3199

3200

3201static int

3203{

3205

3207 {

3209 errcode(ERRCODE_INVALID_PARAMETER_VALUE),

3210 errmsg("\"vars\" argument is not an object"),

3211 errdetail("Jsonpath parameters should be encoded as key-value pairs of \"vars\" object."));

3212 }

3213

3214

3215 return vars != NULL ? 1 : 0;

3216}

3217

3218

3219

3220

3221

3222

3223static int

3225{

3227

3229 {

3231

3234 }

3235

3236 return -1;

3237}

3238

3239

3242{

3244

3246}

3247

3248

3249

3250

3251static int

3253 const char *s2, int len2)

3254{

3255 int cmp;

3256

3257 cmp = memcmp(s1, s2, Min(len1, len2));

3258

3259 if (cmp != 0)

3260 return cmp;

3261

3262 if (len1 == len2)

3263 return 0;

3264

3265 return len1 < len2 ? -1 : 1;

3266}

3267

3268

3269

3270

3271

3272static int

3274 const char *mbstr2, int mblen2)

3275{

3278 {

3279

3280

3281

3282

3283

3285 }

3286 else

3287 {

3288 char *utf8str1,

3289 *utf8str2;

3290 int cmp,

3291 utf8len1,

3292 utf8len2;

3293

3294

3295

3296

3297

3298

3299

3302 utf8len1 = (mbstr1 == utf8str1) ? mblen1 : strlen(utf8str1);

3303 utf8len2 = (mbstr2 == utf8str2) ? mblen2 : strlen(utf8str2);

3304

3306

3307

3308

3309

3310

3311 if (mbstr1 == utf8str1 && mbstr2 == utf8str2)

3312 return cmp;

3313

3314

3315 if (mbstr1 != utf8str1)

3316 pfree(utf8str1);

3317 if (mbstr2 != utf8str2)

3318 pfree(utf8str2);

3319

3320

3321

3322

3323

3324

3325

3326

3327

3328

3329 if (cmp == 0)

3331 else

3332 return cmp;

3333 }

3334}

3335

3336

3337

3338

3341{

3342 int cmp;

3343 bool res;

3344

3346 {

3348

3349

3350

3351

3352

3354

3355

3357 }

3358

3359 switch (jb1->type)

3360 {

3362 cmp = 0;

3363 break;

3365 cmp = jb1->val.boolean == jb2->val.boolean ? 0 :

3366 jb1->val.boolean ? 1 : -1;

3367 break;

3370 break;

3373 return jb1->val.string.len != jb2->val.string.len ||

3374 memcmp(jb1->val.string.val,

3375 jb2->val.string.val,

3377

3379 jb2->val.string.val, jb2->val.string.len);

3380 break;

3382 {

3383 bool cast_error;

3384

3386 jb1->val.datetime.typid,

3387 jb2->val.datetime.value,

3388 jb2->val.datetime.typid,

3389 useTz,

3390 &cast_error);

3391

3392 if (cast_error)

3394 }

3395 break;

3396

3400 return jpbUnknown;

3401

3402 default:

3403 elog(ERROR, "invalid jsonb value type %d", jb1->type);

3404 }

3405

3406 switch (op)

3407 {

3409 res = (cmp == 0);

3410 break;

3412 res = (cmp != 0);

3413 break;

3415 res = (cmp < 0);

3416 break;

3418 res = (cmp > 0);

3419 break;

3421 res = (cmp <= 0);

3422 break;

3424 res = (cmp >= 0);

3425 break;

3426 default:

3427 elog(ERROR, "unrecognized jsonpath operation: %d", op);

3429 }

3430

3432}

3433

3434

3435static int

3437{

3441}

3442

3445{

3447

3448 *dst = *src;

3449

3450 return dst;

3451}

3452

3453

3454

3455

3456

3460{

3464 Datum numeric_index;

3465 bool have_error = false;

3466

3468 return res;

3469

3473 (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),

3474 errmsg("jsonpath array subscript is not a single numeric value"))));

3475

3479

3481 &have_error);

3482

3483 if (have_error)

3485 (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),

3486 errmsg("jsonpath array subscript is out of integer range"))));

3487

3489}

3490

3491

3494{

3496

3500

3501 return baseObject;

3502}

3503

3504static void

3506{

3509}

3510

3511static void

3513{

3515 {

3518 }

3519 else if (!jvl->list)

3521 else

3523}

3524

3525static int

3527{

3529}

3530

3531static bool

3533{

3535}

3536

3539{

3541}

3542

3543static List *

3545{

3548

3549 return jvl->list;

3550}

3551

3552static void

3554{

3556 {

3559 it->next = NULL;

3560 }

3561 else if (jvl->list != NIL)

3562 {

3566 }

3567 else

3568 {

3569 it->value = NULL;

3571 it->next = NULL;

3572 }

3573}

3574

3575

3576

3577

3580{

3582

3583 if (it->next)

3584 {

3587 }

3588 else

3589 {

3590 it->value = NULL;

3591 }

3592

3593 return result;

3594}

3595

3596

3597

3598

3601{

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

3605

3606 return jbv;

3607}

3608

3609

3610

3611

3612static int

3614{

3616

3618 {

3620

3621

3623

3628 else

3629 elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header);

3630 }

3631

3632 return type;

3633}

3634

3635

3638{

3639

3642

3643 return scalar->type == type ? scalar : NULL;

3644}

3645

3646

3649{

3653

3655

3659

3661}

3662

3663

3664static void

3666{

3667 if (!useTz)

3669 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

3670 errmsg("cannot convert value from %s to %s without time zone usage",

3671 type1, type2),

3672 errhint("Use *_tz() function for time zone support.")));

3673}

3674

3675

3678{

3680

3682}

3683

3684

3685

3686

3687

3688static int

3690{

3692}

3693

3694

3695

3696

3697static int

3699{

3701

3703}

3704

3705

3706

3707

3708static int

3710{

3712

3714}

3715

3716

3717

3718

3719

3720

3721static int

3723 bool useTz, bool *cast_error)

3724{

3726

3727 *cast_error = false;

3728

3729 switch (typid1)

3730 {

3731 case DATEOID:

3732 switch (typid2)

3733 {

3734 case DATEOID:

3736

3737 break;

3738

3739 case TIMESTAMPOID:

3742 useTz);

3743

3744 case TIMESTAMPTZOID:

3747 useTz);

3748

3749 case TIMEOID:

3750 case TIMETZOID:

3751 *cast_error = true;

3752 return 0;

3753

3754 default:

3755 elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",

3756 typid2);

3757 }

3758 break;

3759

3760 case TIMEOID:

3761 switch (typid2)

3762 {

3763 case TIMEOID:

3765

3766 break;

3767

3768 case TIMETZOID:

3771

3772 break;

3773

3774 case DATEOID:

3775 case TIMESTAMPOID:

3776 case TIMESTAMPTZOID:

3777 *cast_error = true;

3778 return 0;

3779

3780 default:

3781 elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",

3782 typid2);

3783 }

3784 break;

3785

3786 case TIMETZOID:

3787 switch (typid2)

3788 {

3789 case TIMEOID:

3792

3793 break;

3794

3795 case TIMETZOID:

3797

3798 break;

3799

3800 case DATEOID:

3801 case TIMESTAMPOID:

3802 case TIMESTAMPTZOID:

3803 *cast_error = true;

3804 return 0;

3805

3806 default:

3807 elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",

3808 typid2);

3809 }

3810 break;

3811

3812 case TIMESTAMPOID:

3813 switch (typid2)

3814 {

3815 case DATEOID:

3818 useTz);

3819

3820 case TIMESTAMPOID:

3822

3823 break;

3824

3825 case TIMESTAMPTZOID:

3828 useTz);

3829

3830 case TIMEOID:

3831 case TIMETZOID:

3832 *cast_error = true;

3833 return 0;

3834

3835 default:

3836 elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",

3837 typid2);

3838 }

3839 break;

3840

3841 case TIMESTAMPTZOID:

3842 switch (typid2)

3843 {

3844 case DATEOID:

3847 useTz);

3848

3849 case TIMESTAMPOID:

3852 useTz);

3853

3854 case TIMESTAMPTZOID:

3856

3857 break;

3858

3859 case TIMEOID:

3860 case TIMETZOID:

3861 *cast_error = true;

3862 return 0;

3863

3864 default:

3865 elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",

3866 typid2);

3867 }

3868 break;

3869

3870 default:

3871 elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u", typid1);

3872 }

3873

3874 if (*cast_error)

3875 return 0;

3876

3878}

3879

3880

3881

3882

3883

3884

3885

3886bool

3888{

3890

3894

3896

3899

3900 return res == jperOk;

3901}

3902

3903

3904

3905

3906

3907

3908

3912 const char *column_name)

3913{

3915 bool wrap;

3918 int count;

3919

3925 {

3927 *empty = false;

3928 return (Datum) 0;

3929 }

3930

3931

3932

3933

3934

3935

3936

3937

3938

3939

3940

3941

3942

3943

3944

3945

3946

3947

3948

3951 if (singleton == NULL)

3952 wrap = false;

3954 wrap = false;

3956 wrap = true;

3958 wrap = count > 1;

3959 else

3960 {

3961 elog(ERROR, "unrecognized json wrapper %d", (int) wrapper);

3962 wrap = false;

3963 }

3964

3965 if (wrap)

3967

3968

3969 if (count > 1)

3970 {

3972 {

3974 return (Datum) 0;

3975 }

3976

3977 if (column_name)

3979 (errcode(ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM),

3980 errmsg("JSON path expression for column \"%s\" must return single item when no wrapper is requested",

3981 column_name),

3982 errhint("Use the WITH WRAPPER clause to wrap SQL/JSON items into an array.")));

3983 else

3985 (errcode(ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM),

3986 errmsg("JSON path expression in JSON_QUERY must return single item when no wrapper is requested"),

3987 errhint("Use the WITH WRAPPER clause to wrap SQL/JSON items into an array.")));

3988 }

3989

3990 if (singleton)

3992

3993 *empty = true;

3995}

3996

3997

3998

3999

4000

4001

4002

4005 const char *column_name)

4006{

4010 int count;

4011

4014 error, &found, true);

4015

4017

4019 {

4021 *empty = false;

4022 return NULL;

4023 }

4024

4026

4027 *empty = (count == 0);

4028

4029 if (*empty)

4030 return NULL;

4031

4032

4033 if (count > 1)

4034 {

4036 {

4038 return NULL;

4039 }

4040

4041 if (column_name)

4043 (errcode(ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM),

4044 errmsg("JSON path expression for column \"%s\" must return single scalar item",

4045 column_name)));

4046 else

4048 (errcode(ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM),

4049 errmsg("JSON path expression in JSON_VALUE must return single scalar item")));

4050 }

4051

4055

4056

4058 {

4060 {

4062 return NULL;

4063 }

4064

4065 if (column_name)

4067 (errcode(ERRCODE_SQL_JSON_SCALAR_REQUIRED),

4068 errmsg("JSON path expression for column \"%s\" must return single scalar item",

4069 column_name)));

4070 else

4072 (errcode(ERRCODE_SQL_JSON_SCALAR_REQUIRED),

4073 errmsg("JSON path expression in JSON_VALUE must return single scalar item")));

4074 }

4075

4077 return NULL;

4078

4079 return res;

4080}

4081

4082

4083

4084

4085

4086

4087

4090{

4092

4094 elog(ERROR, "%s called with invalid TableFuncScanState", fname);

4097 elog(ERROR, "%s called with invalid TableFuncScanState", fname);

4098

4099 return result;

4100}

4101

4102

4103

4104

4105

4106

4107

4108

4109static void

4111{

4119

4122

4123

4124

4125

4126

4127 if (state->passingvalexprs)

4128 {

4131

4135 namelc, je->passing_names)

4136 {

4140

4145

4146

4147

4148

4149

4152

4154 }

4155 }

4156

4159

4160

4161

4162

4163

4166

4167 state->opaque = cxt;

4168}

4169

4170

4171

4172

4173

4174static void

4176{

4179

4180

4182

4183 state->opaque = NULL;

4184}

4185

4186

4187

4188

4189

4190

4195{

4197

4199 planstate->parent = parentstate;

4200

4202 {

4204 int i;

4205

4210

4211

4214

4215 for (i = scan->colMin; i >= 0 && i <= scan->colMax; i++)

4217

4220 }

4222 {

4224

4226 args, mcxt);

4228 args, mcxt);

4229 }

4230

4231 return planstate;

4232}

4233

4234

4235

4236

4237

4238static void

4240{

4243

4245}

4246

4247

4248

4249

4250

4251static void

4253{

4258

4260

4262

4264

4268 &planstate->found,

4269 true);

4270

4272

4274 {

4277 }

4278

4279

4284}

4285

4286

4287

4288

4289

4290

4291static bool

4293{

4298 else

4299 elog(ERROR, "invalid JsonTablePlan %d", (int) planstate->plan->type);

4300

4302

4303 return false;

4304}

4305

4306

4307

4308

4309

4310

4311

4312

4313

4314

4315

4316

4317

4318static bool

4320{

4323

4324

4325

4326

4327

4329 {

4331 return true;

4332 }

4333

4334

4336

4337

4338 if (jbv == NULL)

4339 {

4342 return false;

4343 }

4344

4345

4346

4347

4348

4353

4354

4356

4357

4358 if (planstate->nested)

4359 {

4360

4362

4363

4364

4365

4366

4367

4368

4370 }

4371

4372

4373 return true;

4374}

4375

4376

4377

4378

4379

4380static void

4382{

4383

4386 {

4388

4391

4392

4393

4394

4395

4396 }

4398 {

4401 }

4402}

4403

4404

4405

4406

4407

4408

4409static bool

4411{

4412

4413

4415 {

4416

4417

4418

4419

4421 {

4422

4423 return false;

4424 }

4425 }

4426

4427 return true;

4428}

4429

4430

4431

4432

4433

4434

4435

4436static bool

4438{

4441

4443}

4444

4445

4446

4447

4448

4449

4450

4451

4454 Oid typid, int32 typmod, bool *isnull)

4455{

4463

4464

4465 if (current->isnull)

4466 {

4467 result = (Datum) 0;

4468 *isnull = true;

4469 }

4470

4471 else if (estate)

4472 {

4475

4476

4479

4480 result = ExecEvalExpr(estate, econtext, isnull);

4481

4484 }

4485

4486 else

4487 {

4489 *isnull = false;

4490 }

4491

4492 return result;

4493}

ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)

int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)

void j2date(int jd, int *year, int *month, int *day)

int32 numeric_int4_opt_error(Numeric num, bool *have_error)

Datum float8_numeric(PG_FUNCTION_ARGS)

Datum numeric_cmp(PG_FUNCTION_ARGS)

Numeric numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)

Numeric numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)

Numeric int64_to_numeric(int64 val)

Datum float4_numeric(PG_FUNCTION_ARGS)

Datum int4_numeric(PG_FUNCTION_ARGS)

Datum numeric_uminus(PG_FUNCTION_ARGS)

Datum numeric_ceil(PG_FUNCTION_ARGS)

Datum numerictypmodin(PG_FUNCTION_ARGS)

Datum numeric_out(PG_FUNCTION_ARGS)

int64 numeric_int8_opt_error(Numeric num, bool *have_error)

Datum numeric_trunc(PG_FUNCTION_ARGS)

Datum numeric_in(PG_FUNCTION_ARGS)

bool numeric_is_nan(Numeric num)

Numeric numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)

Numeric numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)

Datum int2_numeric(PG_FUNCTION_ARGS)

Datum numeric_abs(PG_FUNCTION_ARGS)

Datum int8_numeric(PG_FUNCTION_ARGS)

Numeric numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)

bool numeric_is_inf(Numeric num)

Datum numeric_floor(PG_FUNCTION_ARGS)

Datum timestamp_cmp(PG_FUNCTION_ARGS)

bool AdjustTimestampForTypmod(Timestamp *time, int32 typmod, Node *escontext)

Datum timestamp_timestamptz(PG_FUNCTION_ARGS)

int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)

int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)

int32 anytimestamp_typmod_check(bool istz, int32 typmod)

Datum timestamptz_timestamp(PG_FUNCTION_ARGS)

bool parse_bool(const char *value, bool *result)

#define PG_USED_FOR_ASSERTS_ONLY

#define POSTGRES_EPOCH_JDATE

int32 date_cmp_timestamp_internal(DateADT dateVal, Timestamp dt2)

Datum date_cmp(PG_FUNCTION_ARGS)

Datum time_cmp(PG_FUNCTION_ARGS)

Datum timestamp_time(PG_FUNCTION_ARGS)

int32 anytime_typmod_check(bool istz, int32 typmod)

Datum date_timestamptz(PG_FUNCTION_ARGS)

Datum timetz_cmp(PG_FUNCTION_ARGS)

Datum timetz_time(PG_FUNCTION_ARGS)

Datum time_timetz(PG_FUNCTION_ARGS)

Datum timestamptz_timetz(PG_FUNCTION_ARGS)

void AdjustTimeForTypmod(TimeADT *time, int32 typmod)

Datum timestamptz_date(PG_FUNCTION_ARGS)

Datum timestamp_date(PG_FUNCTION_ARGS)

int32 date_cmp_timestamptz_internal(DateADT dateVal, TimestampTz dt2)

Datum timestamptz_time(PG_FUNCTION_ARGS)

Datum date_timestamp(PG_FUNCTION_ARGS)

static TimeTzADT * DatumGetTimeTzADTP(Datum X)

static DateADT DatumGetDateADT(Datum X)

static TimeADT DatumGetTimeADT(Datum X)

static Datum TimeTzADTPGetDatum(const TimeTzADT *X)

static Datum TimeADTGetDatum(TimeADT X)

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

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

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)

float8 float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)

Datum Int64GetDatum(int64 X)

Datum Float8GetDatum(float8 X)

bool DirectInputFunctionCallSafe(PGFunction func, char *str, Oid typioparam, int32 typmod, fmNodePtr escontext, Datum *result)

#define PG_FREE_IF_COPY(ptr, n)

#define DirectFunctionCall2(func, arg1, arg2)

#define DirectFunctionCall1(func, arg1)

#define PG_GETARG_BOOL(n)

Datum(* PGFunction)(FunctionCallInfo fcinfo)

#define PG_RETURN_BOOL(x)

char * format_type_be(Oid type_oid)

Datum parse_datetime(text *date_txt, text *fmt, Oid collid, bool strict, Oid *typid, int32 *typmod, int *tz, Node *escontext)

#define SRF_IS_FIRSTCALL()

#define SRF_PERCALL_SETUP()

#define SRF_RETURN_NEXT(_funcctx, _result)

#define SRF_FIRSTCALL_INIT()

#define SRF_RETURN_DONE(_funcctx)

Assert(PointerIsAligned(start, uint64))

Datum int8in(PG_FUNCTION_ARGS)

Datum int4in(PG_FUNCTION_ARGS)

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

char * JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp)

Datum jsonb_in(PG_FUNCTION_ARGS)

const char * JsonbTypeName(JsonbValue *val)

bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)

#define JsonContainerIsScalar(jc)

#define JsonContainerIsArray(jc)

#define JsonContainerSize(jc)

#define PG_GETARG_JSONB_P_COPY(x)

static Datum JsonbPGetDatum(const Jsonb *p)

#define IsAJsonbScalar(jsonbval)

#define PG_RETURN_JSONB_P(x)

#define PG_GETARG_JSONB_P(x)

#define JsonContainerIsObject(jc)

static Jsonb * DatumGetJsonbP(Datum d)

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

JsonbIterator * JsonbIteratorInit(JsonbContainer *container)

JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)

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

JsonbValue * getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)

Jsonb * JsonbValueToJsonb(JsonbValue *val)

void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)

void jspGetArg(JsonPathItem *v, JsonPathItem *a)

void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)

bool jspGetBool(JsonPathItem *v)

void jspInit(JsonPathItem *v, JsonPath *js)

char * jspGetString(JsonPathItem *v, int32 *len)

Numeric jspGetNumeric(JsonPathItem *v)

bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)

const char * jspOperationName(JsonPathItemType type)

bool jspGetNext(JsonPathItem *v, JsonPathItem *a)

void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)

bool jspConvertRegexFlags(uint32 xflags, int *result, struct Node *escontext)

#define PG_GETARG_JSONPATH_P(x)

#define PG_GETARG_JSONPATH_P_COPY(x)

static JsonPath * DatumGetJsonPathP(Datum d)

static JsonPathBool executeComparison(JsonPathItem *cmp, JsonbValue *lv, JsonbValue *rv, void *p)

bool JsonPathExists(Datum jb, JsonPath *jp, bool *error, List *vars)

static Datum jsonb_path_query_first_internal(FunctionCallInfo fcinfo, bool tz)

static JsonPathExecResult executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrap)

Datum jsonb_path_query_tz(PG_FUNCTION_ARGS)

#define jspAutoUnwrap(cxt)

Datum jsonb_path_exists_opr(PG_FUNCTION_ARGS)

static int cmpDateToTimestamp(DateADT date1, Timestamp ts2, bool useTz)

static JsonPathBool executeBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool canHaveNext)

static int JsonbArraySize(JsonbValue *jb)

struct JsonBaseObjectInfo JsonBaseObjectInfo

Numeric(* BinaryArithmFunc)(Numeric num1, Numeric num2, bool *error)

static void JsonTableResetRowPattern(JsonTablePlanState *planstate, Datum item)

struct JsonTablePlanState JsonTablePlanState

static List * JsonValueListGetList(JsonValueList *jvl)

struct JsonValueList JsonValueList

static int compareStrings(const char *mbstr1, int mblen1, const char *mbstr2, int mblen2)

static JsonPathExecResult appendBoolResult(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonValueList *found, JsonPathBool res)

Datum jsonb_path_query_first(PG_FUNCTION_ARGS)

static void JsonTableSetDocument(TableFuncScanState *state, Datum value)

static Datum jsonb_path_query_array_internal(FunctionCallInfo fcinfo, bool tz)

static JsonPathExecResult executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, BinaryArithmFunc func, JsonValueList *found)

static int countVariablesFromJsonb(void *varsJsonb)

static JsonTableExecContext * GetJsonTableExecContext(TableFuncScanState *state, const char *fname)

static Datum jsonb_path_query_internal(FunctionCallInfo fcinfo, bool tz)

#define RETURN_ERROR(throw_error)

#define JSON_TABLE_EXEC_CONTEXT_MAGIC

static JsonPathExecResult executeItemOptUnwrapResultNoThrow(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)

static JsonPathExecResult executeAnyItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbContainer *jbc, JsonValueList *found, uint32 level, uint32 first, uint32 last, bool ignoreStructuralErrors, bool unwrapNext)

static JsonPathExecResult executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)

static JsonPathBool executeStartsWith(JsonPathItem *jsp, JsonbValue *whole, JsonbValue *initial, void *param)

static Datum jsonb_path_match_internal(FunctionCallInfo fcinfo, bool tz)

static JsonBaseObjectInfo setBaseObject(JsonPathExecContext *cxt, JsonbValue *jbv, int32 id)

static Datum castTimeToTimeTz(Datum time, bool useTz)

static void JsonValueListAppend(JsonValueList *jvl, JsonbValue *jbv)

static JsonPathExecResult executeUnaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, PGFunction func, JsonValueList *found)

Datum JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper, bool *empty, bool *error, List *vars, const char *column_name)

static int JsonbType(JsonbValue *jb)

static void JsonTableResetNestedPlan(JsonTablePlanState *planstate)

static JsonPathExecResult executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)

static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)

static void JsonItemFromDatum(Datum val, Oid typid, int32 typmod, JsonbValue *res)

struct JsonPathExecContext JsonPathExecContext

JsonbValue *(* JsonPathGetVarCallback)(void *vars, char *varName, int varNameLen, JsonbValue *baseObject, int *baseObjectId)

Datum jsonb_path_match_tz(PG_FUNCTION_ARGS)

static JsonPathExecResult executeItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)

Datum jsonb_path_query(PG_FUNCTION_ARGS)

static bool JsonTablePlanScanNextRow(JsonTablePlanState *planstate)

Datum jsonb_path_match_opr(PG_FUNCTION_ARGS)

JsonPathBool(* JsonPathPredicateCallback)(JsonPathItem *jsp, JsonbValue *larg, JsonbValue *rarg, void *param)

static JsonbValue * getJsonPathVariableFromJsonb(void *varsJsonb, char *varName, int varNameLength, JsonbValue *baseObject, int *baseObjectId)

static JsonbValue * GetJsonPathVar(void *cxt, char *varName, int varNameLen, JsonbValue *baseObject, int *baseObjectId)

struct JsonTablePlanRowSource JsonTablePlanRowSource

static void JsonValueListInitIterator(const JsonValueList *jvl, JsonValueListIterator *it)

static JsonPathBool executeNestedBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb)

static int compareDatetime(Datum val1, Oid typid1, Datum val2, Oid typid2, bool useTz, bool *cast_error)

static int cmpDateToTimestampTz(DateADT date1, TimestampTz tstz2, bool useTz)

Datum jsonb_path_match(PG_FUNCTION_ARGS)

static JsonbValue * wrapItemsInArray(const JsonValueList *items)

static JsonbValue * JsonValueListNext(const JsonValueList *jvl, JsonValueListIterator *it)

#define jspStrictAbsenceOfErrors(cxt)

static void JsonTableDestroyOpaque(TableFuncScanState *state)

static void JsonValueListClear(JsonValueList *jvl)

static void JsonTableInitOpaque(TableFuncScanState *state, int natts)

static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)

Datum jsonb_path_exists(PG_FUNCTION_ARGS)

#define jperIsError(jper)

static Datum jsonb_path_exists_internal(FunctionCallInfo fcinfo, bool tz)

JsonbValue * JsonPathValue(Datum jb, JsonPath *jp, bool *empty, bool *error, List *vars, const char *column_name)

static bool JsonTablePlanNextRow(JsonTablePlanState *planstate)

struct JsonValueListIterator JsonValueListIterator

Datum jsonb_path_query_array_tz(PG_FUNCTION_ARGS)

static JsonTablePlanState * JsonTableInitPlan(JsonTableExecContext *cxt, JsonTablePlan *plan, JsonTablePlanState *parentstate, List *args, MemoryContext mcxt)

static JsonPathExecResult executeItemUnwrapTargetArray(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrapElements)

static int cmpTimestampToTimestampTz(Timestamp ts1, TimestampTz tstz2, bool useTz)

static JsonPathBool executeLikeRegex(JsonPathItem *jsp, JsonbValue *str, JsonbValue *rarg, void *param)

static int JsonValueListLength(const JsonValueList *jvl)

static bool JsonValueListIsEmpty(JsonValueList *jvl)

#define jspIgnoreStructuralErrors(cxt)

struct JsonLikeRegexContext JsonLikeRegexContext

static void JsonbValueInitNumericDatum(JsonbValue *jbv, Datum num)

static int CountJsonPathVars(void *cxt)

struct JsonTableExecContext JsonTableExecContext

static int compareNumeric(Numeric a, Numeric b)

static Datum JsonTableGetValue(TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)

static JsonPathBool compareItems(int32 op, JsonbValue *jb1, JsonbValue *jb2, bool useTz)

static JsonPathExecResult getArrayIndex(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, int32 *index)

Datum jsonb_path_query_first_tz(PG_FUNCTION_ARGS)

Datum jsonb_path_query_array(PG_FUNCTION_ARGS)

static JsonPathExecResult executeItemOptUnwrapResult(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)

static JsonPathExecResult executeNumericItemMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, PGFunction func, JsonValueList *found)

static void getJsonPathVariable(JsonPathExecContext *cxt, JsonPathItem *variable, JsonbValue *value)

static JsonbValue * JsonValueListHead(JsonValueList *jvl)

Datum jsonb_path_exists_tz(PG_FUNCTION_ARGS)

static bool JsonTableFetchRow(TableFuncScanState *state)

static void getJsonPathItem(JsonPathExecContext *cxt, JsonPathItem *item, JsonbValue *value)

static JsonPathBool executePredicate(JsonPathExecContext *cxt, JsonPathItem *pred, JsonPathItem *larg, JsonPathItem *rarg, JsonbValue *jb, bool unwrapRightArg, JsonPathPredicateCallback exec, void *param)

static int binaryCompareStrings(const char *s1, int len1, const char *s2, int len2)

const TableFuncRoutine JsonbTableRoutine

int(* JsonPathCountVarsCallback)(void *vars)

static JsonbValue * JsonbInitBinary(JsonbValue *jbv, Jsonb *jb)

static void checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2)

static JsonPathExecResult executeJsonPath(JsonPath *path, void *vars, JsonPathGetVarCallback getVar, JsonPathCountVarsCallback countVars, Jsonb *json, bool throwErrors, JsonValueList *result, bool useTz)

static bool JsonTablePlanJoinNextRow(JsonTablePlanState *planstate)

#define jspThrowErrors(cxt)

static JsonbValue * copyJsonbValue(JsonbValue *src)

List * lappend(List *list, void *datum)

List * list_delete_first(List *list)

int GetDatabaseEncoding(void)

char * pg_server_to_any(const char *s, int len, int encoding)

char * pstrdup(const char *in)

void pfree(void *pointer)

void * palloc0(Size size)

MemoryContext TopMemoryContext

MemoryContext CurrentMemoryContext

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

void MemoryContextResetOnly(MemoryContext context)

#define AllocSetContextCreate

#define ALLOCSET_DEFAULT_SIZES

#define CHECK_FOR_INTERRUPTS()

Oid exprType(const Node *expr)

int32 exprTypmod(const Node *expr)

#define IsA(nodeptr, _type_)

#define castNode(_type_, nodeptr)

static Numeric DatumGetNumeric(Datum X)

struct NumericData * Numeric

static Datum NumericGetDatum(Numeric X)

int pg_ltoa(int32 value, char *a)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

#define lfirst_node(type, lc)

static int list_length(const List *l)

#define forboth(cell1, list1, cell2, list2)

static void * list_nth(const List *list, int n)

static ListCell * list_head(const List *l)

static ListCell * list_second_cell(const List *l)

static ListCell * lnext(const List *l, const ListCell *c)

#define list_make2(x1, x2)

PGDLLIMPORT pg_tz * session_timezone

static bool DatumGetBool(Datum X)

static Datum PointerGetDatum(const void *X)

static char * DatumGetCString(Datum X)

static Datum CStringGetDatum(const char *X)

static Datum Int32GetDatum(int32 X)

static int32 DatumGetInt32(Datum X)

static int cmp(const chr *x, const chr *y, size_t len)

static struct cvec * range(struct vars *v, chr a, chr b, int cases)

bool RE_compile_and_execute(text *text_re, char *dat, int dat_len, int cflags, Oid collation, int nmatch, regmatch_t *pmatch)

void check_stack_depth(void)

MemoryContext multi_call_memory_ctx

bool ignoreStructuralErrors

JsonPathGetVarCallback getVar

int lastGeneratedObjectId

JsonBaseObjectInfo baseObject

struct JsonPathItem::@147::@148 args

union JsonPathItem::@147 content

struct JsonPathItem::@147::@149 array

struct JsonPathItem::@147::@150 anybounds

struct JsonPathItem::@147::@152 like_regex

JsonTablePlanState * rootplanstate

JsonTablePlanState ** colplanstates

struct JsonTablePlanState * left

struct JsonTablePlanState * nested

struct JsonTablePlanState * parent

struct JsonTablePlanState * right

JsonTablePlanRowSource current

JsonValueListIterator iter

void(* InitOpaque)(struct TableFuncScanState *state, int natts)

static Datum TimestampTzGetDatum(TimestampTz X)

static Datum TimestampGetDatum(Timestamp X)

static Timestamp DatumGetTimestamp(Datum X)

static TimestampTz DatumGetTimestampTz(Datum X)

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