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{
100
104
106
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 ()
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 ||
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 ((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 , &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)