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
260 Jsonb *json, bool throwErrors,
284 bool ignoreStructuralErrors, bool unwrapNext);
311 JsonbValue *baseObject, int *baseObjectId);
320 int varNameLength,
322 int *baseObjectId);
327 bool useTz);
349 bool useTz, bool *cast_error);
351 const char *type2);
352
363 Oid typid, int32 typmod, bool *isnull);
369
371{
374 .SetNamespace = NULL,
375 .SetRowFilter = NULL,
376 .SetColumnFilter = NULL,
380};
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
398{
403 bool silent = true;
404
406 {
409 }
410
413 jb, !silent, NULL, tz);
414
417
420
422}
423
426{
428}
429
432{
434}
435
436
437
438
439
440
443{
444
446}
447
448
449
450
451
452
455{
460 bool silent = true;
461
463 {
466 }
467
470 jb, !silent, &found, tz);
471
474
476 {
478
481
484 }
485
486 if (!silent)
488 (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
489 errmsg("single boolean result is expected")));
490
492}
493
496{
498}
499
502{
504}
505
506
507
508
509
510
513{
514
516}
517
518
519
520
521
522
525{
530
532 {
537 bool silent;
539
542
547
550 jb, !silent, &found, tz);
551
553
555 }
556
559
561
562 if (c == NULL)
564
567
569}
570
573{
575}
576
579{
581}
582
583
584
585
586
587
590{
596
599 jb, !silent, &found, tz);
600
602}
603
606{
608}
609
612{
614}
615
616
617
618
619
620
623{
629
632 jb, !silent, &found, tz);
633
636 else
638}
639
642{
644}
645
648{
650}
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
680 bool useTz)
681{
686
688
691
696 cxt.root = &jbv;
700
704 cxt.useTz = useTz;
705
707 {
708
709
710
711
713
714 res = executeItem(&cxt, &jsp, &jbv, &vals);
715
717 return res;
718
720 }
721
722 res = executeItem(&cxt, &jsp, &jbv, result);
723
725
726 return res;
727}
728
729
730
731
735{
737}
738
739
740
741
742
743
747{
751
754
755 switch (jsp->type)
756 {
762 {
765 bool hasNext = jspGetNext(jsp, &elem);
766
768 {
769
770
771
772
774 break;
775 }
776
777 v = hasNext ? &vbuf : palloc(sizeof(*v));
778
781
783 v, found, hasNext);
785 }
786 break;
787
788
802 {
804
806 break;
807 }
808
812
816
820
824
828
831
834 found);
835
838 {
839 bool hasNext = jspGetNext(jsp, &elem);
840
843 }
848 (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),
849 errmsg("jsonpath wildcard array accessor can only be applied to an array"))));
850 break;
851
854 {
855 bool hasNext = jspGetNext(jsp, &elem);
856
858 elog(ERROR, "invalid jsonb object type: %d", jb->type);
859
861 (cxt, hasNext ? &elem : NULL,
862 jb->val.binary.data, found, 1, 1, 1,
864 }
868 {
871 (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),
872 errmsg("jsonpath wildcard member accessor can only be applied to an object"))));
873 }
874 break;
875
878 {
880 int i;
882 bool singleton = size < 0;
883 bool hasNext = jspGetNext(jsp, &elem);
884
885 if (singleton)
886 size = 1;
887
889
891 {
895 int32 index_from;
898 &to, i);
899
900 res = getArrayIndex(cxt, &from, jb, &index_from);
901
903 break;
904
906 {
908
910 break;
911 }
912 else
913 index_to = index_from;
914
916 (index_from < 0 ||
917 index_from > index_to ||
918 index_to >= size))
920 (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
921 errmsg("jsonpath array subscript is out of bounds"))));
922
923 if (index_from < 0)
924 index_from = 0;
925
926 if (index_to >= size)
927 index_to = size - 1;
928
930
932 {
934 bool copy;
935
936 if (singleton)
937 {
938 v = jb;
939 copy = true;
940 }
941 else
942 {
945
946 if (v == NULL)
947 continue;
948
949 copy = false;
950 }
951
952 if (!hasNext && !found)
954
956 copy);
957
959 break;
960
961 if (res == jperOk && !found)
962 break;
963 }
964
966 break;
967
968 if (res == jperOk && !found)
969 break;
970 }
971
973 }
975 {
977 (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),
978 errmsg("jsonpath array accessor can only be applied to an array"))));
979 }
980 break;
981
983 {
984 bool hasNext = jspGetNext(jsp, &elem);
985
986
988 {
989 bool savedIgnoreStructuralErrors;
990
994 jb, found, true);
996
997 if (res == jperOk && !found)
998 break;
999 }
1000
1003 (cxt, hasNext ? &elem : NULL,
1004 jb->val.binary.data, found,
1005 1,
1009 break;
1010 }
1011
1014 {
1017
1020
1023
1024 if (v != NULL)
1025 {
1027 v, found, false);
1028
1029
1032 }
1034 {
1036
1039
1041 (errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND), \
1042 errmsg("JSON object does not contain key \"%s\"",
1044 key.val.string.len))));
1045 }
1046 }
1050 {
1053 (errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND),
1054 errmsg("jsonpath member accessor can only be applied to an object"))));
1055 }
1056 break;
1057
1060 found, true);
1061 break;
1062
1064 jb = cxt->root;
1068 break;
1069
1071 {
1073
1076 false);
1077
1082 else
1084 jb, found, true);
1085 break;
1086 }
1087
1089 {
1091
1094 jbv->val.string.len = strlen(jbv->val.string.val);
1095
1097 found, false);
1098 }
1099 break;
1100
1102 {
1104
1105 if (size < 0)
1106 {
1108 {
1111 (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),
1112 errmsg("jsonpath item method .%s() can only be applied to an array",
1114 break;
1115 }
1116
1117 size = 1;
1118 }
1119
1120 jb = palloc(sizeof(*jb));
1121
1124
1125 res = executeNextItem(cxt, jsp, NULL, jb, found, false);
1126 }
1127 break;
1128
1131 found);
1132
1135 found);
1136
1139 found);
1140
1142 {
1144
1147 false);
1148
1150 {
1153 double val;
1155
1157 NULL,
1158 "double precision",
1159 tmp,
1160 (Node *) &escontext);
1161
1164 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1165 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",
1167 if (isinf(val) || isnan(val))
1169 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1170 errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",
1173 }
1175 {
1176
1177 double val;
1178 char *tmp = pnstrdup(jb->val.string.val,
1179 jb->val.string.len);
1181
1183 NULL,
1184 "double precision",
1185 tmp,
1186 (Node *) &escontext);
1187
1190 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1191 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",
1193 if (isinf(val) || isnan(val))
1195 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1196 errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",
1198
1199 jb = &jbv;
1204 }
1205
1208 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1209 errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",
1211
1213 }
1214 break;
1215
1224
1226
1230
1232
1234 {
1237 int last;
1238 bool hasNext = jspGetNext(jsp, &elem);
1239
1241 elog(ERROR, "evaluating jsonpath LAST outside of array subscript");
1242
1243 if (!hasNext && !found)
1244 {
1246 break;
1247 }
1248
1250
1251 lastjbv = hasNext ? &tmpjbv : palloc(sizeof(*lastjbv));
1252
1255
1257 lastjbv, found, hasNext);
1258 }
1259 break;
1260
1262 {
1265
1268 false);
1269
1271 {
1272 bool have_error;
1274
1276 if (have_error)
1278 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1279 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",
1283 "bigint"))));
1284
1287 }
1289 {
1290
1291 char *tmp = pnstrdup(jb->val.string.val,
1292 jb->val.string.len);
1294 bool noerr;
1295
1298 (Node *) &escontext,
1299 &datum);
1300
1303 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1304 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",
1307 }
1308
1311 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1312 errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",
1314
1315 jb = &jbv;
1318 datum));
1319
1321 }
1322 break;
1323
1325 {
1327 bool bval;
1328
1331 false);
1332
1334 {
1335 bval = jb->val.boolean;
1336
1338 }
1340 {
1341 int ival;
1343 bool noerr;
1347
1350 (Node *) &escontext,
1351 &datum);
1352
1355 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1356 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",
1358
1360 if (ival == 0)
1361 bval = false;
1362 else
1363 bval = true;
1364
1366 }
1368 {
1369
1370 char *tmp = pnstrdup(jb->val.string.val,
1371 jb->val.string.len);
1372
1375 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1376 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",
1378
1380 }
1381
1384 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1385 errmsg("jsonpath item method .%s() can only be applied to a boolean, string, or numeric value",
1387
1388 jb = &jbv;
1390 jb->val.boolean = bval;
1391
1393 }
1394 break;
1395
1398 {
1401 char *numstr = NULL;
1402
1405 false);
1406
1408 {
1409 num = jb->val.numeric;
1412 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1413 errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",
1415
1420 }
1422 {
1423
1425 bool noerr;
1427
1428 numstr = pnstrdup(jb->val.string.val, jb->val.string.len);
1429
1432 (Node *) &escontext,
1433 &datum);
1434
1437 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1438 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",
1440
1444 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1445 errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",
1447
1449 }
1450
1453 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1454 errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",
1456
1457
1458
1459
1460
1461
1462
1464 {
1467 int32 precision;
1469 bool have_error;
1470 bool noerr;
1472 Datum datums[2];
1473 char pstr[12];
1474 char sstr[12];
1476
1479 elog(ERROR, "invalid jsonpath item type for .decimal() precision");
1480
1482 &have_error);
1483 if (have_error)
1485 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1486 errmsg("precision of jsonpath item method .%s() is out of range for type integer",
1488
1490 {
1493 elog(ERROR, "invalid jsonpath item type for .decimal() scale");
1494
1496 &have_error);
1497 if (have_error)
1499 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1500 errmsg("scale of jsonpath item method .%s() is out of range for type integer",
1502 }
1503
1504
1505
1506
1507
1508 pg_ltoa(precision, pstr);
1513
1516
1517
1518 Assert(numstr != NULL);
1521 (Node *) &escontext,
1522 &numdatum);
1523
1526 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1527 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",
1529
1531 pfree(arrtypmod);
1532 }
1533
1534 jb = &jbv;
1536 jb->val.numeric = num;
1537
1539 }
1540 break;
1541
1543 {
1546
1549 false);
1550
1552 {
1553 bool have_error;
1555
1557 if (have_error)
1559 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1560 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",
1564
1567 }
1569 {
1570
1571 char *tmp = pnstrdup(jb->val.string.val,
1572 jb->val.string.len);
1574 bool noerr;
1575
1578 (Node *) &escontext,
1579 &datum);
1580
1583 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1584 errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",
1587 }
1588
1591 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1592 errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",
1594
1595 jb = &jbv;
1598 datum));
1599
1601 }
1602 break;
1603
1605 {
1607 char *tmp = NULL;
1608
1611
1613 {
1615
1616
1617
1618
1619
1621 jb->val.string.len);
1622 break;
1626 break;
1628 tmp = (jb->val.boolean) ? "true" : "false";
1629 break;
1631 {
1633
1635 jb->val.datetime.value,
1636 jb->val.datetime.typid,
1637 &jb->val.datetime.tz);
1639 }
1640 break;
1646 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1647 errmsg("jsonpath item method .%s() can only be applied to a boolean, string, numeric, or datetime value",
1649 break;
1650 }
1651
1652 jb = &jbv;
1653 Assert(tmp != NULL);
1654 jb->val.string.val = tmp;
1655 jb->val.string.len = strlen(jb->val.string.val);
1657
1659 }
1660 break;
1661
1662 default:
1663 elog(ERROR, "unrecognized jsonpath item type: %d", jsp->type);
1664 }
1665
1666 return res;
1667}
1668
1669
1670
1671
1675 bool unwrapElements)
1676{
1678 {
1680 elog(ERROR, "invalid jsonb array value type: %d", jb->type);
1681 }
1682
1684 (cxt, jsp, jb->val.binary.data, found, 1, 1, 1,
1685 false, unwrapElements);
1686}
1687
1688
1689
1690
1691
1696{
1698 bool hasNext;
1699
1700 if ()
1701 hasNext = next != NULL;
1702 else if (next)
1704 else
1705 {
1706 next = &elem;
1708 }
1709
1710 if (hasNext)
1712
1713 if (found)
1715
1717}
1718
1719
1720
1721
1722
1727{
1729 {
1734
1736 return res;
1737
1740 {
1742
1745 else
1747 }
1748
1750 }
1751
1752 return executeItem(cxt, jsp, jb, found);
1753}
1754
1755
1756
1757
1763{
1766
1770
1771 return res;
1772}
1773
1774
1778{
1783
1784
1786
1787 if (!canHaveNext && jspHasNext(jsp))
1788 elog(ERROR, "boolean jsonpath item cannot have next item");
1789
1790 switch (jsp->type)
1791 {
1795
1798
1799
1800
1801
1802
1803
1806
1807 return res2 == jpbTrue ? res : res2;
1808
1812
1815
1818
1819 return res2 == jpbFalse ? res : res2;
1820
1823
1825
1828
1830
1835
1846
1847 case jpiStartsWith:
1852
1853 case jpiLikeRegex:
1854 {
1855
1856
1857
1858
1859
1860
1862
1865
1868 }
1869
1872
1874 {
1875
1876
1877
1878
1882 false, &vals);
1883
1886
1888 }
1889 else
1890 {
1893 false, NULL);
1894
1897
1899 }
1900
1901 default:
1902 elog(ERROR, "invalid boolean jsonpath item type: %d", jsp->type);
1904 }
1905}
1906
1907
1908
1909
1910
1914{
1917
1922
1923 return res;
1924}
1925
1926
1927
1928
1929
1930
1931
1935 bool ignoreStructuralErrors, bool unwrapNext)
1936{
1941
1943
1944 if (level > last)
1945 return res;
1946
1948
1949
1950
1951
1953 {
1955 {
1958 }
1959
1961 {
1962
1963 if (level >= first ||
1966 {
1967
1968 if (jsp)
1969 {
1970 if (ignoreStructuralErrors)
1971 {
1972 bool savedIgnoreStructuralErrors;
1973
1978 }
1979 else
1981
1983 break;
1984
1985 if (res == jperOk && !found)
1986 break;
1987 }
1988 else if (found)
1990 else
1992 }
1993
1995 {
1997 (cxt, jsp, v.val.binary.data, found,
1998 level + 1, first, last,
1999 ignoreStructuralErrors, unwrapNext);
2000
2002 break;
2003
2004 if (res == jperOk && found == NULL)
2005 break;
2006 }
2007 }
2008 }
2009
2010 return res;
2011}
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2027 void *param)
2028{
2034 bool error = false;
2035 bool found = false;
2036
2037
2041
2042 if (rarg)
2043 {
2044
2046 unwrapRightArg, &rseq);
2049 }
2050
2053 {
2056 bool first = true;
2057
2059 if (rarg)
2061 else
2062 rval = NULL;
2063
2064
2065 while (rarg ? (rval != NULL) : first)
2066 {
2068
2070 {
2073
2075 }
2076 else if (res == jpbTrue)
2077 {
2080
2081 found = true;
2082 }
2083
2084 first = false;
2085 if (rarg)
2087 }
2088 }
2089
2090 if (found)
2092
2093 if (error)
2095
2097}
2098
2099
2100
2101
2102
2107{
2115
2117
2118
2119
2120
2121
2124 return jper;
2125
2127
2130 return jper;
2131
2135 (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
2136 errmsg("left operand of jsonpath operator %s is not a single numeric value",
2138
2142 (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
2143 errmsg("right operand of jsonpath operator %s is not a single numeric value",
2145
2147 {
2148 res = func(lval->val.numeric, rval->val.numeric, NULL);
2149 }
2150 else
2151 {
2152 bool error = false;
2153
2154 res = func(lval->val.numeric, rval->val.numeric, &error);
2155
2158 }
2159
2160 if ((jsp, &elem) && !found)
2162
2163 lval = palloc(sizeof(*lval));
2165 lval->val.numeric = res;
2166
2167 return executeNextItem(cxt, jsp, &elem, lval, found, false);
2168}
2169
2170
2171
2172
2173
2177{
2184 bool hasNext;
2185
2188
2190 return jper;
2191
2193
2195
2198 {
2200 {
2201 if (!found && !hasNext)
2203 }
2204 else
2205 {
2206 if (!found && !hasNext)
2207 continue;
2208
2210 (errcode(ERRCODE_SQL_JSON_NUMBER_NOT_FOUND),
2211 errmsg("operand of unary jsonpath operator %s is not a numeric value",
2213 }
2214
2215 if (func)
2216 val->val.numeric =
2219
2221
2223 return jper2;
2224
2225 if (jper2 == jperOk)
2226 {
2227 if (!found)
2230 }
2231 }
2232
2233 return jper;
2234}
2235
2236
2237
2238
2239
2240
2243 void *param)
2244{
2247
2250
2251 if (whole->val.string.len >= initial->val.string.len &&
2252 !memcmp(whole->val.string.val,
2253 initial->val.string.val,
2254 initial->val.string.len))
2256
2258}
2259
2260
2261
2262
2263
2264
2267 void *param)
2268{
2270
2273
2274
2275 if (!cxt->regex)
2276 {
2281 &(cxt->cflags), NULL);
2282 }
2283
2285 str->val.string.len,
2286 cxt->cflags, DEFAULT_COLLATION_OID, 0, NULL))
2288
2290}
2291
2292
2293
2294
2295
2300{
2303
2306
2309 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
2310 errmsg("jsonpath item method .%s() can only be applied to a numeric value",
2312
2314
2317
2318 jb = palloc(sizeof(*jb));
2321
2323}
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2340{
2343 text *datetime;
2345 Oid typid;
2346 int32 typmod = -1;
2347 int tz = 0;
2348 bool hasNext;
2351 int32 time_precision = -1;
2352
2355 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2356 errmsg("jsonpath item method .%s() can only be applied to a string",
2358
2360 jb->val.string.len);
2361
2362
2363
2364
2365
2366
2367 collid = DEFAULT_COLLATION_OID;
2368
2369
2370
2371
2372
2374 {
2375 text *template;
2376 char *template_str;
2377 int template_len;
2379
2381
2383 elog(ERROR, "invalid jsonpath item type for .datetime() argument");
2384
2385 template_str = jspGetString(&elem, &template_len);
2386
2388 template_len);
2389
2391 &typid, &typmod, &tz,
2393
2396 else
2398 }
2399 else
2400 {
2401
2402
2403
2404
2405
2406
2407
2408 static const char *fmt_str[] =
2409 {
2410 "yyyy-mm-dd",
2411 "HH24:MI:SS.USTZ",
2412 "HH24:MI:SSTZ",
2413 "HH24:MI:SS.US",
2414 "HH24:MI:SS",
2415 "yyyy-mm-dd HH24:MI:SS.USTZ",
2416 "yyyy-mm-dd HH24:MI:SSTZ",
2417 "yyyy-mm-dd\"T\"HH24:MI:SS.USTZ",
2418 "yyyy-mm-dd\"T\"HH24:MI:SSTZ",
2419 "yyyy-mm-dd HH24:MI:SS.US",
2420 "yyyy-mm-dd HH24:MI:SS",
2421 "yyyy-mm-dd\"T\"HH24:MI:SS.US",
2422 "yyyy-mm-dd\"T\"HH24:MI:SS"
2423 };
2424
2425
2426 static text *fmt_txt[lengthof(fmt_str)] = {0};
2427 int i;
2428
2429
2430
2431
2432
2435 {
2436 bool have_error;
2437
2439
2441 elog(ERROR, "invalid jsonpath item type for %s argument",
2443
2445 &have_error);
2446 if (have_error)
2448 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2449 errmsg("time precision of jsonpath item method .%s() is out of range for type integer",
2451 }
2452
2453
2455 {
2457
2458 if (!fmt_txt[i])
2459 {
2462
2465 }
2466
2468 &typid, &typmod, &tz,
2469 (Node *) &escontext);
2470
2472 {
2474 break;
2475 }
2476 }
2477
2479 {
2482 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2483 errmsg("%s format is not recognized: \"%s\"",
2485 errhint("Use a datetime template argument to specify the input data format."))));
2486 else
2488 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2489 errmsg("%s format is not recognized: \"%s\"",
2491
2492 }
2493 }
2494
2495
2496
2497
2498
2499
2500
2501 switch (jsp->type)
2502 {
2503 case jpiDatetime:
2504 break;
2506 {
2507
2508 switch (typid)
2509 {
2510 case DATEOID:
2511 break;
2512 case TIMEOID:
2513 case TIMETZOID:
2515 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2516 errmsg("%s format is not recognized: \"%s\"",
2518 break;
2519 case TIMESTAMPOID:
2522 break;
2523 case TIMESTAMPTZOID:
2525 "timestamptz", "date");
2528 break;
2529 default:
2530 elog(ERROR, "type with oid %u not supported", typid);
2531 }
2532
2533 typid = DATEOID;
2534 }
2535 break;
2537 {
2538
2539 switch (typid)
2540 {
2541 case DATEOID:
2543 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2544 errmsg("%s format is not recognized: \"%s\"",
2546 break;
2547 case TIMEOID:
2548 break;
2549 case TIMETZOID:
2551 "timetz", "time");
2554 break;
2555 case TIMESTAMPOID:
2558 break;
2559 case TIMESTAMPTZOID:
2561 "timestamptz", "time");
2564 break;
2565 default:
2566 elog(ERROR, "type with oid %u not supported", typid);
2567 }
2568
2569
2570 if (time_precision != -1)
2571 {
2573
2574
2576 time_precision);
2580
2581
2582 typmod = time_precision;
2583 }
2584
2585 typid = TIMEOID;
2586 }
2587 break;
2589 {
2590
2591 switch (typid)
2592 {
2593 case DATEOID:
2594 case TIMESTAMPOID:
2596 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2597 errmsg("%s format is not recognized: \"%s\"",
2599 break;
2600 case TIMEOID:
2602 "time", "timetz");
2605 break;
2606 case TIMETZOID:
2607 break;
2608 case TIMESTAMPTZOID:
2611 break;
2612 default:
2613 elog(ERROR, "type with oid %u not supported", typid);
2614 }
2615
2616
2617 if (time_precision != -1)
2618 {
2620
2621
2623 time_precision);
2627
2628
2629 typmod = time_precision;
2630 }
2631
2632 typid = TIMETZOID;
2633 }
2634 break;
2636 {
2637
2638 switch (typid)
2639 {
2640 case DATEOID:
2643 break;
2644 case TIMEOID:
2645 case TIMETZOID:
2647 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2648 errmsg("%s format is not recognized: \"%s\"",
2650 break;
2651 case TIMESTAMPOID:
2652 break;
2653 case TIMESTAMPTZOID:
2655 "timestamptz", "timestamp");
2658 break;
2659 default:
2660 elog(ERROR, "type with oid %u not supported", typid);
2661 }
2662
2663
2664 if (time_precision != -1)
2665 {
2668
2669
2671 time_precision);
2674 (Node *) &escontext);
2675 if (escontext.error_occurred)
2677 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2678 errmsg("time precision of jsonpath item method .%s() is invalid",
2681
2682
2683 typmod = time_precision;
2684 }
2685
2686 typid = TIMESTAMPOID;
2687 }
2688 break;
2690 {
2693
2694
2695 switch (typid)
2696 {
2697 case DATEOID:
2699 "date", "timestamptz");
2700
2701
2702
2703
2704
2711
2714 break;
2715 case TIMEOID:
2716 case TIMETZOID:
2718 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2719 errmsg("%s format is not recognized: \"%s\"",
2721 break;
2722 case TIMESTAMPOID:
2724 "timestamp", "timestamptz");
2725
2726
2727
2728
2729
2731 &fsec, NULL, NULL) == 0)
2734
2737 break;
2738 case TIMESTAMPTZOID:
2739 break;
2740 default:
2741 elog(ERROR, "type with oid %u not supported", typid);
2742 }
2743
2744
2745 if (time_precision != -1)
2746 {
2749
2750
2752 time_precision);
2755 (Node *) &escontext);
2756 if (escontext.error_occurred)
2758 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2759 errmsg("time precision of jsonpath item method .%s() is invalid",
2762
2763
2764 typmod = time_precision;
2765 }
2766
2767 typid = TIMESTAMPTZOID;
2768 }
2769 break;
2770 default:
2771 elog(ERROR, "unrecognized jsonpath item type: %d", jsp->type);
2772 }
2773
2774 pfree(datetime);
2775
2777 return res;
2778
2780
2781 if (!hasNext && !found)
2782 return res;
2783
2784 jb = hasNext ? &jbvbuf : palloc(sizeof(*jb));
2785
2787 jb->val.datetime.value = value;
2788 jb->val.datetime.typid = typid;
2789 jb->val.datetime.typmod = typmod;
2790 jb->val.datetime.tz = tz;
2791
2792 return executeNextItem(cxt, jsp, &elem, jb, found, hasNext);
2793}
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2821{
2834 bool hasNext;
2835
2838 (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),
2839 errmsg("jsonpath item method .%s() can only be applied to an object",
2841
2842 jbc = jb->val.binary.data;
2843
2845 return jperNotFound;
2846
2848
2850 keystr.val.string.val = "key";
2851 keystr.val.string.len = 3;
2852
2854 valstr.val.string.val = "value";
2855 valstr.val.string.len = 5;
2856
2858 idstr.val.string.val = "id";
2859 idstr.val.string.len = 2;
2860
2861
2865
2868
2870
2872 {
2878
2880 continue;
2881
2883
2884 if (!hasNext && !found)
2885 break;
2886
2889
2890 ps = NULL;
2892
2895
2898
2901
2903
2905
2907
2909
2911
2913
2915 return res;
2916
2917 if (res == jperOk && !found)
2918 break;
2919 }
2920
2921 return res;
2922}
2923
2924
2925
2926
2927
2931{
2934
2936 return jperOk;
2937
2939 {
2941 }
2942 else
2943 {
2946 }
2947
2949}
2950
2951
2952
2953
2954
2955
2956static void
2959{
2960 switch (item->type)
2961 {
2964 break;
2968 break;
2972 break;
2976 &value->val.string.len);
2977 break;
2980 return;
2981 default:
2982 elog(ERROR, "unexpected jsonpath item type");
2983 }
2984}
2985
2986
2987
2988
2991 JsonbValue *baseObject, int *baseObjectId)
2992{
2997 int id = 1;
2998
2999 foreach(lc, vars)
3000 {
3002
3003 if (curvar->namelen == varNameLen &&
3004 strncmp(curvar->name, varName, varNameLen) == 0)
3005 {
3006 var = curvar;
3007 break;
3008 }
3009
3010 id++;
3011 }
3012
3013 if (var == NULL)
3014 {
3015 *baseObjectId = -1;
3016 return NULL;
3017 }
3018
3021 {
3022 *baseObjectId = 0;
3024 }
3025 else
3027
3028 *baseObject = *result;
3029 *baseObjectId = id;
3030
3031 return result;
3032}
3033
3034static int
3036{
3038
3040}
3041
3042
3043
3044
3045
3046
3047static void
3049{
3050 switch (typid)
3051 {
3052 case BOOLOID:
3055 break;
3056 case NUMERICOID:
3058 break;
3059 case INT2OID:
3061 break;
3062 case INT4OID:
3064 break;
3065 case INT8OID:
3067 break;
3068 case FLOAT4OID:
3070 break;
3071 case FLOAT8OID:
3073 break;
3074 case TEXTOID:
3075 case VARCHAROID:
3079 break;
3080 case DATEOID:
3081 case TIMEOID:
3082 case TIMETZOID:
3083 case TIMESTAMPOID:
3084 case TIMESTAMPTZOID:
3086 res->val.datetime.value = val;
3087 res->val.datetime.typid = typid;
3088 res->val.datetime.typmod = typmod;
3089 res->val.datetime.tz = 0;
3090 break;
3091 case JSONBOID:
3092 {
3095
3097 {
3099
3102 }
3103 else
3105 break;
3106 }
3107 case JSONOID:
3108 {
3112
3116
3118 break;
3119 }
3120 default:
3122 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3123 errmsg("could not convert value of type %s to jsonpath",
3125 }
3126}
3127
3128
3129static void
3131{
3134}
3135
3136
3137
3138
3139static void
3142{
3143 char *varName;
3144 int varNameLength;
3146 int baseObjectId;
3148
3151
3152 if (cxt->vars == NULL ||
3153 (v = cxt->getVar(cxt->vars, varName, varNameLength,
3154 &baseObject, &baseObjectId)) == NULL)
3156 (errcode(ERRCODE_UNDEFINED_OBJECT),
3157 errmsg("could not find jsonpath variable \"%s\"",
3158 pnstrdup(varName, varNameLength))));
3159
3160 if (baseObjectId > 0)
3161 {
3164 }
3165}
3166
3167
3168
3169
3170
3173 JsonbValue *baseObject, int *baseObjectId)
3174{
3178
3180 tmp.val.string.val = varName;
3181 tmp.val.string.len = varNameLength;
3182
3184
3185 if (result == NULL)
3186 {
3187 *baseObjectId = -1;
3188 return NULL;
3189 }
3190
3191 *baseObjectId = 1;
3193
3194 return result;
3195}
3196
3197
3198
3199
3200
3201static int
3203{
3205
3207 {
3209 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3210 errmsg("\"vars\" argument is not an object"),
3211 errdetail("Jsonpath parameters should be encoded as key-value pairs of \"vars\" object."));
3212 }
3213
3214
3215 return vars != NULL ? 1 : 0;
3216}
3217
3218
3219
3220
3221
3222
3223static int
3225{
3227
3229 {
3231
3234 }
3235
3236 return -1;
3237}
3238
3239
3242{
3244
3246}
3247
3248
3249
3250
3251static int
3253 const char *s2, int len2)
3254{
3255 int cmp;
3256
3257 cmp = memcmp(s1, s2, Min(len1, len2));
3258
3259 if (cmp != 0)
3260 return cmp;
3261
3262 if (len1 == len2)
3263 return 0;
3264
3265 return len1 < len2 ? -1 : 1;
3266}
3267
3268
3269
3270
3271
3272static int
3274 const char *mbstr2, int mblen2)
3275{
3278 {
3279
3280
3281
3282
3283
3285 }
3286 else
3287 {
3288 char *utf8str1,
3289 *utf8str2;
3290 int cmp,
3291 utf8len1,
3292 utf8len2;
3293
3294
3295
3296
3297
3298
3299
3302 utf8len1 = (mbstr1 == utf8str1) ? mblen1 : strlen(utf8str1);
3303 utf8len2 = (mbstr2 == utf8str2) ? mblen2 : strlen(utf8str2);
3304
3306
3307
3308
3309
3310
3311 if (mbstr1 == utf8str1 && mbstr2 == utf8str2)
3312 return cmp;
3313
3314
3315 if (mbstr1 != utf8str1)
3316 pfree(utf8str1);
3317 if (mbstr2 != utf8str2)
3318 pfree(utf8str2);
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329 if (cmp == 0)
3331 else
3332 return cmp;
3333 }
3334}
3335
3336
3337
3338
3341{
3342 int cmp;
3343 bool res;
3344
3346 {
3348
3349
3350
3351
3352
3354
3355
3357 }
3358
3359 switch (jb1->type)
3360 {
3362 cmp = 0;
3363 break;
3365 cmp = jb1->val.boolean == jb2->val.boolean ? 0 :
3366 jb1->val.boolean ? 1 : -1;
3367 break;
3370 break;
3373 return jb1->val.string.len != jb2->val.string.len ||
3374 memcmp(jb1->val.string.val,
3375 jb2->val.string.val,
3377
3379 jb2->val.string.val, jb2->val.string.len);
3380 break;
3382 {
3383 bool cast_error;
3384
3386 jb1->val.datetime.typid,
3387 jb2->val.datetime.value,
3388 jb2->val.datetime.typid,
3389 useTz,
3390 &cast_error);
3391
3392 if (cast_error)
3394 }
3395 break;
3396
3400 return jpbUnknown;
3401
3402 default:
3403 elog(ERROR, "invalid jsonb value type %d", jb1->type);
3404 }
3405
3406 switch (op)
3407 {
3409 res = (cmp == 0);
3410 break;
3412 res = (cmp != 0);
3413 break;
3415 res = (cmp < 0);
3416 break;
3418 res = (cmp > 0);
3419 break;
3421 res = (cmp <= 0);
3422 break;
3424 res = (cmp >= 0);
3425 break;
3426 default:
3427 elog(ERROR, "unrecognized jsonpath operation: %d", op);
3429 }
3430
3432}
3433
3434
3435static int
3437{
3441}
3442
3445{
3447
3448 *dst = *src;
3449
3450 return dst;
3451}
3452
3453
3454
3455
3456
3460{
3464 Datum numeric_index;
3465 bool have_error = false;
3466
3468 return res;
3469
3473 (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
3474 errmsg("jsonpath array subscript is not a single numeric value"))));
3475
3479
3481 &have_error);
3482
3483 if (have_error)
3485 (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
3486 errmsg("jsonpath array subscript is out of integer range"))));
3487
3489}
3490
3491
3494{
3496
3500
3501 return baseObject;
3502}
3503
3504static void
3506{
3509}
3510
3511static void
3513{
3515 {
3518 }
3519 else if (!jvl->list)
3521 else
3523}
3524
3525static int
3527{
3529}
3530
3531static bool
3533{
3535}
3536
3539{
3541}
3542
3543static List *
3545{
3548
3549 return jvl->list;
3550}
3551
3552static void
3554{
3556 {
3559 it->next = NULL;
3560 }
3561 else if (jvl->list != NIL)
3562 {
3566 }
3567 else
3568 {
3569 it->value = NULL;
3571 it->next = NULL;
3572 }
3573}
3574
3575
3576
3577
3580{
3582
3583 if (it->next)
3584 {
3587 }
3588 else
3589 {
3590 it->value = NULL;
3591 }
3592
3593 return result;
3594}
3595
3596
3597
3598
3601{
3603 jbv->val.binary.data = &jb->root;
3605
3606 return jbv;
3607}
3608
3609
3610
3611
3612static int
3614{
3616
3618 {
3620
3621
3623
3628 else
3629 elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header);
3630 }
3631
3632 return type;
3633}
3634
3635
3638{
3639
3642
3643 return scalar->type == type ? scalar : NULL;
3644}
3645
3646
3649{
3653
3655
3659
3661}
3662
3663
3664static void
3666{
3667 if (!useTz)
3669 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3670 errmsg("cannot convert value from %s to %s without time zone usage",
3671 type1, type2),
3672 errhint("Use *_tz() function for time zone support.")));
3673}
3674
3675
3678{
3680
3682}
3683
3684
3685
3686
3687
3688static int
3690{
3692}
3693
3694
3695
3696
3697static int
3699{
3701
3703}
3704
3705
3706
3707
3708static int
3710{
3712
3714}
3715
3716
3717
3718
3719
3720
3721static int
3723 bool useTz, bool *cast_error)
3724{
3726
3727 *cast_error = false;
3728
3729 switch (typid1)
3730 {
3731 case DATEOID:
3732 switch (typid2)
3733 {
3734 case DATEOID:
3736
3737 break;
3738
3739 case TIMESTAMPOID:
3742 useTz);
3743
3744 case TIMESTAMPTZOID:
3747 useTz);
3748
3749 case TIMEOID:
3750 case TIMETZOID:
3751 *cast_error = true;
3752 return 0;
3753
3754 default:
3755 elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
3756 typid2);
3757 }
3758 break;
3759
3760 case TIMEOID:
3761 switch (typid2)
3762 {
3763 case TIMEOID:
3765
3766 break;
3767
3768 case TIMETZOID:
3771
3772 break;
3773
3774 case DATEOID:
3775 case TIMESTAMPOID:
3776 case TIMESTAMPTZOID:
3777 *cast_error = true;
3778 return 0;
3779
3780 default:
3781 elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
3782 typid2);
3783 }
3784 break;
3785
3786 case TIMETZOID:
3787 switch (typid2)
3788 {
3789 case TIMEOID:
3792
3793 break;
3794
3795 case TIMETZOID:
3797
3798 break;
3799
3800 case DATEOID:
3801 case TIMESTAMPOID:
3802 case TIMESTAMPTZOID:
3803 *cast_error = true;
3804 return 0;
3805
3806 default:
3807 elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
3808 typid2);
3809 }
3810 break;
3811
3812 case TIMESTAMPOID:
3813 switch (typid2)
3814 {
3815 case DATEOID:
3818 useTz);
3819
3820 case TIMESTAMPOID:
3822
3823 break;
3824
3825 case TIMESTAMPTZOID:
3828 useTz);
3829
3830 case TIMEOID:
3831 case TIMETZOID:
3832 *cast_error = true;
3833 return 0;
3834
3835 default:
3836 elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
3837 typid2);
3838 }
3839 break;
3840
3841 case TIMESTAMPTZOID:
3842 switch (typid2)
3843 {
3844 case DATEOID:
3847 useTz);
3848
3849 case TIMESTAMPOID:
3852 useTz);
3853
3854 case TIMESTAMPTZOID:
3856
3857 break;
3858
3859 case TIMEOID:
3860 case TIMETZOID:
3861 *cast_error = true;
3862 return 0;
3863
3864 default:
3865 elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
3866 typid2);
3867 }
3868 break;
3869
3870 default:
3871 elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u", typid1);
3872 }
3873
3874 if (*cast_error)
3875 return 0;
3876
3878}
3879
3880
3881
3882
3883
3884
3885
3886bool
3888{
3890
3894
3896
3899
3900 return res == jperOk;
3901}
3902
3903
3904
3905
3906
3907
3908
3912 const char *column_name)
3913{
3915 bool wrap;
3918 int count;
3919
3925 {
3927 *empty = false;
3928 return (Datum) 0;
3929 }
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3951 if (singleton == NULL)
3952 wrap = false;
3954 wrap = false;
3956 wrap = true;
3958 wrap = count > 1;
3959 else
3960 {
3961 elog(ERROR, "unrecognized json wrapper %d", (int) wrapper);
3962 wrap = false;
3963 }
3964
3965 if (wrap)
3967
3968
3969 if (count > 1)
3970 {
3972 {
3974 return (Datum) 0;
3975 }
3976
3977 if (column_name)
3979 (errcode(ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM),
3980 errmsg("JSON path expression for column \"%s\" must return single item when no wrapper is requested",
3981 column_name),
3982 errhint("Use the WITH WRAPPER clause to wrap SQL/JSON items into an array.")));
3983 else
3985 (errcode(ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM),
3986 errmsg("JSON path expression in JSON_QUERY must return single item when no wrapper is requested"),
3987 errhint("Use the WITH WRAPPER clause to wrap SQL/JSON items into an array.")));
3988 }
3989
3990 if (singleton)
3992
3993 *empty = true;
3995}
3996
3997
3998
3999
4000
4001
4002
4005 const char *column_name)
4006{
4010 int count;
4011
4014 , &found, true);
4015
4017
4019 {
4021 *empty = false;
4022 return NULL;
4023 }
4024
4026
4027 *empty = (count == 0);
4028
4029 if (*empty)
4030 return NULL;
4031
4032
4033 if (count > 1)
4034 {
4036 {
4038 return NULL;
4039 }
4040
4041 if (column_name)
4043 (errcode(ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM),
4044 errmsg("JSON path expression for column \"%s\" must return single scalar item",
4045 column_name)));
4046 else
4048 (errcode(ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM),
4049 errmsg("JSON path expression in JSON_VALUE must return single scalar item")));
4050 }
4051
4055
4056
4058 {
4060 {
4062 return NULL;
4063 }
4064
4065 if (column_name)
4067 (errcode(ERRCODE_SQL_JSON_SCALAR_REQUIRED),
4068 errmsg("JSON path expression for column \"%s\" must return single scalar item",
4069 column_name)));
4070 else
4072 (errcode(ERRCODE_SQL_JSON_SCALAR_REQUIRED),
4073 errmsg("JSON path expression in JSON_VALUE must return single scalar item")));
4074 }
4075
4077 return NULL;
4078
4079 return res;
4080}
4081
4082
4083
4084
4085
4086
4087
4090{
4092
4094 elog(ERROR, "%s called with invalid TableFuncScanState", fname);
4097 elog(ERROR, "%s called with invalid TableFuncScanState", fname);
4098
4099 return result;
4100}
4101
4102
4103
4104
4105
4106
4107
4108
4109static void
4111{
4119
4122
4123
4124
4125
4126
4127 if (state->passingvalexprs)
4128 {
4131
4135 namelc, je->passing_names)
4136 {
4140
4145
4146
4147
4148
4149
4152
4154 }
4155 }
4156
4159
4160
4161
4162
4163
4166
4167 state->opaque = cxt;
4168}
4169
4170
4171
4172
4173
4174static void
4176{
4179
4180
4182
4183 state->opaque = NULL;
4184}
4185
4186
4187
4188
4189
4190
4195{
4197
4199 planstate->parent = parentstate;
4200
4202 {
4204 int i;
4205
4210
4211
4214
4215 for (i = scan->colMin; i >= 0 && i <= scan->colMax; i++)
4217
4220 }
4222 {
4224
4226 args, mcxt);
4228 args, mcxt);
4229 }
4230
4231 return planstate;
4232}
4233
4234
4235
4236
4237
4238static void
4240{
4243
4245}
4246
4247
4248
4249
4250
4251static void
4253{
4258
4260
4262
4264
4268 &planstate->found,
4269 true);
4270
4272
4274 {
4277 }
4278
4279
4284}
4285
4286
4287
4288
4289
4290
4291static bool
4293{
4298 else
4299 elog(ERROR, "invalid JsonTablePlan %d", (int) planstate->plan->type);
4300
4302
4303 return false;
4304}
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318static bool
4320{
4323
4324
4325
4326
4327
4329 {
4331 return true;
4332 }
4333
4334
4336
4337
4338 if (jbv == NULL)
4339 {
4342 return false;
4343 }
4344
4345
4346
4347
4348
4353
4354
4356
4357
4358 if (planstate->nested)
4359 {
4360
4362
4363
4364
4365
4366
4367
4368
4370 }
4371
4372
4373 return true;
4374}
4375
4376
4377
4378
4379
4380static void
4382{
4383
4386 {
4388
4391
4392
4393
4394
4395
4396 }
4398 {
4401 }
4402}
4403
4404
4405
4406
4407
4408
4409static bool
4411{
4412
4413
4415 {
4416
4417
4418
4419
4421 {
4422
4423 return false;
4424 }
4425 }
4426
4427 return true;
4428}
4429
4430
4431
4432
4433
4434
4435
4436static bool
4438{
4441
4443}
4444
4445
4446
4447
4448
4449
4450
4451
4454 Oid typid, int32 typmod, bool *isnull)
4455{
4463
4464
4465 if (current->isnull)
4466 {
4467 result = (Datum) 0;
4468 *isnull = true;
4469 }
4470
4471 else if (estate)
4472 {
4475
4476
4479
4480 result = ExecEvalExpr(estate, econtext, isnull);
4481
4484 }
4485
4486 else
4487 {
4489 *isnull = false;
4490 }
4491
4492 return result;
4493}
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)
void j2date(int jd, int *year, int *month, int *day)
int32 numeric_int4_opt_error(Numeric num, bool *have_error)
Datum float8_numeric(PG_FUNCTION_ARGS)
Datum numeric_cmp(PG_FUNCTION_ARGS)
Numeric numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
Numeric numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
Numeric int64_to_numeric(int64 val)
Datum float4_numeric(PG_FUNCTION_ARGS)
Datum int4_numeric(PG_FUNCTION_ARGS)
Datum numeric_uminus(PG_FUNCTION_ARGS)
Datum numeric_ceil(PG_FUNCTION_ARGS)
Datum numerictypmodin(PG_FUNCTION_ARGS)
Datum numeric_out(PG_FUNCTION_ARGS)
int64 numeric_int8_opt_error(Numeric num, bool *have_error)
Datum numeric_trunc(PG_FUNCTION_ARGS)
Datum numeric_in(PG_FUNCTION_ARGS)
bool numeric_is_nan(Numeric num)
Numeric numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
Numeric numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)
Datum int2_numeric(PG_FUNCTION_ARGS)
Datum numeric_abs(PG_FUNCTION_ARGS)
Datum int8_numeric(PG_FUNCTION_ARGS)
Numeric numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
bool numeric_is_inf(Numeric num)
Datum numeric_floor(PG_FUNCTION_ARGS)
Datum timestamp_cmp(PG_FUNCTION_ARGS)
bool AdjustTimestampForTypmod(Timestamp *time, int32 typmod, Node *escontext)
Datum timestamp_timestamptz(PG_FUNCTION_ARGS)
int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
int32 anytimestamp_typmod_check(bool istz, int32 typmod)
Datum timestamptz_timestamp(PG_FUNCTION_ARGS)
bool parse_bool(const char *value, bool *result)
#define PG_USED_FOR_ASSERTS_ONLY
#define POSTGRES_EPOCH_JDATE
int32 date_cmp_timestamp_internal(DateADT dateVal, Timestamp dt2)
Datum date_cmp(PG_FUNCTION_ARGS)
Datum time_cmp(PG_FUNCTION_ARGS)
Datum timestamp_time(PG_FUNCTION_ARGS)
int32 anytime_typmod_check(bool istz, int32 typmod)
Datum date_timestamptz(PG_FUNCTION_ARGS)
Datum timetz_cmp(PG_FUNCTION_ARGS)
Datum timetz_time(PG_FUNCTION_ARGS)
Datum time_timetz(PG_FUNCTION_ARGS)
Datum timestamptz_timetz(PG_FUNCTION_ARGS)
void AdjustTimeForTypmod(TimeADT *time, int32 typmod)
Datum timestamptz_date(PG_FUNCTION_ARGS)
Datum timestamp_date(PG_FUNCTION_ARGS)
int32 date_cmp_timestamptz_internal(DateADT dateVal, TimestampTz dt2)
Datum timestamptz_time(PG_FUNCTION_ARGS)
Datum date_timestamp(PG_FUNCTION_ARGS)
static TimeTzADT * DatumGetTimeTzADTP(Datum X)
static DateADT DatumGetDateADT(Datum X)
static TimeADT DatumGetTimeADT(Datum X)
static Datum TimeTzADTPGetDatum(const TimeTzADT *X)
static Datum TimeADTGetDatum(TimeADT X)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
float8 float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Datum Int64GetDatum(int64 X)
Datum Float8GetDatum(float8 X)
bool DirectInputFunctionCallSafe(PGFunction func, char *str, Oid typioparam, int32 typmod, fmNodePtr escontext, Datum *result)
#define PG_FREE_IF_COPY(ptr, n)
#define DirectFunctionCall2(func, arg1, arg2)
#define DirectFunctionCall1(func, arg1)
#define PG_GETARG_BOOL(n)
Datum(* PGFunction)(FunctionCallInfo fcinfo)
#define PG_RETURN_BOOL(x)
char * format_type_be(Oid type_oid)
Datum parse_datetime(text *date_txt, text *fmt, Oid collid, bool strict, Oid *typid, int32 *typmod, int *tz, Node *escontext)
#define SRF_IS_FIRSTCALL()
#define SRF_PERCALL_SETUP()
#define SRF_RETURN_NEXT(_funcctx, _result)
#define SRF_FIRSTCALL_INIT()
#define SRF_RETURN_DONE(_funcctx)
Assert(PointerIsAligned(start, uint64))
Datum int8in(PG_FUNCTION_ARGS)
Datum int4in(PG_FUNCTION_ARGS)
if(TABLE==NULL||TABLE_index==NULL)
char * JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp)
Datum jsonb_in(PG_FUNCTION_ARGS)
const char * JsonbTypeName(JsonbValue *val)
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
#define JsonContainerIsScalar(jc)
#define JsonContainerIsArray(jc)
#define JsonContainerSize(jc)
#define PG_GETARG_JSONB_P_COPY(x)
static Datum JsonbPGetDatum(const Jsonb *p)
#define IsAJsonbScalar(jsonbval)
#define PG_RETURN_JSONB_P(x)
#define PG_GETARG_JSONB_P(x)
#define JsonContainerIsObject(jc)
static Jsonb * DatumGetJsonbP(Datum d)
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
JsonbValue * getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)
Jsonb * JsonbValueToJsonb(JsonbValue *val)
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
bool jspGetBool(JsonPathItem *v)
void jspInit(JsonPathItem *v, JsonPath *js)
char * jspGetString(JsonPathItem *v, int32 *len)
Numeric jspGetNumeric(JsonPathItem *v)
bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)
const char * jspOperationName(JsonPathItemType type)
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
bool jspConvertRegexFlags(uint32 xflags, int *result, struct Node *escontext)
#define PG_GETARG_JSONPATH_P(x)
#define PG_GETARG_JSONPATH_P_COPY(x)
static JsonPath * DatumGetJsonPathP(Datum d)
static JsonPathBool executeComparison(JsonPathItem *cmp, JsonbValue *lv, JsonbValue *rv, void *p)
bool JsonPathExists(Datum jb, JsonPath *jp, bool *error, List *vars)
static Datum jsonb_path_query_first_internal(FunctionCallInfo fcinfo, bool tz)
static JsonPathExecResult executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrap)
Datum jsonb_path_query_tz(PG_FUNCTION_ARGS)
#define jspAutoUnwrap(cxt)
Datum jsonb_path_exists_opr(PG_FUNCTION_ARGS)
static int cmpDateToTimestamp(DateADT date1, Timestamp ts2, bool useTz)
static JsonPathBool executeBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool canHaveNext)
static int JsonbArraySize(JsonbValue *jb)
struct JsonBaseObjectInfo JsonBaseObjectInfo
Numeric(* BinaryArithmFunc)(Numeric num1, Numeric num2, bool *error)
static void JsonTableResetRowPattern(JsonTablePlanState *planstate, Datum item)
struct JsonTablePlanState JsonTablePlanState
static List * JsonValueListGetList(JsonValueList *jvl)
struct JsonValueList JsonValueList
static int compareStrings(const char *mbstr1, int mblen1, const char *mbstr2, int mblen2)
static JsonPathExecResult appendBoolResult(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonValueList *found, JsonPathBool res)
Datum jsonb_path_query_first(PG_FUNCTION_ARGS)
static void JsonTableSetDocument(TableFuncScanState *state, Datum value)
static Datum jsonb_path_query_array_internal(FunctionCallInfo fcinfo, bool tz)
static JsonPathExecResult executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, BinaryArithmFunc func, JsonValueList *found)
static int countVariablesFromJsonb(void *varsJsonb)
static JsonTableExecContext * GetJsonTableExecContext(TableFuncScanState *state, const char *fname)
static Datum jsonb_path_query_internal(FunctionCallInfo fcinfo, bool tz)
#define RETURN_ERROR(throw_error)
#define JSON_TABLE_EXEC_CONTEXT_MAGIC
static JsonPathExecResult executeItemOptUnwrapResultNoThrow(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)
static JsonPathExecResult executeAnyItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbContainer *jbc, JsonValueList *found, uint32 level, uint32 first, uint32 last, bool ignoreStructuralErrors, bool unwrapNext)
static JsonPathExecResult executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
static JsonPathBool executeStartsWith(JsonPathItem *jsp, JsonbValue *whole, JsonbValue *initial, void *param)
static Datum jsonb_path_match_internal(FunctionCallInfo fcinfo, bool tz)
static JsonBaseObjectInfo setBaseObject(JsonPathExecContext *cxt, JsonbValue *jbv, int32 id)
static Datum castTimeToTimeTz(Datum time, bool useTz)
static void JsonValueListAppend(JsonValueList *jvl, JsonbValue *jbv)
static JsonPathExecResult executeUnaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, PGFunction func, JsonValueList *found)
Datum JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper, bool *empty, bool *error, List *vars, const char *column_name)
static int JsonbType(JsonbValue *jb)
static void JsonTableResetNestedPlan(JsonTablePlanState *planstate)
static JsonPathExecResult executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
static void JsonItemFromDatum(Datum val, Oid typid, int32 typmod, JsonbValue *res)
struct JsonPathExecContext JsonPathExecContext
JsonbValue *(* JsonPathGetVarCallback)(void *vars, char *varName, int varNameLen, JsonbValue *baseObject, int *baseObjectId)
Datum jsonb_path_match_tz(PG_FUNCTION_ARGS)
static JsonPathExecResult executeItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
Datum jsonb_path_query(PG_FUNCTION_ARGS)
static bool JsonTablePlanScanNextRow(JsonTablePlanState *planstate)
Datum jsonb_path_match_opr(PG_FUNCTION_ARGS)
JsonPathBool(* JsonPathPredicateCallback)(JsonPathItem *jsp, JsonbValue *larg, JsonbValue *rarg, void *param)
static JsonbValue * getJsonPathVariableFromJsonb(void *varsJsonb, char *varName, int varNameLength, JsonbValue *baseObject, int *baseObjectId)
static JsonbValue * GetJsonPathVar(void *cxt, char *varName, int varNameLen, JsonbValue *baseObject, int *baseObjectId)
struct JsonTablePlanRowSource JsonTablePlanRowSource
static void JsonValueListInitIterator(const JsonValueList *jvl, JsonValueListIterator *it)
static JsonPathBool executeNestedBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb)
static int compareDatetime(Datum val1, Oid typid1, Datum val2, Oid typid2, bool useTz, bool *cast_error)
static int cmpDateToTimestampTz(DateADT date1, TimestampTz tstz2, bool useTz)
Datum jsonb_path_match(PG_FUNCTION_ARGS)
static JsonbValue * wrapItemsInArray(const JsonValueList *items)
static JsonbValue * JsonValueListNext(const JsonValueList *jvl, JsonValueListIterator *it)
#define jspStrictAbsenceOfErrors(cxt)
static void JsonTableDestroyOpaque(TableFuncScanState *state)
static void JsonValueListClear(JsonValueList *jvl)
static void JsonTableInitOpaque(TableFuncScanState *state, int natts)
static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)
Datum jsonb_path_exists(PG_FUNCTION_ARGS)
#define jperIsError(jper)
static Datum jsonb_path_exists_internal(FunctionCallInfo fcinfo, bool tz)
JsonbValue * JsonPathValue(Datum jb, JsonPath *jp, bool *empty, bool *error, List *vars, const char *column_name)
static bool JsonTablePlanNextRow(JsonTablePlanState *planstate)
struct JsonValueListIterator JsonValueListIterator
Datum jsonb_path_query_array_tz(PG_FUNCTION_ARGS)
static JsonTablePlanState * JsonTableInitPlan(JsonTableExecContext *cxt, JsonTablePlan *plan, JsonTablePlanState *parentstate, List *args, MemoryContext mcxt)
static JsonPathExecResult executeItemUnwrapTargetArray(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrapElements)
static int cmpTimestampToTimestampTz(Timestamp ts1, TimestampTz tstz2, bool useTz)
static JsonPathBool executeLikeRegex(JsonPathItem *jsp, JsonbValue *str, JsonbValue *rarg, void *param)
static int JsonValueListLength(const JsonValueList *jvl)
static bool JsonValueListIsEmpty(JsonValueList *jvl)
#define jspIgnoreStructuralErrors(cxt)
struct JsonLikeRegexContext JsonLikeRegexContext
static void JsonbValueInitNumericDatum(JsonbValue *jbv, Datum num)
static int CountJsonPathVars(void *cxt)
struct JsonTableExecContext JsonTableExecContext
static int compareNumeric(Numeric a, Numeric b)
static Datum JsonTableGetValue(TableFuncScanState *state, int colnum, Oid typid, int32 typmod, bool *isnull)
static JsonPathBool compareItems(int32 op, JsonbValue *jb1, JsonbValue *jb2, bool useTz)
static JsonPathExecResult getArrayIndex(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, int32 *index)
Datum jsonb_path_query_first_tz(PG_FUNCTION_ARGS)
Datum jsonb_path_query_array(PG_FUNCTION_ARGS)
static JsonPathExecResult executeItemOptUnwrapResult(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)
static JsonPathExecResult executeNumericItemMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, PGFunction func, JsonValueList *found)
static void getJsonPathVariable(JsonPathExecContext *cxt, JsonPathItem *variable, JsonbValue *value)
static JsonbValue * JsonValueListHead(JsonValueList *jvl)
Datum jsonb_path_exists_tz(PG_FUNCTION_ARGS)
static bool JsonTableFetchRow(TableFuncScanState *state)
static void getJsonPathItem(JsonPathExecContext *cxt, JsonPathItem *item, JsonbValue *value)
static JsonPathBool executePredicate(JsonPathExecContext *cxt, JsonPathItem *pred, JsonPathItem *larg, JsonPathItem *rarg, JsonbValue *jb, bool unwrapRightArg, JsonPathPredicateCallback exec, void *param)
static int binaryCompareStrings(const char *s1, int len1, const char *s2, int len2)
const TableFuncRoutine JsonbTableRoutine
int(* JsonPathCountVarsCallback)(void *vars)
static JsonbValue * JsonbInitBinary(JsonbValue *jbv, Jsonb *jb)
static void checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2)
static JsonPathExecResult executeJsonPath(JsonPath *path, void *vars, JsonPathGetVarCallback getVar, JsonPathCountVarsCallback countVars, Jsonb *json, bool throwErrors, JsonValueList *result, bool useTz)
static bool JsonTablePlanJoinNextRow(JsonTablePlanState *planstate)
#define jspThrowErrors(cxt)
static JsonbValue * copyJsonbValue(JsonbValue *src)
List * lappend(List *list, void *datum)
List * list_delete_first(List *list)
int GetDatabaseEncoding(void)
char * pg_server_to_any(const char *s, int len, int encoding)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext TopMemoryContext
MemoryContext CurrentMemoryContext
char * pnstrdup(const char *in, Size len)
void MemoryContextResetOnly(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define CHECK_FOR_INTERRUPTS()
Oid exprType(const Node *expr)
int32 exprTypmod(const Node *expr)
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
static Numeric DatumGetNumeric(Datum X)
struct NumericData * Numeric
static Datum NumericGetDatum(Numeric X)
int pg_ltoa(int32 value, char *a)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
static void * list_nth(const List *list, int n)
static ListCell * list_head(const List *l)
static ListCell * list_second_cell(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
#define list_make2(x1, x2)
PGDLLIMPORT pg_tz * session_timezone
static bool DatumGetBool(Datum X)
static Datum PointerGetDatum(const void *X)
static char * DatumGetCString(Datum X)
static Datum CStringGetDatum(const char *X)
static Datum Int32GetDatum(int32 X)
static int32 DatumGetInt32(Datum X)
static int cmp(const chr *x, const chr *y, size_t len)
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
bool RE_compile_and_execute(text *text_re, char *dat, int dat_len, int cflags, Oid collation, int nmatch, regmatch_t *pmatch)
void check_stack_depth(void)
MemoryContext multi_call_memory_ctx
bool ignoreStructuralErrors
JsonPathGetVarCallback getVar
int lastGeneratedObjectId
JsonBaseObjectInfo baseObject
struct JsonPathItem::@147::@148 args
union JsonPathItem::@147 content
struct JsonPathItem::@147::@149 array
struct JsonPathItem::@147::@150 anybounds
struct JsonPathItem::@147::@152 like_regex
JsonTablePlanState * rootplanstate
JsonTablePlanState ** colplanstates
struct JsonTablePlanState * left
struct JsonTablePlanState * nested
struct JsonTablePlanState * parent
struct JsonTablePlanState * right
JsonTablePlanRowSource current
JsonValueListIterator iter
void(* InitOpaque)(struct TableFuncScanState *state, int natts)
static Datum TimestampTzGetDatum(TimestampTz X)
static Datum TimestampGetDatum(Timestamp X)
static Timestamp DatumGetTimestamp(Datum X)
static TimestampTz DatumGetTimestampTz(Datum X)
#define VARSIZE_ANY_EXHDR(PTR)
text * cstring_to_text_with_len(const char *s, int len)
text * cstring_to_text(const char *s)
char * text_to_cstring(const text *t)