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 Node *escontext);

257

261 Jsonb *json, bool throwErrors,

285 bool ignoreStructuralErrors, bool unwrapNext);

312 JsonbValue *baseObject, int *baseObjectId);

321 int varNameLength,

323 int *baseObjectId);

328 bool useTz);

350 bool useTz, bool *cast_error);

352 const char *type2);

353

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

370

372{

375 .SetNamespace = NULL,

376 .SetRowFilter = NULL,

377 .SetColumnFilter = NULL,

381};

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

399{

404 bool silent = true;

405

407 {

410 }

411

414 jb, !silent, NULL, tz);

415

418

421

423}

424

427{

429}

430

433{

435}

436

437

438

439

440

441

444{

445

447}

448

449

450

451

452

453

456{

461 bool silent = true;

462

464 {

467 }

468

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

472

475

477 {

479

482

485 }

486

487 if (!silent)

489 (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),

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

491

493}

494

497{

499}

500

503{

505}

506

507

508

509

510

511

514{

515

517}

518

519

520

521

522

523

526{

531

533 {

538 bool silent;

540

543

548

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

552

554

556 }

557

560

562

563 if (c == NULL)

565

568

570}

571

574{

576}

577

580{

582}

583

584

585

586

587

588

591{

597

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

601

603}

604

607{

609}

610

613{

615}

616

617

618

619

620

621

624{

630

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

634

637 else

639}

640

643{

645}

646

649{

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

676

681 bool useTz)

682{

687

689

692

697 cxt.root = &jbv;

701

705 cxt.useTz = useTz;

706

708 {

709

710

711

712

714

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

716

718 return res;

719

721 }

722

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

724

726

727 return res;

728}

729

730

731

732

736{

738}

739

740

741

742

743

744

748{

752

755

756 switch (jsp->type)

757 {

763 {

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

767

769 {

770

771

772

773

775 break;

776 }

777

779

782

784 v, found, hasNext);

786 }

787 break;

788

789

803 {

805

807 break;

808 }

809

813

817

821

825

829

832

835 found);

836

839 {

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

841

844 }

849 (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),

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

851 break;

852

855 {

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

857

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

860

862 (cxt, hasNext ? &elem : NULL,

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

865 }

869 {

872 (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),

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

874 }

875 break;

876

879 {

881 int i;

883 bool singleton = size < 0;

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

885

886 if (singleton)

887 size = 1;

888

890

892 {

896 int32 index_from;

899 &to, i);

900

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

902

904 break;

905

907 {

909

911 break;

912 }

913 else

914 index_to = index_from;

915

917 (index_from < 0 ||

918 index_from > index_to ||

919 index_to >= size))

921 (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),

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

923

924 if (index_from < 0)

925 index_from = 0;

926

927 if (index_to >= size)

928 index_to = size - 1;

929

931

933 {

935 bool copy;

936

937 if (singleton)

938 {

939 v = jb;

940 copy = true;

941 }

942 else

943 {

946

947 if (v == NULL)

948 continue;

949

950 copy = false;

951 }

952

953 if (!hasNext && !found)

955

957 copy);

958

960 break;

961

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

963 break;

964 }

965

967 break;

968

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

970 break;

971 }

972

974 }

976 {

978 (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),

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

980 }

981 break;

982

984 {

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

986

987

989 {

990 bool savedIgnoreStructuralErrors;

991

995 jb, found, true);

997

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

999 break;

1000 }

1001

1004 (cxt, hasNext ? &elem : NULL,

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

1006 1,

1010 break;

1011 }

1012

1015 {

1018

1021

1024

1025 if (v != NULL)

1026 {

1028 v, found, false);

1029

1030

1033 }

1035 {

1037

1040

1042 (errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND), \

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

1045 key.val.string.len))));

1046 }

1047 }

1051 {

1054 (errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND),

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

1056 }

1057 break;

1058

1061 found, true);

1062 break;

1063

1065 jb = cxt->root;

1069 break;

1070

1072 {

1074

1077 false);

1078

1083 else

1085 jb, found, true);

1086 break;

1087 }

1088

1090 {

1092

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

1096

1098 found, false);

1099 }

1100 break;

1101

1103 {

1105

1106 if (size < 0)

1107 {

1109 {

1112 (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),

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

1115 break;

1116 }

1117

1118 size = 1;

1119 }

1120

1122

1125

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

1127 }

1128 break;

1129

1132 found);

1133

1136 found);

1137

1140 found);

1141

1143 {

1145

1148 false);

1149

1151 {

1154 double val;

1156

1158 NULL,

1159 "double precision",

1160 tmp,

1161 (Node *) &escontext);

1162

1165 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1168 if (isinf(val) || isnan(val))

1170 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1174 }

1176 {

1177

1178 double val;

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

1180 jb->val.string.len);

1182

1184 NULL,

1185 "double precision",

1186 tmp,

1187 (Node *) &escontext);

1188

1191 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1194 if (isinf(val) || isnan(val))

1196 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1199

1200 jb = &jbv;

1205 }

1206

1209 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1212

1214 }

1215 break;

1216

1225

1227

1231

1233

1235 {

1238 int last;

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

1240

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

1243

1244 if (!hasNext && !found)

1245 {

1247 break;

1248 }

1249

1251

1253

1256

1258 lastjbv, found, hasNext);

1259 }

1260 break;

1261

1263 {

1266

1269 false);

1270

1272 {

1275

1277 (Node *) &escontext);

1280 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1285 "bigint"))));

1286

1289 }

1291 {

1292

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

1294 jb->val.string.len);

1296 bool noerr;

1297

1300 (Node *) &escontext,

1301 &datum);

1302

1305 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1309 }

1310

1313 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1316

1317 jb = &jbv;

1320 datum));

1321

1323 }

1324 break;

1325

1327 {

1329 bool bval;

1330

1333 false);

1334

1336 {

1337 bval = jb->val.boolean;

1338

1340 }

1342 {

1343 int ival;

1345 bool noerr;

1349

1352 (Node *) &escontext,

1353 &datum);

1354

1357 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1360

1362 if (ival == 0)

1363 bval = false;

1364 else

1365 bval = true;

1366

1368 }

1370 {

1371

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

1373 jb->val.string.len);

1374

1377 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1380

1382 }

1383

1386 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1389

1390 jb = &jbv;

1392 jb->val.boolean = bval;

1393

1395 }

1396 break;

1397

1400 {

1403 char *numstr = NULL;

1404

1407 false);

1408

1410 {

1411 num = jb->val.numeric;

1414 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1417

1422 }

1424 {

1425

1427 bool noerr;

1429

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

1431

1434 (Node *) &escontext,

1435 &datum);

1436

1439 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1442

1446 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1449

1451 }

1452

1455 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1458

1459

1460

1461

1462

1463

1464

1466 {

1469 int32 precision;

1471 bool noerr;

1473 Datum datums[2];

1474 char pstr[12];

1475 char sstr[12];

1477

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

1481

1483 (Node *) &escontext);

1486 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1489

1491 {

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

1495

1497 (Node *) &escontext);

1498 if (escontext.error_occurred)

1500 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1503 }

1504

1505

1506

1507

1508

1509 pg_ltoa(precision, pstr);

1514

1517

1518

1519 Assert(numstr != NULL);

1522 (Node *) &escontext,

1523 &numdatum);

1524

1527 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1530

1532 pfree(arrtypmod);

1533 }

1534

1535 jb = &jbv;

1537 jb->val.numeric = num;

1538

1540 }

1541 break;

1542

1544 {

1547

1550 false);

1551

1553 {

1556

1558 (Node *) &escontext);

1561 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1566

1569 }

1571 {

1572

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

1574 jb->val.string.len);

1576 bool noerr;

1577

1580 (Node *) &escontext,

1581 &datum);

1582

1585 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1589 }

1590

1593 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1596

1597 jb = &jbv;

1600 datum));

1601

1603 }

1604 break;

1605

1607 {

1609 char *tmp = NULL;

1610

1613

1615 {

1617

1618

1619

1620

1621

1623 jb->val.string.len);

1624 break;

1628 break;

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

1631 break;

1633 {

1635

1637 jb->val.datetime.value,

1638 jb->val.datetime.typid,

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

1641 }

1642 break;

1648 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

1651 break;

1652 }

1653

1654 jb = &jbv;

1655 Assert(tmp != NULL);

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

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

1659

1661 }

1662 break;

1663

1664 default:

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

1666 }

1667

1668 return res;

1669}

1670

1671

1672

1673

1677 bool unwrapElements)

1678{

1680 {

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

1683 }

1684

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

1687 false, unwrapElements);

1688}

1689

1690

1691

1692

1693

1698{

1700 bool hasNext;

1701

1702 if (cur)

1703 hasNext = next != NULL;

1704 else if (next)

1706 else

1707 {

1708 next = &elem;

1710 }

1711

1712 if (hasNext)

1714

1715 if (found)

1717

1719}

1720

1721

1722

1723

1724

1729{

1731 {

1736

1738 return res;

1739

1742 {

1744

1747 else

1749 }

1750

1752 }

1753

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

1755}

1756

1757

1758

1759

1765{

1768

1772

1773 return res;

1774}

1775

1776

1780{

1785

1786

1788

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

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

1791

1792 switch (jsp->type)

1793 {

1797

1800

1801

1802

1803

1804

1805

1808

1809 return res2 == jpbTrue ? res : res2;

1810

1814

1817

1820

1821 return res2 == jpbFalse ? res : res2;

1822

1825

1827

1830

1832

1837

1848

1849 case jpiStartsWith:

1854

1855 case jpiLikeRegex:

1856 {

1857

1858

1859

1860

1861

1862

1864

1867

1870 }

1871

1874

1876 {

1877

1878

1879

1880

1884 false, &vals);

1885

1888

1890 }

1891 else

1892 {

1895 false, NULL);

1896

1899

1901 }

1902

1903 default:

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

1906 }

1907}

1908

1909

1910

1911

1912

1916{

1919

1924

1925 return res;

1926}

1927

1928

1929

1930

1931

1932

1933

1937 bool ignoreStructuralErrors, bool unwrapNext)

1938{

1943

1945

1946 if (level > last)

1947 return res;

1948

1950

1951

1952

1953

1955 {

1957 {

1960 }

1961

1963 {

1964

1965 if (level >= first ||

1967 v.type != jbvBinary))

1968 {

1969

1970 if (jsp)

1971 {

1972 if (ignoreStructuralErrors)

1973 {

1974 bool savedIgnoreStructuralErrors;

1975

1980 }

1981 else

1983

1985 break;

1986

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

1988 break;

1989 }

1990 else if (found)

1992 else

1994 }

1995

1997 {

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

2000 level + 1, first, last,

2001 ignoreStructuralErrors, unwrapNext);

2002

2004 break;

2005

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

2007 break;

2008 }

2009 }

2010 }

2011

2012 return res;

2013}

2014

2015

2016

2017

2018

2019

2020

2021

2022

2023

2024

2029 void *param)

2030{

2036 bool error = false;

2037 bool found = false;

2038

2039

2043

2044 if (rarg)

2045 {

2046

2048 unwrapRightArg, &rseq);

2051 }

2052

2055 {

2058 bool first = true;

2059

2061 if (rarg)

2063 else

2064 rval = NULL;

2065

2066

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

2068 {

2070

2072 {

2075

2077 }

2078 else if (res == jpbTrue)

2079 {

2082

2083 found = true;

2084 }

2085

2086 first = false;

2087 if (rarg)

2089 }

2090 }

2091

2092 if (found)

2094

2095 if (error)

2097

2099}

2100

2101

2102

2103

2104

2109{

2117

2119

2120

2121

2122

2123

2126 return jper;

2127

2129

2132 return jper;

2133

2137 (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),

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

2140

2144 (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),

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

2147

2149 {

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

2151 }

2152 else

2153 {

2155

2156 res = func(lval->val.numeric, rval->val.numeric, (Node *) &escontext);

2157

2160 }

2161

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

2164

2167 lval->val.numeric = res;

2168

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

2170}

2171

2172

2173

2174

2175

2179{

2186 bool hasNext;

2187

2190

2192 return jper;

2193

2195

2197

2200 {

2202 {

2203 if (!found && !hasNext)

2205 }

2206 else

2207 {

2208 if (!found && !hasNext)

2209 continue;

2210

2212 (errcode(ERRCODE_SQL_JSON_NUMBER_NOT_FOUND),

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

2215 }

2216

2217 if (func)

2218 val->val.numeric =

2221

2223

2225 return jper2;

2226

2227 if (jper2 == jperOk)

2228 {

2229 if (!found)

2232 }

2233 }

2234

2235 return jper;

2236}

2237

2238

2239

2240

2241

2242

2245 void *param)

2246{

2249

2252

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

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

2255 initial->val.string.val,

2256 initial->val.string.len))

2258

2260}

2261

2262

2263

2264

2265

2266

2269 void *param)

2270{

2272

2275

2276

2277 if (!cxt->regex)

2278 {

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

2284 }

2285

2287 str->val.string.len,

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

2290

2292}

2293

2294

2295

2296

2297

2302{

2305

2308

2311 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),

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

2314

2316

2319

2323

2325}

2326

2327

2328

2329

2330

2331

2332

2333

2334

2335

2336

2337

2338

2342{

2345 text *datetime;

2347 Oid typid;

2348 int32 typmod = -1;

2349 int tz = 0;

2350 bool hasNext;

2353 int32 time_precision = -1;

2354

2357 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

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

2360

2362 jb->val.string.len);

2363

2364

2365

2366

2367

2368

2369 collid = DEFAULT_COLLATION_OID;

2370

2371

2372

2373

2374

2376 {

2377 text *template;

2378 char *template_str;

2379 int template_len;

2381

2383

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

2386

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

2388

2390 template_len);

2391

2393 &typid, &typmod, &tz,

2395

2398 else

2400 }

2401 else

2402 {

2403

2404

2405

2406

2407

2408

2409

2410 static const char *fmt_str[] =

2411 {

2412 "yyyy-mm-dd",

2413 "HH24:MI:SS.USTZ",

2414 "HH24:MI:SSTZ",

2415 "HH24:MI:SS.US",

2416 "HH24:MI:SS",

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

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

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

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

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

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

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

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

2425 };

2426

2427

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

2429 int i;

2430

2431

2432

2433

2434

2437 {

2439

2441

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

2445

2447 (Node *) &escontext);

2450 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

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

2453 }

2454

2455

2457 {

2459

2460 if (!fmt_txt[i])

2461 {

2464

2467 }

2468

2470 &typid, &typmod, &tz,

2471 (Node *) &escontext);

2472

2474 {

2476 break;

2477 }

2478 }

2479

2481 {

2484 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

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

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

2488 else

2490 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

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

2493

2494 }

2495 }

2496

2497

2498

2499

2500

2501

2502

2503 switch (jsp->type)

2504 {

2505 case jpiDatetime:

2506 break;

2508 {

2509

2510 switch (typid)

2511 {

2512 case DATEOID:

2513 break;

2514 case TIMEOID:

2515 case TIMETZOID:

2517 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

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

2520 break;

2521 case TIMESTAMPOID:

2524 break;

2525 case TIMESTAMPTZOID:

2527 "timestamptz", "date");

2530 break;

2531 default:

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

2533 }

2534

2535 typid = DATEOID;

2536 }

2537 break;

2539 {

2540

2541 switch (typid)

2542 {

2543 case DATEOID:

2545 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

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

2548 break;

2549 case TIMEOID:

2550 break;

2551 case TIMETZOID:

2553 "timetz", "time");

2556 break;

2557 case TIMESTAMPOID:

2560 break;

2561 case TIMESTAMPTZOID:

2563 "timestamptz", "time");

2566 break;

2567 default:

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

2569 }

2570

2571

2572 if (time_precision != -1)

2573 {

2575

2576

2578 time_precision);

2582

2583

2584 typmod = time_precision;

2585 }

2586

2587 typid = TIMEOID;

2588 }

2589 break;

2591 {

2592

2593 switch (typid)

2594 {

2595 case DATEOID:

2596 case TIMESTAMPOID:

2598 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

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

2601 break;

2602 case TIMEOID:

2604 "time", "timetz");

2607 break;

2608 case TIMETZOID:

2609 break;

2610 case TIMESTAMPTZOID:

2613 break;

2614 default:

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

2616 }

2617

2618

2619 if (time_precision != -1)

2620 {

2622

2623

2625 time_precision);

2629

2630

2631 typmod = time_precision;

2632 }

2633

2634 typid = TIMETZOID;

2635 }

2636 break;

2638 {

2639

2640 switch (typid)

2641 {

2642 case DATEOID:

2645 break;

2646 case TIMEOID:

2647 case TIMETZOID:

2649 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

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

2652 break;

2653 case TIMESTAMPOID:

2654 break;

2655 case TIMESTAMPTZOID:

2657 "timestamptz", "timestamp");

2660 break;

2661 default:

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

2663 }

2664

2665

2666 if (time_precision != -1)

2667 {

2670

2671

2673 time_precision);

2676 (Node *) &escontext);

2677 if (escontext.error_occurred)

2679 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

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

2683

2684

2685 typmod = time_precision;

2686 }

2687

2688 typid = TIMESTAMPOID;

2689 }

2690 break;

2692 {

2695

2696

2697 switch (typid)

2698 {

2699 case DATEOID:

2701 "date", "timestamptz");

2702

2703

2704

2705

2706

2713

2716 break;

2717 case TIMEOID:

2718 case TIMETZOID:

2720 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

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

2723 break;

2724 case TIMESTAMPOID:

2726 "timestamp", "timestamptz");

2727

2728

2729

2730

2731

2733 &fsec, NULL, NULL) == 0)

2736

2739 break;

2740 case TIMESTAMPTZOID:

2741 break;

2742 default:

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

2744 }

2745

2746

2747 if (time_precision != -1)

2748 {

2751

2752

2754 time_precision);

2757 (Node *) &escontext);

2758 if (escontext.error_occurred)

2760 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),

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

2764

2765

2766 typmod = time_precision;

2767 }

2768

2769 typid = TIMESTAMPTZOID;

2770 }

2771 break;

2772 default:

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

2774 }

2775

2776 pfree(datetime);

2777

2779 return res;

2780

2782

2783 if (!hasNext && !found)

2784 return res;

2785

2787

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

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

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

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

2793

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

2795}

2796

2797

2798

2799

2800

2801

2802

2803

2804

2805

2806

2807

2808

2809

2810

2811

2812

2813

2814

2815

2816

2817

2818

2819

2823{

2836 bool hasNext;

2837

2840 (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),

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

2843

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

2845

2847 return jperNotFound;

2848

2850

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

2853 keystr.val.string.len = 3;

2854

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

2857 valstr.val.string.len = 5;

2858

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

2861 idstr.val.string.len = 2;

2862

2863

2867

2870

2872

2874 {

2879

2881 continue;

2882

2884

2885 if (!hasNext && !found)

2886 break;

2887

2890

2891 memset(&ps, 0, sizeof(ps));

2892

2894

2897

2900

2903

2905

2907

2909

2911

2913

2915

2917 return res;

2918

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

2920 break;

2921 }

2922

2923 return res;

2924}

2925

2926

2927

2928

2929

2933{

2936

2938 return jperOk;

2939

2941 {

2943 }

2944 else

2945 {

2948 }

2949

2951}

2952

2953

2954

2955

2956

2957

2958static void

2961{

2962 switch (item->type)

2963 {

2966 break;

2970 break;

2974 break;

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

2979 break;

2982 return;

2983 default:

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

2985 }

2986}

2987

2988

2989

2990

2993 JsonbValue *baseObject, int *baseObjectId)

2994{

2999 int id = 1;

3000

3001 foreach(lc, vars)

3002 {

3004

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

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

3007 {

3008 var = curvar;

3009 break;

3010 }

3011

3012 id++;

3013 }

3014

3015 if (var == NULL)

3016 {

3017 *baseObjectId = -1;

3018 return NULL;

3019 }

3020

3023 {

3024 *baseObjectId = 0;

3026 }

3027 else

3029

3030 *baseObject = *result;

3031 *baseObjectId = id;

3032

3033 return result;

3034}

3035

3036static int

3038{

3040

3042}

3043

3044

3045

3046

3047

3048

3049static void

3051{

3052 switch (typid)

3053 {

3054 case BOOLOID:

3057 break;

3058 case NUMERICOID:

3060 break;

3061 case INT2OID:

3063 break;

3064 case INT4OID:

3066 break;

3067 case INT8OID:

3069 break;

3070 case FLOAT4OID:

3072 break;

3073 case FLOAT8OID:

3075 break;

3076 case TEXTOID:

3077 case VARCHAROID:

3081 break;

3082 case DATEOID:

3083 case TIMEOID:

3084 case TIMETZOID:

3085 case TIMESTAMPOID:

3086 case TIMESTAMPTZOID:

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

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

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

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

3092 break;

3093 case JSONBOID:

3094 {

3097

3099 {

3101

3104 }

3105 else

3107 break;

3108 }

3109 case JSONOID:

3110 {

3114

3118

3120 break;

3121 }

3122 default:

3124 errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

3127 }

3128}

3129

3130

3131static void

3133{

3136}

3137

3138

3139

3140

3141static void

3144{

3145 char *varName;

3146 int varNameLength;

3148 int baseObjectId;

3150

3153

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

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

3156 &baseObject, &baseObjectId)) == NULL)

3158 (errcode(ERRCODE_UNDEFINED_OBJECT),

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

3160 pnstrdup(varName, varNameLength))));

3161

3162 if (baseObjectId > 0)

3163 {

3166 }

3167}

3168

3169

3170

3171

3172

3175 JsonbValue *baseObject, int *baseObjectId)

3176{

3180

3182 tmp.val.string.val = varName;

3183 tmp.val.string.len = varNameLength;

3184

3186

3187 if (result == NULL)

3188 {

3189 *baseObjectId = -1;

3190 return NULL;

3191 }

3192

3193 *baseObjectId = 1;

3195

3196 return result;

3197}

3198

3199

3200

3201

3202

3203static int

3205{

3207

3209 {

3211 errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

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

3214 }

3215

3216

3217 return vars != NULL ? 1 : 0;

3218}

3219

3220

3221

3222

3223

3224

3225static int

3227{

3229

3231 {

3233

3236 }

3237

3238 return -1;

3239}

3240

3241

3244{

3246

3248}

3249

3250

3251

3252

3253static int

3255 const char *s2, int len2)

3256{

3257 int cmp;

3258

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

3260

3261 if (cmp != 0)

3262 return cmp;

3263

3264 if (len1 == len2)

3265 return 0;

3266

3267 return len1 < len2 ? -1 : 1;

3268}

3269

3270

3271

3272

3273

3274static int

3276 const char *mbstr2, int mblen2)

3277{

3280 {

3281

3282

3283

3284

3285

3287 }

3288 else

3289 {

3290 char *utf8str1,

3291 *utf8str2;

3292 int cmp,

3293 utf8len1,

3294 utf8len2;

3295

3296

3297

3298

3299

3300

3301

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

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

3306

3308

3309

3310

3311

3312

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

3314 return cmp;

3315

3316

3317 if (mbstr1 != utf8str1)

3318 pfree(utf8str1);

3319 if (mbstr2 != utf8str2)

3320 pfree(utf8str2);

3321

3322

3323

3324

3325

3326

3327

3328

3329

3330

3331 if (cmp == 0)

3333 else

3334 return cmp;

3335 }

3336}

3337

3338

3339

3340

3343{

3344 int cmp;

3345 bool res;

3346

3348 {

3350

3351

3352

3353

3354

3356

3357

3359 }

3360

3361 switch (jb1->type)

3362 {

3364 cmp = 0;

3365 break;

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

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

3369 break;

3372 break;

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

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

3377 jb2->val.string.val,

3379

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

3382 break;

3384 {

3385 bool cast_error;

3386

3388 jb1->val.datetime.typid,

3389 jb2->val.datetime.value,

3390 jb2->val.datetime.typid,

3391 useTz,

3392 &cast_error);

3393

3394 if (cast_error)

3396 }

3397 break;

3398

3402 return jpbUnknown;

3403

3404 default:

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

3406 }

3407

3408 switch (op)

3409 {

3411 res = (cmp == 0);

3412 break;

3414 res = (cmp != 0);

3415 break;

3417 res = (cmp < 0);

3418 break;

3420 res = (cmp > 0);

3421 break;

3423 res = (cmp <= 0);

3424 break;

3426 res = (cmp >= 0);

3427 break;

3428 default:

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

3431 }

3432

3434}

3435

3436

3437static int

3439{

3443}

3444

3447{

3449

3450 *dst = *src;

3451

3452 return dst;

3453}

3454

3455

3456

3457

3458

3462{

3466 Datum numeric_index;

3468

3470 return res;

3471

3475 (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),

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

3477

3481

3483 (Node *) &escontext);

3484

3487 (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),

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

3489

3491}

3492

3493

3496{

3498

3502

3503 return baseObject;

3504}

3505

3506static void

3508{

3511}

3512

3513static void

3515{

3517 {

3520 }

3521 else if (!jvl->list)

3523 else

3525}

3526

3527static int

3529{

3531}

3532

3533static bool

3535{

3537}

3538

3541{

3543}

3544

3545static List *

3547{

3550

3551 return jvl->list;

3552}

3553

3554static void

3556{

3558 {

3561 it->next = NULL;

3562 }

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

3564 {

3568 }

3569 else

3570 {

3571 it->value = NULL;

3573 it->next = NULL;

3574 }

3575}

3576

3577

3578

3579

3582{

3584

3585 if (it->next)

3586 {

3589 }

3590 else

3591 {

3592 it->value = NULL;

3593 }

3594

3595 return result;

3596}

3597

3598

3599

3600

3603{

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

3607

3608 return jbv;

3609}

3610

3611

3612

3613

3614static int

3616{

3618

3620 {

3622

3623

3625

3630 else

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

3632 }

3633

3634 return type;

3635}

3636

3637

3640{

3641

3644

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

3646}

3647

3648

3651{

3655

3657

3661

3663

3664 return ps.result;

3665}

3666

3667

3668static void

3670{

3671 if (!useTz)

3673 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

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

3675 type1, type2),

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

3677}

3678

3679

3682{

3684

3686}

3687

3688

3689

3690

3691

3692static int

3694{

3696}

3697

3698

3699

3700

3701static int

3703{

3705

3707}

3708

3709

3710

3711

3712static int

3714{

3716

3718}

3719

3720

3721

3722

3723

3724

3725static int

3727 bool useTz, bool *cast_error)

3728{

3730

3731 *cast_error = false;

3732

3733 switch (typid1)

3734 {

3735 case DATEOID:

3736 switch (typid2)

3737 {

3738 case DATEOID:

3740

3741 break;

3742

3743 case TIMESTAMPOID:

3746 useTz);

3747

3748 case TIMESTAMPTZOID:

3751 useTz);

3752

3753 case TIMEOID:

3754 case TIMETZOID:

3755 *cast_error = true;

3756 return 0;

3757

3758 default:

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

3760 typid2);

3761 }

3762 break;

3763

3764 case TIMEOID:

3765 switch (typid2)

3766 {

3767 case TIMEOID:

3769

3770 break;

3771

3772 case TIMETZOID:

3775

3776 break;

3777

3778 case DATEOID:

3779 case TIMESTAMPOID:

3780 case TIMESTAMPTZOID:

3781 *cast_error = true;

3782 return 0;

3783

3784 default:

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

3786 typid2);

3787 }

3788 break;

3789

3790 case TIMETZOID:

3791 switch (typid2)

3792 {

3793 case TIMEOID:

3796

3797 break;

3798

3799 case TIMETZOID:

3801

3802 break;

3803

3804 case DATEOID:

3805 case TIMESTAMPOID:

3806 case TIMESTAMPTZOID:

3807 *cast_error = true;

3808 return 0;

3809

3810 default:

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

3812 typid2);

3813 }

3814 break;

3815

3816 case TIMESTAMPOID:

3817 switch (typid2)

3818 {

3819 case DATEOID:

3822 useTz);

3823

3824 case TIMESTAMPOID:

3826

3827 break;

3828

3829 case TIMESTAMPTZOID:

3832 useTz);

3833

3834 case TIMEOID:

3835 case TIMETZOID:

3836 *cast_error = true;

3837 return 0;

3838

3839 default:

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

3841 typid2);

3842 }

3843 break;

3844

3845 case TIMESTAMPTZOID:

3846 switch (typid2)

3847 {

3848 case DATEOID:

3851 useTz);

3852

3853 case TIMESTAMPOID:

3856 useTz);

3857

3858 case TIMESTAMPTZOID:

3860

3861 break;

3862

3863 case TIMEOID:

3864 case TIMETZOID:

3865 *cast_error = true;

3866 return 0;

3867

3868 default:

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

3870 typid2);

3871 }

3872 break;

3873

3874 default:

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

3876 }

3877

3878 if (*cast_error)

3879 return 0;

3880

3882}

3883

3884

3885

3886

3887

3888

3889

3890bool

3892{

3894

3898

3900

3903

3904 return res == jperOk;

3905}

3906

3907

3908

3909

3910

3911

3912

3916 const char *column_name)

3917{

3919 bool wrap;

3922 int count;

3923

3929 {

3931 *empty = false;

3932 return (Datum) 0;

3933 }

3934

3935

3936

3937

3938

3939

3940

3941

3942

3943

3944

3945

3946

3947

3948

3949

3950

3951

3952

3955 if (singleton == NULL)

3956 wrap = false;

3958 wrap = false;

3960 wrap = true;

3962 wrap = count > 1;

3963 else

3964 {

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

3966 wrap = false;

3967 }

3968

3969 if (wrap)

3971

3972

3973 if (count > 1)

3974 {

3976 {

3978 return (Datum) 0;

3979 }

3980

3981 if (column_name)

3983 (errcode(ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM),

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

3985 column_name),

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

3987 else

3989 (errcode(ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM),

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

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

3992 }

3993

3994 if (singleton)

3996

3997 *empty = true;

3999}

4000

4001

4002

4003

4004

4005

4006

4009 const char *column_name)

4010{

4014 int count;

4015

4018 error, &found, true);

4019

4021

4023 {

4025 *empty = false;

4026 return NULL;

4027 }

4028

4030

4031 *empty = (count == 0);

4032

4033 if (*empty)

4034 return NULL;

4035

4036

4037 if (count > 1)

4038 {

4040 {

4042 return NULL;

4043 }

4044

4045 if (column_name)

4047 (errcode(ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM),

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

4049 column_name)));

4050 else

4052 (errcode(ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM),

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

4054 }

4055

4059

4060

4062 {

4064 {

4066 return NULL;

4067 }

4068

4069 if (column_name)

4071 (errcode(ERRCODE_SQL_JSON_SCALAR_REQUIRED),

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

4073 column_name)));

4074 else

4076 (errcode(ERRCODE_SQL_JSON_SCALAR_REQUIRED),

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

4078 }

4079

4081 return NULL;

4082

4083 return res;

4084}

4085

4086

4087

4088

4089

4090

4091

4094{

4096

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

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

4102

4103 return result;

4104}

4105

4106

4107

4108

4109

4110

4111

4112

4113static void

4115{

4123

4126

4127

4128

4129

4130

4131 if (state->passingvalexprs)

4132 {

4135

4139 namelc, je->passing_names)

4140 {

4144

4149

4150

4151

4152

4153

4156

4158 }

4159 }

4160

4162

4163

4164

4165

4166

4169

4170 state->opaque = cxt;

4171}

4172

4173

4174

4175

4176

4177static void

4179{

4182

4183

4185

4186 state->opaque = NULL;

4187}

4188

4189

4190

4191

4192

4193

4198{

4200

4202 planstate->parent = parentstate;

4203

4205 {

4207 int i;

4208

4213

4214

4217

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

4220

4223 }

4225 {

4227

4229 args, mcxt);

4231 args, mcxt);

4232 }

4233

4234 return planstate;

4235}

4236

4237

4238

4239

4240

4241static void

4243{

4246

4248}

4249

4250

4251

4252

4253

4254static void

4256{

4261

4263

4265

4267

4271 &planstate->found,

4272 true);

4273

4275

4277 {

4280 }

4281

4282

4287}

4288

4289

4290

4291

4292

4293

4294static bool

4296{

4301 else

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

4303

4305

4306 return false;

4307}

4308

4309

4310

4311

4312

4313

4314

4315

4316

4317

4318

4319

4320

4321static bool

4323{

4326

4327

4328

4329

4330

4332 {

4334 return true;

4335 }

4336

4337

4339

4340

4341 if (jbv == NULL)

4342 {

4345 return false;

4346 }

4347

4348

4349

4350

4351

4356

4357

4359

4360

4361 if (planstate->nested)

4362 {

4363

4365

4366

4367

4368

4369

4370

4371

4373 }

4374

4375

4376 return true;

4377}

4378

4379

4380

4381

4382

4383static void

4385{

4386

4389 {

4391

4394

4395

4396

4397

4398

4399 }

4401 {

4404 }

4405}

4406

4407

4408

4409

4410

4411

4412static bool

4414{

4415

4416

4418 {

4419

4420

4421

4422

4424 {

4425

4426 return false;

4427 }

4428 }

4429

4430 return true;

4431}

4432

4433

4434

4435

4436

4437

4438

4439static bool

4441{

4444

4446}

4447

4448

4449

4450

4451

4452

4453

4454

4457 Oid typid, int32 typmod, bool *isnull)

4458{

4466

4467

4468 if (current->isnull)

4469 {

4470 result = (Datum) 0;

4471 *isnull = true;

4472 }

4473

4474 else if (estate)

4475 {

4478

4479

4482

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

4484

4487 }

4488

4489 else

4490 {

4492 *isnull = false;

4493 }

4494

4495 return result;

4496}

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)

Datum float8_numeric(PG_FUNCTION_ARGS)

Datum numeric_cmp(PG_FUNCTION_ARGS)

Numeric int64_to_numeric(int64 val)

Datum float4_numeric(PG_FUNCTION_ARGS)

Datum int4_numeric(PG_FUNCTION_ARGS)

Datum numeric_uminus(PG_FUNCTION_ARGS)

Numeric numeric_mod_safe(Numeric num1, Numeric num2, Node *escontext)

Datum numeric_ceil(PG_FUNCTION_ARGS)

int32 numeric_int4_safe(Numeric num, Node *escontext)

Datum numerictypmodin(PG_FUNCTION_ARGS)

Numeric numeric_add_safe(Numeric num1, Numeric num2, Node *escontext)

int64 numeric_int8_safe(Numeric num, Node *escontext)

Numeric numeric_div_safe(Numeric num1, Numeric num2, Node *escontext)

Numeric numeric_sub_safe(Numeric num1, Numeric num2, Node *escontext)

Datum numeric_out(PG_FUNCTION_ARGS)

Datum numeric_trunc(PG_FUNCTION_ARGS)

Datum numeric_in(PG_FUNCTION_ARGS)

bool numeric_is_nan(Numeric num)

Datum int2_numeric(PG_FUNCTION_ARGS)

Numeric numeric_mul_safe(Numeric num1, Numeric num2, Node *escontext)

Datum numeric_abs(PG_FUNCTION_ARGS)

Datum int8_numeric(PG_FUNCTION_ARGS)

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)

#define palloc_object(type)

#define palloc_array(type, count)

#define palloc0_object(type)

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

bool DirectInputFunctionCallSafe(PGFunction func, char *str, Oid typioparam, int32 typmod, Node *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)

void pushJsonbValue(JsonbInState *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

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)

Numeric(* BinaryArithmFunc)(Numeric num1, Numeric num2, Node *escontext)

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)

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)

static char buf[DEFAULT_XLOG_SEG_SIZE]

PGDLLIMPORT pg_tz * session_timezone

static Datum Int64GetDatum(int64 X)

static bool DatumGetBool(Datum X)

static Datum PointerGetDatum(const void *X)

static char * DatumGetCString(Datum X)

static Pointer DatumGetPointer(Datum X)

static Datum Float8GetDatum(float8 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::@146::@153 like_regex

struct JsonPathItem::@146::@149 array

struct JsonPathItem::@146::@147 args

union JsonPathItem::@146 content

struct JsonPathItem::@146::@150 anybounds

JsonTablePlanState * rootplanstate

JsonTablePlanState ** colplanstates

struct JsonTablePlanState * left

struct JsonTablePlanState * nested

struct JsonTablePlanState * parent

struct JsonTablePlanState * right

JsonTablePlanRowSource current

JsonValueListIterator iter

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

static Datum TimestampTzGetDatum(TimestampTz X)

static Datum TimestampGetDatum(Timestamp X)

static Timestamp DatumGetTimestamp(Datum X)

static TimestampTz DatumGetTimestampTz(Datum X)

static Size VARSIZE_ANY_EXHDR(const void *PTR)

static char * VARDATA_ANY(const void *PTR)

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

text * cstring_to_text(const char *s)

char * text_to_cstring(const text *t)