From 50cc9912aff4138fa0ef9ea6db453952182c55b6 Mon Sep 17 00:00:00 2001 From: Taiki Koshino Date: Thu, 20 Aug 2026 01:11:33 +0900 Subject: [PATCH v8] Feature: Import PostgreSQL 19 new parser. Major changes of PostgreSQL 19 parser include: - Add support for SQL Property Graph Queries (SQL/PGQ). - Add FOR PORTION OF clause to UPDATE and DELETE. - Allow GROUP BY to process target list subqueries that have expressions referencing non-subquery columns. - Allow window functions to ignore NULLs with the IGNORE NULLS/RESPECT NULLS clause. - Add support for INSERT ... ON CONFLICT DO SELECT ... RETURNING. - Add REPACK command which replaces VACUUM FULL and CLUSTER. - Allow REPACK to rebuild tables without access-exclusive locking. - Allow partitions to be merged and split using ALTER TABLE ... MERGE/SPLIT PARTITIONS. - Allow GRANT/REVOKE to specify the effective role performing the privileges adjustment. - Allow CREATE SCHEMA to create more types of objects in newly-created schemas. - Allow CHECKPOINT to accept a list of options. - Add CONNECTION clause to CREATE FOREIGN DATA WRAPPER to specify a function to be called for subscription connection parameters. - Add memory usage and parallelism reporting to VACUUM (VERBOSE) and autovacuum logs. etc. --- src/include/parser/keywords.h | 4 +- src/include/parser/kwlist.h | 17 + src/include/parser/kwlist_d.h | 961 +++++----- src/include/parser/makefuncs.h | 6 +- src/include/parser/nodes.h | 27 +- src/include/parser/nodetags.h | 981 +++++----- src/include/parser/parsenodes.h | 381 +++- src/include/parser/parser.h | 8 +- src/include/parser/pg_class.h | 9 +- src/include/parser/pg_config_manual.h | 27 +- src/include/parser/pg_list.h | 44 +- src/include/parser/pg_trigger.h | 8 +- src/include/parser/pg_wchar.h | 244 +-- src/include/parser/primnodes.h | 140 +- src/include/parser/scanner.h | 9 +- src/include/parser/scansup.h | 4 +- src/include/parser/stringinfo.h | 6 +- .../parser/unicode_east_asian_fw_table.h | 21 +- src/include/parser/unicode_nonspacing_table.h | 9 +- src/include/parser/value.h | 4 +- src/include/utils/elog.h | 36 +- src/include/utils/palloc.h | 5 + src/parser/copyfuncs.c | 16 +- src/parser/gram.y | 1581 +++++++++++++++-- src/parser/gram_minimal.y | 1581 +++++++++++++++-- src/parser/gram_template.y | 1581 +++++++++++++++-- src/parser/keywords.c | 4 +- src/parser/kwlookup.c | 4 +- src/parser/list.c | 4 +- src/parser/makefuncs.c | 9 +- src/parser/outfuncs.c | 63 +- src/parser/parser.c | 20 +- src/parser/scan.l | 103 +- src/parser/scansup.c | 4 +- src/parser/snprintf.c | 101 +- src/parser/stringinfo.c | 8 +- src/parser/value.c | 4 +- src/parser/wchar.c | 293 +-- src/protocol/pool_process_query.c | 6 +- src/rewrite/pool_timestamp.c | 24 +- src/sql/pgpool-regclass/pgpool-regclass.c | 1 + 41 files changed, 6008 insertions(+), 2350 deletions(-) diff --git a/src/include/parser/keywords.h b/src/include/parser/keywords.h index a56380499..5f7f4e0e7 100644 --- a/src/include/parser/keywords.h +++ b/src/include/parser/keywords.h @@ -4,8 +4,8 @@ * PostgreSQL's list of SQL keywords * * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/common/keywords.h diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 098738447..fbb8ad8e7 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -137,6 +137,7 @@ PG_KEYWORD("delimiters", DELIMITERS, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("depends", DEPENDS, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("depth", DEPTH, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("desc", DESC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("destination", DESTINATION, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("detach", DETACH, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("dictionary", DICTIONARY, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("disable", DISABLE_P, UNRESERVED_KEYWORD, BARE_LABEL) @@ -148,6 +149,7 @@ PG_KEYWORD("domain", DOMAIN_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("double", DOUBLE_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("drop", DROP, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("each", EACH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("edge", EDGE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("else", ELSE, RESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("empty", EMPTY_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("enable", ENABLE_P, UNRESERVED_KEYWORD, BARE_LABEL) @@ -192,6 +194,8 @@ PG_KEYWORD("generated", GENERATED, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("global", GLOBAL, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("grant", GRANT, RESERVED_KEYWORD, AS_LABEL) PG_KEYWORD("granted", GRANTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("graph", GRAPH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("graph_table", GRAPH_TABLE, COL_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("greatest", GREATEST, COL_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("group", GROUP_P, RESERVED_KEYWORD, AS_LABEL) PG_KEYWORD("grouping", GROUPING, COL_NAME_KEYWORD, BARE_LABEL) @@ -203,6 +207,7 @@ PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL) PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("ignore", IGNORE_P, UNRESERVED_KEYWORD, AS_LABEL) PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL) @@ -270,6 +275,7 @@ PG_KEYWORD("location", LOCATION, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("lock", LOCK_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("locked", LOCKED, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("logged", LOGGED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("lsn", LSN_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("mapping", MAPPING, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("match", MATCH, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("matched", MATCHED, UNRESERVED_KEYWORD, BARE_LABEL) @@ -296,6 +302,7 @@ PG_KEYWORD("nfd", NFD, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("nfkc", NFKC, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("nfkd", NFKD, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("no", NO, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("node", NODE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("none", NONE, COL_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("normalize", NORMALIZE, COL_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("normalized", NORMALIZED, UNRESERVED_KEYWORD, BARE_LABEL) @@ -338,6 +345,7 @@ PG_KEYWORD("parameter", PARAMETER, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("parser", PARSER, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("partial", PARTIAL, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("partition", PARTITION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("partitions", PARTITIONS, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("path", PATH, UNRESERVED_KEYWORD, BARE_LABEL) @@ -347,6 +355,7 @@ PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("plan", PLAN, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("plans", PLANS, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("policy", POLICY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("portion", PORTION, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("position", POSITION, COL_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("preceding", PRECEDING, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("precision", PRECISION, COL_NAME_KEYWORD, AS_LABEL) @@ -360,6 +369,8 @@ PG_KEYWORD("procedural", PROCEDURAL, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("procedure", PROCEDURE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("procedures", PROCEDURES, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("program", PROGRAM, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("properties", PROPERTIES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("property", PROPERTY, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("publication", PUBLICATION, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("quote", QUOTE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("quotes", QUOTES, UNRESERVED_KEYWORD, BARE_LABEL) @@ -373,13 +384,16 @@ PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("referencing", REFERENCING, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("reindex", REINDEX, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("relationship", RELATIONSHIP, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("relative", RELATIVE_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("release", RELEASE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("rename", RENAME, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("repack", REPACK, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("repeatable", REPEATABLE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("replace", REPLACE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("replica", REPLICA, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("reset", RESET, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("respect", RESPECT_P, UNRESERVED_KEYWORD, AS_LABEL) PG_KEYWORD("restart", RESTART, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("restrict", RESTRICT, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("return", RETURN, UNRESERVED_KEYWORD, BARE_LABEL) @@ -422,6 +436,7 @@ PG_KEYWORD("smallint", SMALLINT, COL_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("snapshot", SNAPSHOT, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("some", SOME, RESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("source", SOURCE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("split", SPLIT, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("sql", SQL_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("stable", STABLE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("standalone", STANDALONE_P, UNRESERVED_KEYWORD, BARE_LABEL) @@ -492,10 +507,12 @@ PG_KEYWORD("variadic", VARIADIC, RESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("varying", VARYING, UNRESERVED_KEYWORD, AS_LABEL) PG_KEYWORD("verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("version", VERSION_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("vertex", VERTEX, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("view", VIEW, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("views", VIEWS, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("virtual", VIRTUAL, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("volatile", VOLATILE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("wait", WAIT, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("when", WHEN, RESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("where", WHERE, RESERVED_KEYWORD, AS_LABEL) PG_KEYWORD("whitespace", WHITESPACE_P, UNRESERVED_KEYWORD, BARE_LABEL) diff --git a/src/include/parser/kwlist_d.h b/src/include/parser/kwlist_d.h index 023a3432a..2be45facf 100644 --- a/src/include/parser/kwlist_d.h +++ b/src/include/parser/kwlist_d.h @@ -3,7 +3,7 @@ * kwlist_d.h * List of keywords represented as a ScanKeywordList. * - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES @@ -133,6 +133,7 @@ static const char ScanKeywords_kw_string[] = "depends\0" "depth\0" "desc\0" + "destination\0" "detach\0" "dictionary\0" "disable\0" @@ -144,6 +145,7 @@ static const char ScanKeywords_kw_string[] = "double\0" "drop\0" "each\0" + "edge\0" "else\0" "empty\0" "enable\0" @@ -188,6 +190,8 @@ static const char ScanKeywords_kw_string[] = "global\0" "grant\0" "granted\0" + "graph\0" + "graph_table\0" "greatest\0" "group\0" "grouping\0" @@ -199,6 +203,7 @@ static const char ScanKeywords_kw_string[] = "hour\0" "identity\0" "if\0" + "ignore\0" "ilike\0" "immediate\0" "immutable\0" @@ -266,6 +271,7 @@ static const char ScanKeywords_kw_string[] = "lock\0" "locked\0" "logged\0" + "lsn\0" "mapping\0" "match\0" "matched\0" @@ -292,6 +298,7 @@ static const char ScanKeywords_kw_string[] = "nfkc\0" "nfkd\0" "no\0" + "node\0" "none\0" "normalize\0" "normalized\0" @@ -334,6 +341,7 @@ static const char ScanKeywords_kw_string[] = "parser\0" "partial\0" "partition\0" + "partitions\0" "passing\0" "password\0" "path\0" @@ -343,6 +351,7 @@ static const char ScanKeywords_kw_string[] = "plan\0" "plans\0" "policy\0" + "portion\0" "position\0" "preceding\0" "precision\0" @@ -356,6 +365,8 @@ static const char ScanKeywords_kw_string[] = "procedure\0" "procedures\0" "program\0" + "properties\0" + "property\0" "publication\0" "quote\0" "quotes\0" @@ -369,13 +380,16 @@ static const char ScanKeywords_kw_string[] = "referencing\0" "refresh\0" "reindex\0" + "relationship\0" "relative\0" "release\0" "rename\0" + "repack\0" "repeatable\0" "replace\0" "replica\0" "reset\0" + "respect\0" "restart\0" "restrict\0" "return\0" @@ -418,6 +432,7 @@ static const char ScanKeywords_kw_string[] = "snapshot\0" "some\0" "source\0" + "split\0" "sql\0" "stable\0" "standalone\0" @@ -488,10 +503,12 @@ static const char ScanKeywords_kw_string[] = "varying\0" "verbose\0" "version\0" + "vertex\0" "view\0" "views\0" "virtual\0" "volatile\0" + "wait\0" "when\0" "where\0" "whitespace\0" @@ -631,537 +648,561 @@ static const uint16 ScanKeywords_kw_offsets[] = { 886, 892, 897, - 904, - 915, - 923, - 931, - 940, + 909, + 916, + 927, + 935, 943, 952, - 959, - 966, + 955, + 964, 971, - 976, - 981, - 987, - 994, - 1003, - 1013, - 1017, - 1026, - 1031, - 1037, - 1044, - 1050, - 1057, - 1065, - 1075, - 1085, - 1093, - 1100, - 1108, - 1119, - 1129, - 1138, + 978, + 983, + 988, + 993, + 998, + 1004, + 1011, + 1020, + 1030, + 1034, + 1043, + 1048, + 1054, + 1061, + 1067, + 1074, + 1082, + 1092, + 1102, + 1110, + 1117, + 1125, + 1136, 1146, - 1152, - 1159, - 1165, - 1172, - 1181, - 1187, - 1193, - 1203, - 1207, - 1213, - 1221, - 1228, - 1236, - 1243, - 1248, + 1155, + 1163, + 1169, + 1176, + 1182, + 1189, + 1198, + 1204, + 1210, + 1220, + 1224, + 1230, + 1238, + 1245, 1253, - 1262, - 1272, - 1282, + 1260, + 1265, + 1270, + 1279, 1289, - 1295, - 1303, + 1299, + 1306, 1312, - 1318, - 1327, - 1334, - 1342, - 1349, - 1356, - 1361, - 1366, - 1375, - 1378, + 1320, + 1326, + 1338, + 1347, + 1353, + 1362, + 1369, + 1377, 1384, - 1394, - 1404, + 1391, + 1396, + 1401, + 1410, 1413, 1420, - 1423, - 1431, - 1441, - 1451, - 1458, - 1464, - 1472, - 1480, - 1489, - 1499, + 1426, + 1436, + 1446, + 1455, + 1462, + 1465, + 1473, + 1483, + 1493, + 1500, 1506, - 1512, - 1518, - 1524, - 1536, - 1543, - 1551, - 1555, - 1563, - 1573, - 1582, - 1587, - 1595, - 1598, + 1514, + 1522, + 1531, + 1541, + 1548, + 1554, + 1560, + 1566, + 1578, + 1585, + 1593, + 1597, 1605, 1615, - 1620, - 1625, - 1636, - 1650, + 1624, + 1629, + 1637, + 1640, + 1647, + 1657, 1662, - 1674, - 1689, - 1700, - 1712, - 1727, - 1738, - 1749, + 1667, + 1678, + 1692, + 1704, + 1716, + 1731, + 1742, 1754, - 1758, - 1763, 1769, - 1778, - 1784, - 1789, - 1797, + 1780, + 1791, + 1796, + 1800, 1805, - 1815, - 1821, + 1811, + 1820, 1826, - 1832, - 1837, - 1843, - 1850, - 1855, - 1861, - 1871, - 1886, - 1895, - 1900, - 1907, - 1914, - 1922, + 1831, + 1839, + 1847, + 1857, + 1863, + 1868, + 1874, + 1879, + 1885, + 1892, + 1897, + 1903, + 1913, 1928, - 1936, + 1937, + 1942, 1949, - 1958, - 1964, - 1977, - 1984, - 1991, - 2000, - 2005, - 2011, - 2016, - 2021, - 2027, - 2036, - 2044, - 2050, + 1956, + 1960, + 1968, + 1974, + 1982, + 1995, + 2004, + 2010, + 2023, + 2030, + 2037, + 2046, + 2051, 2057, - 2061, - 2066, - 2070, - 2074, - 2079, - 2084, - 2087, - 2092, - 2102, - 2113, - 2117, + 2062, + 2067, + 2073, + 2082, + 2090, + 2096, + 2103, + 2107, + 2112, + 2116, + 2120, 2125, - 2132, - 2140, - 2147, - 2152, - 2159, - 2165, - 2173, - 2180, - 2188, + 2130, + 2133, + 2138, + 2143, + 2153, + 2164, + 2168, + 2176, + 2183, 2191, - 2195, - 2202, - 2207, - 2211, + 2198, + 2203, + 2210, 2216, - 2219, 2224, - 2233, - 2240, - 2248, - 2251, - 2257, - 2268, + 2231, + 2239, + 2242, + 2246, + 2253, + 2258, + 2262, + 2267, + 2270, 2275, - 2279, - 2285, - 2290, + 2284, + 2291, 2299, - 2307, - 2318, - 2324, + 2302, + 2308, + 2319, + 2326, 2330, - 2339, - 2349, - 2356, - 2364, - 2374, - 2382, - 2391, - 2396, - 2403, - 2410, - 2418, - 2423, - 2429, + 2336, + 2341, + 2350, + 2358, + 2369, + 2375, + 2381, + 2390, + 2400, + 2407, + 2415, + 2425, 2436, - 2445, - 2455, + 2444, + 2453, + 2458, 2465, - 2473, - 2482, + 2472, + 2480, + 2485, 2491, - 2499, - 2505, - 2516, - 2527, - 2537, - 2548, - 2556, - 2568, - 2574, - 2581, - 2587, - 2592, + 2498, + 2506, + 2515, + 2525, + 2535, + 2543, + 2552, + 2561, + 2569, + 2575, + 2586, 2597, - 2606, - 2616, - 2620, - 2631, - 2643, - 2651, - 2659, - 2668, - 2676, - 2683, - 2694, - 2702, + 2607, + 2618, + 2626, + 2637, + 2646, + 2658, + 2664, + 2671, + 2677, + 2682, + 2687, + 2696, + 2706, 2710, - 2716, - 2724, + 2721, 2733, - 2740, - 2750, - 2758, - 2765, + 2741, + 2749, + 2762, 2771, - 2776, - 2785, - 2792, - 2800, - 2809, - 2813, - 2818, - 2823, - 2833, - 2840, - 2847, - 2855, - 2862, - 2869, + 2779, + 2786, + 2793, + 2804, + 2812, + 2820, + 2826, + 2834, + 2842, + 2851, + 2858, + 2868, 2876, - 2885, - 2892, - 2901, - 2911, - 2924, + 2883, + 2889, + 2894, + 2903, + 2910, + 2918, + 2927, 2931, - 2939, - 2952, - 2956, - 2962, - 2967, + 2936, + 2941, + 2951, + 2958, + 2965, 2973, - 2978, - 2986, - 2993, - 2998, - 3007, - 3016, - 3021, - 3028, - 3032, - 3039, - 3050, - 3056, - 3066, - 3077, - 3083, - 3090, - 3098, - 3105, - 3112, - 3119, + 2980, + 2987, + 2994, + 3003, + 3010, + 3019, + 3029, + 3042, + 3049, + 3057, + 3070, + 3074, + 3080, + 3085, + 3091, + 3096, + 3104, + 3111, + 3116, 3125, - 3138, - 3148, + 3134, + 3139, + 3146, + 3152, 3156, - 3166, - 3172, - 3179, - 3191, - 3197, - 3204, - 3216, - 3227, - 3234, - 3239, - 3248, - 3258, - 3263, - 3268, - 3273, - 3278, - 3288, - 3291, - 3300, - 3312, - 3322, + 3163, + 3174, + 3180, + 3190, + 3201, + 3207, + 3214, + 3222, + 3229, + 3236, + 3243, + 3249, + 3262, + 3272, + 3280, + 3290, + 3296, + 3303, + 3315, + 3321, 3328, - 3336, - 3341, - 3346, - 3355, + 3340, + 3351, + 3358, 3363, - 3368, - 3374, + 3372, 3382, + 3387, 3392, - 3404, - 3418, - 3430, + 3397, + 3402, + 3412, + 3415, + 3424, 3436, - 3443, - 3451, + 3446, + 3452, 3460, - 3469, - 3475, - 3482, + 3465, + 3470, + 3479, 3487, - 3493, - 3500, + 3492, + 3498, 3506, - 3515, - 3525, - 3531, - 3538, - 3546, - 3555, - 3563, - 3571, - 3579, + 3516, + 3528, + 3542, + 3554, + 3560, + 3567, + 3575, 3584, - 3590, - 3598, - 3607, - 3612, - 3618, - 3629, - 3636, - 3641, - 3648, - 3656, - 3661, - 3669, - 3675, + 3593, + 3599, + 3606, + 3611, + 3617, + 3624, + 3630, + 3639, + 3649, + 3655, + 3662, + 3670, 3679, - 3693, + 3687, + 3695, 3703, - 3714, - 3724, - 3734, + 3710, + 3715, + 3721, + 3729, + 3738, + 3743, 3748, - 3757, - 3763, - 3771, + 3754, + 3765, + 3772, + 3777, 3784, - 3793, - 3798, - 3802, + 3792, + 3797, + 3805, + 3811, + 3815, + 3829, + 3839, + 3850, + 3860, + 3870, + 3884, + 3893, + 3899, + 3907, + 3920, + 3929, + 3934, + 3938, }; -#define SCANKEYWORDS_NUM_KEYWORDS 495 +#define SCANKEYWORDS_NUM_KEYWORDS 512 static int ScanKeywords_hash_func(const void *key, size_t keylen) { - static const int16 h[991] = { - 32767, -121, 32767, -21, 32767, 32767, 32767, -435, - 391, 32767, 32767, 487, 377, 213, 32767, 32767, - 32767, 32767, 32767, 20, 32767, 32767, 1, -114, - 458, 375, 88, 535, 32767, 32767, 319, 387, - -180, 0, 0, 32767, -473, 163, 105, 0, - 32767, 32767, 32767, 21, 173, -212, 32767, 371, - 65, 125, 32767, 455, 32767, 370, -342, 830, - 32767, 176, 1114, -78, -161, 32767, 239, -903, - 32767, -653, 32767, -412, 149, 32767, 1137, 32767, - -618, 32767, 919, -333, 237, 20, 32767, 380, - 195, 32767, 152, 135, 264, 115, 95, 0, - 32767, 876, -342, 32767, 32767, 374, 956, 108, - -41, 0, -760, 32767, 32767, 0, 32767, 422, - 328, 32767, 32767, 32767, 60, -183, 32767, -630, - 32767, 266, -353, 503, 32767, -111, 32767, 32767, - 480, 171, -264, 32767, 193, 482, 73, 194, - 32767, 288, 32767, 176, 370, 32767, 32767, 0, - 234, 32767, 62, 229, 32767, 32767, 32767, 0, - 32767, 32767, 32767, 32767, 466, 32767, 56, 32767, - -77, 407, 395, 86, 0, 32767, 201, 562, - 0, -460, 0, 32767, 32767, 32767, 290, 32767, - 35, 32767, 1, 32767, 396, 70, 0, 97, - 434, 420, 272, 178, 32767, 32767, 29, 346, - 0, 382, 32767, 32767, 423, -1086, 32767, 378, - 32767, 429, 32767, -210, 0, 32767, 32767, 369, - -652, 328, 64, 418, 1112, 32767, 32767, 0, - 0, 216, 32767, 32767, -339, -659, 32767, 289, - 419, 47, 32767, 767, -622, 0, -293, 0, - 32767, 32767, -257, 0, 0, 32767, 0, 32767, - 32767, 441, 32767, 0, -279, 0, 38, -433, - 32767, 470, 32767, 0, 32767, 245, -162, 32767, - 32767, -238, 32767, 0, 32767, 32767, 77, 32767, - 32767, 103, 32767, 32767, 181, 342, 32767, 150, - 440, 12, 32767, 244, 32767, 0, -149, 835, - 32767, 390, 423, 189, 32767, 32767, 32767, 32767, - 32767, 0, 0, -138, 32767, 255, 32767, 282, - 32767, -740, -639, 48, -126, 32767, 32767, 32767, - 32767, 32767, 32767, 647, 46, 369, 32767, 0, - 32767, 32767, -206, 32767, 32767, -130, 32767, 96, - 32767, 0, -27, 32767, 356, 32767, 32767, -311, - 314, 13, -158, 32767, 32767, 0, 486, 52, - 32767, 437, -3, 308, -314, -94, 32767, 32767, - 32767, 32767, 0, 32767, 765, 270, 32767, 205, - 32767, 32767, 240, -328, -50, 70, 57, -99, - 95, 32767, 32767, 464, 32767, 32767, 32767, 203, - 445, 32767, 391, 32767, 141, -210, 172, -125, - 0, 32767, 130, 32767, -66, 32767, 32767, 0, - 393, 32767, 32767, 185, 0, 32767, 258, 40, - -799, 32767, 23, 32767, 87, 32767, 119, 32767, - 32767, -227, 138, 32767, 32767, 32767, 206, 344, - 1, 71, 32767, 0, 421, 32767, 32767, 32767, - -625, 32767, 32767, 38, 491, 32767, 32767, -984, - 198, 0, 455, -16, 56, 0, -717, 411, - 200, 0, 32767, 0, 32767, 188, 82, 32767, - 32767, 0, 32767, -80, 80, 32767, -675, 32767, - 378, 26, 0, 32767, 32767, 57, 0, 32767, - 633, 32767, 0, 32767, 307, 32767, 132, 32767, - 320, 220, 32767, 0, 264, 32767, 499, -7, - 139, 271, 32767, 357, 532, 168, 32767, 258, - 32767, 17, 219, -178, 299, 32767, 32767, -27, - 382, 32767, 32767, 32767, 32767, 32767, 637, 32767, - 32767, 329, -364, 32767, -16, 355, -197, 127, - 340, -434, 224, -3, -186, 0, 176, 156, - 32767, 32767, 105, 32767, 435, 34, 32767, 32767, - 568, -176, 0, -471, 333, 32767, 0, -218, - 32767, 254, 283, 0, 326, 32767, 32767, 32767, - 0, 32767, 32767, 99, -142, 0, 318, 303, - 360, 267, 32767, 344, 0, 32767, 32767, 32767, - 547, 32767, 32767, 334, 0, -59, 446, -366, - -253, 32767, -165, 32767, 32767, 32767, 427, -152, - 15, 32767, 32767, 0, 51, 32767, 98, 599, - 169, 31, 0, -116, 0, 0, 32767, -402, - 32767, 32767, 263, 32767, 32767, -205, -94, 0, - 280, 260, 32767, 32767, 1124, 32767, -543, 0, - 0, 32767, 32767, 32767, 32767, 32767, 773, 7, - 930, 288, -620, 32767, 132, 32767, 0, 0, - 58, 32767, 373, 848, 228, 112, -4, 32767, - 32767, -152, 651, 32767, 32767, 1013, -685, 240, - 242, -117, 38, 110, 32767, 0, 32767, -48, - 32767, -113, 32767, 0, 92, 1228, 0, 760, - 32767, 0, 32767, 0, 457, -144, 774, 198, - 32767, 32767, 32767, 351, 329, 292, 32767, 32767, - 118, 32767, 32767, 331, 80, 117, 815, 32767, - 0, 32767, 370, 32767, 32767, 0, 32767, -419, - 32767, 32767, 32767, 0, 32767, 32767, 32767, 193, - 0, 32767, 0, 32767, 32767, 32767, 870, 0, - 32767, -52, 454, 0, 32767, 64, 0, 310, - 0, -338, 32767, 119, 32767, 32767, -366, 32767, - 0, 159, 32767, 362, 66, 32767, 32767, 32767, - 0, -122, -39, 425, 361, 32767, -160, 420, - 163, 210, 32767, 32767, 32767, 32767, -642, 0, - -287, 0, 32767, 0, 401, 0, 221, 32767, - 238, 0, 525, 0, 91, 32767, 325, 32767, - 32767, -651, 129, 463, 0, 0, 32767, 172, - 287, 32767, 32767, -122, 0, 32767, 32767, 798, - 492, 109, -52, 0, 0, 6, 32767, 32767, - 32767, 474, 32767, 87, 32767, 32767, 31, 32767, - 451, 7, 252, 69, 32767, 6, -276, 97, - 32767, 32767, 32767, 32767, 32767, 141, 524, 32767, - 83, -304, 32767, 32767, 32767, 941, 32767, 32767, - 32767, 32767, 107, 32767, 32767, 32767, 32767, 32767, - 32767, 535, -733, 493, 32767, 554, -257, 18, - 173, -370, 191, 528, 406, 0, 468, 292, - 32767, -142, 417, 179, -27, 322, 32767, 504, - 32767, 433, 153, 182, 394, 32767, 32767, 32767, - 0, 32767, 177, 118, 32767, 32767, 83, 194, - 18, -781, 0, 322, 0, 19, 344, 32767, - 156, 118, 0, 32767, 372, 32767, 32767, 0, - 32767, -452, 366, 1133, -126, 834, 32767, 32767, - 32767, 1193, 162, 32767, 0, 0, -328, 360, - 353, -489, 0, 32767, 32767, 32767, 32767, 32767, - -237, 290, 32767, -780, 32767, -78, 32767, 0, - 137, 0, 94, 0, 344, 32767, 671, -164, - 422, 32767, 405, 32767, 57, 0, 141, 32767, - 32767, -16, 32767, 32767, -55, 46, 221, 32767, - 247, 32767, 0, 10, 32767, 401, 613, 32767, - 0, -244, 250, 32767, 223, 32767, 274, 32767, - 32767, 0, 124, 32767, 291, 303, -299, 234, - 38, 32767, 0, 32767, 181, 0, 536, 32767, - 23, -195, -192, 0, 1087, 32767, 60, 32767, - 177, 32767, 0, -646, 622, -36, 752, 46, - 0, 32767, 32767, 1067, 0, 32767, -187, 192, - 0, 32767, 32767, 425, 0, 32767, 879, 32767, - 32767, -129, 0, 32767, 190, 175, 254 + static const int16 h[1025] = { + 32767, 0, 32767, 32767, 105, 32767, 0, 247, + -377, 0, 32767, -225, 32767, 275, -381, 163, + 54, 232, 431, 32767, 32767, 471, 322, 449, + 32767, 0, 32767, 616, -46, 1217, 32767, 275, + 32767, 246, 32767, 405, -115, 402, -9, 32767, + 32767, 278, 78, 0, -279, 367, 32767, 218, + 32767, 32767, 32767, 32767, 203, 32767, 0, 800, + 32767, 32767, 144, 32767, -542, 131, 377, 21, + 0, 249, -528, 32767, 32767, 32767, 32767, -80, + 32767, 32767, 306, 32767, 128, 545, 122, 398, + 32767, 32767, 76, 32767, 424, 84, 32767, 536, + 48, -369, 32767, 32767, 0, 32767, -184, 32767, + 32767, 32767, -65, 205, 32767, 75, -260, 588, + 32767, 32767, 0, -234, 32767, 32767, 199, 32767, + -217, 32767, 32767, 192, 0, 170, 32767, 149, + 0, -35, 32767, 0, -63, 176, 216, 32767, + 170, 157, 0, 0, 282, 280, 183, 0, + -264, 32767, -252, -177, 111, -197, 84, -48, + 413, 18, -163, 0, 32767, 50, 32767, 32767, + 336, 32767, 32767, 369, 88, -176, 380, 32767, + 0, 494, 32767, 112, 32767, -303, 32767, 132, + -391, 115, 32767, 393, 32767, -173, 32767, 32767, + 537, 95, 0, 0, 680, 299, 323, -73, + 32767, 32767, -901, 32767, -275, 32767, 349, 383, + 32767, 318, -234, -34, 32767, 28, 444, 722, + 32767, -110, 82, 427, 0, 1057, -41, 0, + 386, 32767, 0, 32767, -224, 32767, 100, 197, + -555, 0, 243, 341, 384, -204, 32767, 32767, + 413, 580, 32767, 32767, 22, 32767, 239, -52, + 32767, 32767, 311, 32767, 1018, 32767, -587, 32767, + -261, 782, 32767, 32767, 47, 32767, 155, 32767, + 32767, 32767, 0, 273, -70, 32767, 124, 32767, + 445, -435, 32767, 725, 311, 32767, 889, 0, + 0, 0, 32767, 0, 186, 369, 32767, 529, + 32767, 32767, 257, -82, 347, 230, 376, 227, + -268, 0, 32767, 314, 131, 32767, 169, 32767, + 0, -93, -130, 252, 32767, 32767, 41, 389, + 32767, 0, 219, 307, 513, 1157, 454, 32767, + 32767, 146, 32767, 32767, 578, 242, 0, 32767, + 32767, 32767, 422, 472, 1347, 132, -362, 120, + 38, 226, -414, 32767, 81, 32767, 0, 57, + 0, 0, 32767, 32767, 32767, 988, 32767, 256, + 588, 32767, 32767, 597, 32767, 17, 148, 354, + -59, 32767, 228, 60, 319, 32767, 32767, -97, + 69, 32767, 32767, 0, 538, 32767, 32767, 32767, + 0, 32767, 32767, 32767, 0, 352, 291, 0, + 0, 0, 405, 32767, 235, 32767, 32767, 28, + 32767, 321, -96, -38, 32767, 32767, 0, 0, + 454, 32767, 200, 32767, -228, -158, 32767, 32767, + 452, 63, 32767, 208, 32767, -550, 0, 0, + 32767, 32767, 57, 32767, 31, -13, 249, 32767, + 62, 32767, 0, 32767, -307, -803, 238, 296, + 32767, 309, 0, 32767, 32767, 438, 32767, 179, + 111, 32767, 32767, 32767, 240, 32767, 206, 32767, + 183, -28, -140, 430, 0, -143, 32767, 32767, + 32767, 32767, 0, 443, 18, -162, 32767, 92, + 2, 395, 244, 30, 32767, 32767, -146, 32767, + 32767, -342, -216, 32767, -234, 432, 0, 11, + 32767, 32767, 357, 0, -498, 27, 400, -7, + -79, 32767, 32767, 32767, 109, 32767, 32767, 0, + -74, 32767, 32767, 32767, 374, 0, 32767, 32767, + 32767, 32767, -30, -390, 32767, 0, 349, 0, + 32767, 2, 32767, 236, 362, 397, 32767, 32767, + 577, 360, 32767, 214, 32767, -899, 32767, 32767, + 0, -239, -281, 32767, -480, 32767, 159, 102, + 32767, 32767, 32767, 907, 443, 143, 0, 32767, + 32767, 0, 185, 32767, -53, -78, 32767, 921, + 32767, 438, 424, -57, 468, 32767, 32767, 456, + 32767, 32767, -495, 77, 0, -453, 0, 38, + 0, 32767, 109, -328, 105, 32767, 20, 0, + 32767, 303, 32767, 32767, 32767, 0, 32767, 305, + 439, -345, -428, 32767, 743, 32767, 436, 52, + 360, 32767, 32767, 32767, 32767, 0, 261, -175, + 32767, 32767, 558, -113, 0, 485, 68, 0, + 32767, 0, 678, 32767, 386, 0, 408, -324, + 0, 32767, 323, 262, 423, 32767, 298, 32767, + 628, 163, 223, -447, -8, 0, 219, -240, + -5, 489, 418, 32767, 145, -337, 32767, 224, + 32767, 197, 32767, 32767, -93, 340, -49, 32767, + 32767, 32767, 32767, 450, 259, 32767, -186, 195, + 32767, 269, 740, 32767, 490, 32767, 32767, 165, + 0, 0, 47, 497, 684, -160, 32767, 199, + -40, 32767, 32767, 32767, 0, 299, 0, 0, + 92, 0, 154, 410, 32767, 0, 34, 0, + 32767, 32767, 305, -78, 32767, 32767, 5, 138, + 0, 0, 0, 0, -321, 0, 32767, 32767, + 32767, 102, 736, 176, -702, -368, 32767, 364, + 32767, 134, -184, 60, 147, 32767, 32767, 32767, + 32767, 0, 438, 39, 0, 245, 377, 281, + -392, 85, 32767, 32767, 426, 0, 32767, 0, + 26, -286, 32767, 32767, -307, 780, 218, 32767, + 32767, 32767, 31, -257, 32767, 8, 32767, 577, + 32767, 32767, 32767, 32767, 492, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 121, 32767, + 32767, 32767, 32767, 0, 186, 32767, 32767, 32767, + 32767, 358, 32767, 32767, 436, 32767, -360, 32767, + 103, 32767, 250, 539, 32767, 375, 32767, -164, + 49, 32767, 32767, 32767, 32767, 0, 32767, 15, + 0, 32767, 171, 311, -339, 0, 445, 0, + 204, 32767, 0, 32767, 486, 32767, 0, -381, + 32767, 32767, 0, 32767, 32767, 409, -150, -1, + 32767, 14, 364, 480, 0, 104, 303, 954, + 32767, 377, 32767, 476, 424, 188, 32767, 0, + 32767, 0, 32767, 300, 32767, 0, -331, 0, + 317, 398, 411, 570, 136, 191, 32767, 417, + 385, 253, 250, 131, 32767, 433, 32767, 711, + 0, 32767, 156, 32767, 32767, 432, 32767, -531, + 0, -52, 176, 32767, 405, 32767, 32767, 80, + 0, 300, 32767, 1, 122, 0, 96, 0, + -79, 32767, 284, 51, 372, 573, 271, 353, + 32767, 113, 32767, 0, 32767, 32767, 32767, 365, + 32767, 32767, 32767, 32767, 602, 0, 32767, 171, + 32767, 0, 32767, -77, 32767, 355, 0, 32767, + 156, 32767, 134, 0, 160, 32767, 337, 0, + 32767, 32767, 12, 323, 32767, 32767, 32767, 72, + 0, -81, 435, -313, 412, 32767, 0, 77, + 60, 0, 32767, 428, 248, 32767, 32767, 481, + 220, 0, 344, 32767, 0, 94, 32767, 231, + 129, 628, 253, 32767, -129, 0, 0, 32767, + 32767, 32767, 121, 32767, 0, 32767, 416, 2, + 389, 0, 561, 131, 220, 282, 191, 32767, + 32767, 32767, 32767, 0, 464, 769, 41, 457, + 32767, 32767, 32767, 32767, 175, 41, 4, 0, + 32767, 0, 113, 218, 32767, 203, 406, 32767, + -160, 32767, 0, 32767, 657, 0, 32767, 0, + 32767, 32767, -38, 32767, 146, 137, 265, -334, + 32767, 32767, 32767, 141, -63, 349, 171, 0, + -312, 32767, -125, 0, 207, 32767, 363, 0, + -80 }; const unsigned char *k = (const unsigned char *) key; uint32 a = 0; - uint32 b = 1; + uint32 b = 0; while (keylen--) { unsigned char c = *k++ | 0x20; a = a * 257 + c; - b = b * 127 + c; + b = b * 8191 + c; } - return h[a % 991] + h[b % 991]; + return h[a % 1025] + h[b % 1025]; } +extern PGDLLIMPORT const ScanKeywordList ScanKeywords; + const ScanKeywordList ScanKeywords = { ScanKeywords_kw_string, ScanKeywords_kw_offsets, diff --git a/src/include/parser/makefuncs.h b/src/include/parser/makefuncs.h index 0441c8e5d..f61e66b8f 100644 --- a/src/include/parser/makefuncs.h +++ b/src/include/parser/makefuncs.h @@ -4,8 +4,8 @@ * prototypes for the creator functions of various nodes * * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/makefuncs.h @@ -99,7 +99,7 @@ extern JsonValueExpr *makeJsonValueExpr(Expr *raw_expr, Expr *formatted_expr, extern Node *makeJsonKeyValue(Node *key, Node *value); extern Node *makeJsonIsPredicate(Node *expr, JsonFormat *format, JsonValueType item_type, bool unique_keys, - int location); + Oid exprBaseType, int location); extern JsonBehavior *makeJsonBehavior(JsonBehaviorType btype, Node *expr, int location); extern JsonTablePath *makeJsonTablePath(Const *pathvalue, char *pathname); diff --git a/src/include/parser/nodes.h b/src/include/parser/nodes.h index 5412ef4c8..f33c1c025 100644 --- a/src/include/parser/nodes.h +++ b/src/include/parser/nodes.h @@ -4,8 +4,8 @@ * Definitions for tagged nodes. * * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/nodes.h @@ -112,14 +112,12 @@ typedef enum NodeTag * - custom_query_jumble: Has custom implementation in queryjumblefuncs.c * for the field of a node. Also available as a node attribute. * - * - query_jumble_ignore: Ignore the field for the query jumbling. Note - * that typmod and collation information are usually irrelevant for the - * query jumbling. + * - query_jumble_ignore: Ignore the field for query jumbling. * * - query_jumble_squash: Squash multiple values during query jumbling. * * - query_jumble_location: Mark the field as a location to track. This is - * only allowed for integer fields that include "location" in their name. + * only used for fields of type ParseLoc, which otherwise are not jumbled. * * - read_as(VALUE): In nodeRead(), replace the field's value with VALUE. * @@ -195,6 +193,8 @@ castNodeImpl(NodeTag type, void *ptr) * ---------------------------------------------------------------- */ +#ifndef FRONTEND + /* * nodes/{outfuncs.c,print.c} */ @@ -205,7 +205,7 @@ extern void outNode(struct StringInfoData *str, const void *obj); extern void outToken(struct StringInfoData *str, const char *s); extern void outBitmapset(struct StringInfoData *str, const struct Bitmapset *bms); -extern void outDatum(struct StringInfoData *str, uintptr_t value, +extern void outDatum(struct StringInfoData *str, Datum value, int typlen, bool typbyval); extern char *nodeToString(const void *obj); extern char *nodeToStringWithLocations(const void *obj); @@ -219,7 +219,7 @@ extern void *stringToNode(const char *str); extern void *stringToNodeWithLocations(const char *str); #endif extern struct Bitmapset *readBitmapset(void); -extern uintptr_t readDatum(bool typbyval); +extern Datum readDatum(bool typbyval); extern bool *readBoolCols(int numCols); extern int *readIntCols(int numCols); extern Oid *readOidCols(int numCols); @@ -231,8 +231,8 @@ extern int16 *readAttrNumberCols(int numCols); extern void *copyObjectImpl(const void *from); /* cast result back to argument type, if supported by compiler */ -#ifdef HAVE_TYPEOF -#define copyObject(obj) ((typeof(obj)) copyObjectImpl(obj)) +#ifdef HAVE_TYPEOF_UNQUAL +#define copyObject(obj) ((typeof_unqual(*(obj)) *) copyObjectImpl(obj)) #else #define copyObject(obj) copyObjectImpl(obj) #endif @@ -242,6 +242,8 @@ extern void *copyObjectImpl(const void *from); */ extern bool equal(const void *a, const void *b); +#endif /* !FRONTEND */ + /* * Typedef for parse location. This is just an int, but this way @@ -326,8 +328,8 @@ typedef enum JoinType * These codes are used internally in the planner, but are not supported * by the executor (nor, indeed, by most of the planner). */ - JOIN_UNIQUE_OUTER, /* LHS path must be made unique */ - JOIN_UNIQUE_INNER, /* RHS path must be made unique */ + JOIN_UNIQUE_OUTER, /* LHS has be made unique */ + JOIN_UNIQUE_INNER, /* RHS has be made unique */ /* * We might need additional join types someday. @@ -431,6 +433,7 @@ typedef enum OnConflictAction ONCONFLICT_NONE, /* No "ON CONFLICT" clause */ ONCONFLICT_NOTHING, /* ON CONFLICT ... DO NOTHING */ ONCONFLICT_UPDATE, /* ON CONFLICT ... DO UPDATE */ + ONCONFLICT_SELECT, /* ON CONFLICT ... DO SELECT */ } OnConflictAction; /* diff --git a/src/include/parser/nodetags.h b/src/include/parser/nodetags.h index 312727639..3a9e06f6b 100644 --- a/src/include/parser/nodetags.h +++ b/src/include/parser/nodetags.h @@ -15,482 +15,505 @@ * *------------------------------------------------------------------------- */ - T_List = 1, - T_Alias = 2, - T_RangeVar = 3, - T_TableFunc = 4, - T_IntoClause = 5, - T_Var = 6, - T_Const = 7, - T_Param = 8, - T_Aggref = 9, - T_GroupingFunc = 10, - T_WindowFunc = 11, - T_WindowFuncRunCondition = 12, - T_MergeSupportFunc = 13, - T_SubscriptingRef = 14, - T_FuncExpr = 15, - T_NamedArgExpr = 16, - T_OpExpr = 17, - T_DistinctExpr = 18, - T_NullIfExpr = 19, - T_ScalarArrayOpExpr = 20, - T_BoolExpr = 21, - T_SubLink = 22, - T_SubPlan = 23, - T_AlternativeSubPlan = 24, - T_FieldSelect = 25, - T_FieldStore = 26, - T_RelabelType = 27, - T_CoerceViaIO = 28, - T_ArrayCoerceExpr = 29, - T_ConvertRowtypeExpr = 30, - T_CollateExpr = 31, - T_CaseExpr = 32, - T_CaseWhen = 33, - T_CaseTestExpr = 34, - T_ArrayExpr = 35, - T_RowExpr = 36, - T_RowCompareExpr = 37, - T_CoalesceExpr = 38, - T_MinMaxExpr = 39, - T_SQLValueFunction = 40, - T_XmlExpr = 41, - T_JsonFormat = 42, - T_JsonReturning = 43, - T_JsonValueExpr = 44, - T_JsonConstructorExpr = 45, - T_JsonIsPredicate = 46, - T_JsonBehavior = 47, - T_JsonExpr = 48, - T_JsonTablePath = 49, - T_JsonTablePathScan = 50, - T_JsonTableSiblingJoin = 51, - T_NullTest = 52, - T_BooleanTest = 53, - T_MergeAction = 54, - T_CoerceToDomain = 55, - T_CoerceToDomainValue = 56, - T_SetToDefault = 57, - T_CurrentOfExpr = 58, - T_NextValueExpr = 59, - T_InferenceElem = 60, - T_ReturningExpr = 61, - T_TargetEntry = 62, - T_RangeTblRef = 63, - T_JoinExpr = 64, - T_FromExpr = 65, - T_OnConflictExpr = 66, - T_Query = 67, - T_TypeName = 68, - T_ColumnRef = 69, - T_ParamRef = 70, - T_A_Expr = 71, - T_A_Const = 72, - T_TypeCast = 73, - T_CollateClause = 74, - T_RoleSpec = 75, - T_FuncCall = 76, - T_A_Star = 77, - T_A_Indices = 78, - T_A_Indirection = 79, - T_A_ArrayExpr = 80, - T_ResTarget = 81, - T_MultiAssignRef = 82, - T_SortBy = 83, - T_WindowDef = 84, - T_RangeSubselect = 85, - T_RangeFunction = 86, - T_RangeTableFunc = 87, - T_RangeTableFuncCol = 88, - T_RangeTableSample = 89, - T_ColumnDef = 90, - T_TableLikeClause = 91, - T_IndexElem = 92, - T_DefElem = 93, - T_LockingClause = 94, - T_XmlSerialize = 95, - T_PartitionElem = 96, - T_PartitionSpec = 97, - T_PartitionBoundSpec = 98, - T_PartitionRangeDatum = 99, - T_PartitionCmd = 100, - T_RangeTblEntry = 101, - T_RTEPermissionInfo = 102, - T_RangeTblFunction = 103, - T_TableSampleClause = 104, - T_WithCheckOption = 105, - T_SortGroupClause = 106, - T_GroupingSet = 107, - T_WindowClause = 108, - T_RowMarkClause = 109, - T_WithClause = 110, - T_InferClause = 111, - T_OnConflictClause = 112, - T_CTESearchClause = 113, - T_CTECycleClause = 114, - T_CommonTableExpr = 115, - T_MergeWhenClause = 116, - T_ReturningOption = 117, - T_ReturningClause = 118, - T_TriggerTransition = 119, - T_JsonOutput = 120, - T_JsonArgument = 121, - T_JsonFuncExpr = 122, - T_JsonTablePathSpec = 123, - T_JsonTable = 124, - T_JsonTableColumn = 125, - T_JsonKeyValue = 126, - T_JsonParseExpr = 127, - T_JsonScalarExpr = 128, - T_JsonSerializeExpr = 129, - T_JsonObjectConstructor = 130, - T_JsonArrayConstructor = 131, - T_JsonArrayQueryConstructor = 132, - T_JsonAggConstructor = 133, - T_JsonObjectAgg = 134, - T_JsonArrayAgg = 135, - T_RawStmt = 136, - T_InsertStmt = 137, - T_DeleteStmt = 138, - T_UpdateStmt = 139, - T_MergeStmt = 140, - T_SelectStmt = 141, - T_SetOperationStmt = 142, - T_ReturnStmt = 143, - T_PLAssignStmt = 144, - T_CreateSchemaStmt = 145, - T_AlterTableStmt = 146, - T_AlterTableCmd = 147, - T_ATAlterConstraint = 148, - T_ReplicaIdentityStmt = 149, - T_AlterCollationStmt = 150, - T_AlterDomainStmt = 151, - T_GrantStmt = 152, - T_ObjectWithArgs = 153, - T_AccessPriv = 154, - T_GrantRoleStmt = 155, - T_AlterDefaultPrivilegesStmt = 156, - T_CopyStmt = 157, - T_VariableSetStmt = 158, - T_VariableShowStmt = 159, - T_CreateStmt = 160, - T_Constraint = 161, - T_CreateTableSpaceStmt = 162, - T_DropTableSpaceStmt = 163, - T_AlterTableSpaceOptionsStmt = 164, - T_AlterTableMoveAllStmt = 165, - T_CreateExtensionStmt = 166, - T_AlterExtensionStmt = 167, - T_AlterExtensionContentsStmt = 168, - T_CreateFdwStmt = 169, - T_AlterFdwStmt = 170, - T_CreateForeignServerStmt = 171, - T_AlterForeignServerStmt = 172, - T_CreateForeignTableStmt = 173, - T_CreateUserMappingStmt = 174, - T_AlterUserMappingStmt = 175, - T_DropUserMappingStmt = 176, - T_ImportForeignSchemaStmt = 177, - T_CreatePolicyStmt = 178, - T_AlterPolicyStmt = 179, - T_CreateAmStmt = 180, - T_CreateTrigStmt = 181, - T_CreateEventTrigStmt = 182, - T_AlterEventTrigStmt = 183, - T_CreatePLangStmt = 184, - T_CreateRoleStmt = 185, - T_AlterRoleStmt = 186, - T_AlterRoleSetStmt = 187, - T_DropRoleStmt = 188, - T_CreateSeqStmt = 189, - T_AlterSeqStmt = 190, - T_DefineStmt = 191, - T_CreateDomainStmt = 192, - T_CreateOpClassStmt = 193, - T_CreateOpClassItem = 194, - T_CreateOpFamilyStmt = 195, - T_AlterOpFamilyStmt = 196, - T_DropStmt = 197, - T_TruncateStmt = 198, - T_CommentStmt = 199, - T_SecLabelStmt = 200, - T_DeclareCursorStmt = 201, - T_ClosePortalStmt = 202, - T_FetchStmt = 203, - T_IndexStmt = 204, - T_CreateStatsStmt = 205, - T_StatsElem = 206, - T_AlterStatsStmt = 207, - T_CreateFunctionStmt = 208, - T_FunctionParameter = 209, - T_AlterFunctionStmt = 210, - T_DoStmt = 211, - T_InlineCodeBlock = 212, - T_CallStmt = 213, - T_CallContext = 214, - T_RenameStmt = 215, - T_AlterObjectDependsStmt = 216, - T_AlterObjectSchemaStmt = 217, - T_AlterOwnerStmt = 218, - T_AlterOperatorStmt = 219, - T_AlterTypeStmt = 220, - T_RuleStmt = 221, - T_NotifyStmt = 222, - T_ListenStmt = 223, - T_UnlistenStmt = 224, - T_TransactionStmt = 225, - T_CompositeTypeStmt = 226, - T_CreateEnumStmt = 227, - T_CreateRangeStmt = 228, - T_AlterEnumStmt = 229, - T_ViewStmt = 230, - T_LoadStmt = 231, - T_CreatedbStmt = 232, - T_AlterDatabaseStmt = 233, - T_AlterDatabaseRefreshCollStmt = 234, - T_AlterDatabaseSetStmt = 235, - T_DropdbStmt = 236, - T_AlterSystemStmt = 237, - T_ClusterStmt = 238, - T_VacuumStmt = 239, - T_VacuumRelation = 240, - T_ExplainStmt = 241, - T_CreateTableAsStmt = 242, - T_RefreshMatViewStmt = 243, - T_CheckPointStmt = 244, - T_DiscardStmt = 245, - T_LockStmt = 246, - T_ConstraintsSetStmt = 247, - T_ReindexStmt = 248, - T_CreateConversionStmt = 249, - T_CreateCastStmt = 250, - T_CreateTransformStmt = 251, - T_PrepareStmt = 252, - T_ExecuteStmt = 253, - T_DeallocateStmt = 254, - T_DropOwnedStmt = 255, - T_ReassignOwnedStmt = 256, - T_AlterTSDictionaryStmt = 257, - T_AlterTSConfigurationStmt = 258, - T_PublicationTable = 259, - T_PublicationObjSpec = 260, - T_CreatePublicationStmt = 261, - T_AlterPublicationStmt = 262, - T_CreateSubscriptionStmt = 263, - T_AlterSubscriptionStmt = 264, - T_DropSubscriptionStmt = 265, - T_PlannerGlobal = 266, - T_PlannerInfo = 267, - T_RelOptInfo = 268, - T_IndexOptInfo = 269, - T_ForeignKeyOptInfo = 270, - T_StatisticExtInfo = 271, - T_JoinDomain = 272, - T_EquivalenceClass = 273, - T_EquivalenceMember = 274, - T_PathKey = 275, - T_GroupByOrdering = 276, - T_PathTarget = 277, - T_ParamPathInfo = 278, - T_Path = 279, - T_IndexPath = 280, - T_IndexClause = 281, - T_BitmapHeapPath = 282, - T_BitmapAndPath = 283, - T_BitmapOrPath = 284, - T_TidPath = 285, - T_TidRangePath = 286, - T_SubqueryScanPath = 287, - T_ForeignPath = 288, - T_CustomPath = 289, - T_AppendPath = 290, - T_MergeAppendPath = 291, - T_GroupResultPath = 292, - T_MaterialPath = 293, - T_MemoizePath = 294, - T_UniquePath = 295, - T_GatherPath = 296, - T_GatherMergePath = 297, - T_NestPath = 298, - T_MergePath = 299, - T_HashPath = 300, - T_ProjectionPath = 301, - T_ProjectSetPath = 302, - T_SortPath = 303, - T_IncrementalSortPath = 304, - T_GroupPath = 305, - T_UpperUniquePath = 306, - T_AggPath = 307, - T_GroupingSetData = 308, - T_RollupData = 309, - T_GroupingSetsPath = 310, - T_MinMaxAggPath = 311, - T_WindowAggPath = 312, - T_SetOpPath = 313, - T_RecursiveUnionPath = 314, - T_LockRowsPath = 315, - T_ModifyTablePath = 316, - T_LimitPath = 317, - T_RestrictInfo = 318, - T_PlaceHolderVar = 319, - T_SpecialJoinInfo = 320, - T_OuterJoinClauseInfo = 321, - T_AppendRelInfo = 322, - T_RowIdentityVarInfo = 323, - T_PlaceHolderInfo = 324, - T_MinMaxAggInfo = 325, - T_PlannerParamItem = 326, - T_AggInfo = 327, - T_AggTransInfo = 328, - T_UniqueRelInfo = 329, - T_PlannedStmt = 330, - T_Result = 331, - T_ProjectSet = 332, - T_ModifyTable = 333, - T_Append = 334, - T_MergeAppend = 335, - T_RecursiveUnion = 336, - T_BitmapAnd = 337, - T_BitmapOr = 338, - T_SeqScan = 339, - T_SampleScan = 340, - T_IndexScan = 341, - T_IndexOnlyScan = 342, - T_BitmapIndexScan = 343, - T_BitmapHeapScan = 344, - T_TidScan = 345, - T_TidRangeScan = 346, - T_SubqueryScan = 347, - T_FunctionScan = 348, - T_ValuesScan = 349, - T_TableFuncScan = 350, - T_CteScan = 351, - T_NamedTuplestoreScan = 352, - T_WorkTableScan = 353, - T_ForeignScan = 354, - T_CustomScan = 355, - T_NestLoop = 356, - T_NestLoopParam = 357, - T_MergeJoin = 358, - T_HashJoin = 359, - T_Material = 360, - T_Memoize = 361, - T_Sort = 362, - T_IncrementalSort = 363, - T_Group = 364, - T_Agg = 365, - T_WindowAgg = 366, - T_Unique = 367, - T_Gather = 368, - T_GatherMerge = 369, - T_Hash = 370, - T_SetOp = 371, - T_LockRows = 372, - T_Limit = 373, - T_PlanRowMark = 374, - T_PartitionPruneInfo = 375, - T_PartitionedRelPruneInfo = 376, - T_PartitionPruneStepOp = 377, - T_PartitionPruneStepCombine = 378, - T_PlanInvalItem = 379, - T_ExprState = 380, - T_IndexInfo = 381, - T_ExprContext = 382, - T_ReturnSetInfo = 383, - T_ProjectionInfo = 384, - T_JunkFilter = 385, - T_OnConflictSetState = 386, - T_MergeActionState = 387, - T_ResultRelInfo = 388, - T_EState = 389, - T_WindowFuncExprState = 390, - T_SetExprState = 391, - T_SubPlanState = 392, - T_DomainConstraintState = 393, - T_ResultState = 394, - T_ProjectSetState = 395, - T_ModifyTableState = 396, - T_AppendState = 397, - T_MergeAppendState = 398, - T_RecursiveUnionState = 399, - T_BitmapAndState = 400, - T_BitmapOrState = 401, - T_ScanState = 402, - T_SeqScanState = 403, - T_SampleScanState = 404, - T_IndexScanState = 405, - T_IndexOnlyScanState = 406, - T_BitmapIndexScanState = 407, - T_BitmapHeapScanState = 408, - T_TidScanState = 409, - T_TidRangeScanState = 410, - T_SubqueryScanState = 411, - T_FunctionScanState = 412, - T_ValuesScanState = 413, - T_TableFuncScanState = 414, - T_CteScanState = 415, - T_NamedTuplestoreScanState = 416, - T_WorkTableScanState = 417, - T_ForeignScanState = 418, - T_CustomScanState = 419, - T_JoinState = 420, - T_NestLoopState = 421, - T_MergeJoinState = 422, - T_HashJoinState = 423, - T_MaterialState = 424, - T_MemoizeState = 425, - T_SortState = 426, - T_IncrementalSortState = 427, - T_GroupState = 428, - T_AggState = 429, - T_WindowAggState = 430, - T_UniqueState = 431, - T_GatherState = 432, - T_GatherMergeState = 433, - T_HashState = 434, - T_SetOpState = 435, - T_LockRowsState = 436, - T_LimitState = 437, - T_IndexAmRoutine = 438, - T_TableAmRoutine = 439, - T_TsmRoutine = 440, - T_EventTriggerData = 441, - T_TriggerData = 442, - T_TupleTableSlot = 443, - T_FdwRoutine = 444, - T_Bitmapset = 445, - T_ExtensibleNode = 446, - T_ErrorSaveContext = 447, - T_IdentifySystemCmd = 448, - T_BaseBackupCmd = 449, - T_CreateReplicationSlotCmd = 450, - T_DropReplicationSlotCmd = 451, - T_AlterReplicationSlotCmd = 452, - T_StartReplicationCmd = 453, - T_ReadReplicationSlotCmd = 454, - T_TimeLineHistoryCmd = 455, - T_UploadManifestCmd = 456, - T_SupportRequestSimplify = 457, - T_SupportRequestSelectivity = 458, - T_SupportRequestCost = 459, - T_SupportRequestRows = 460, - T_SupportRequestIndexCondition = 461, - T_SupportRequestWFuncMonotonic = 462, - T_SupportRequestOptimizeWindowClause = 463, - T_SupportRequestModifyInPlace = 464, - T_Integer = 465, - T_Float = 466, - T_Boolean = 467, - T_String = 468, - T_BitString = 469, - T_ForeignKeyCacheInfo = 470, - T_IntList = 471, - T_OidList = 472, - T_XidList = 473, - T_AllocSetContext = 474, - T_GenerationContext = 475, - T_SlabContext = 476, - T_BumpContext = 477, - T_TIDBitmap = 478, - T_WindowObjectData = 479, + T_List = 1, + T_Alias = 2, + T_RangeVar = 3, + T_TableFunc = 4, + T_IntoClause = 5, + T_Var = 6, + T_Const = 7, + T_Param = 8, + T_Aggref = 9, + T_GroupingFunc = 10, + T_WindowFunc = 11, + T_WindowFuncRunCondition = 12, + T_MergeSupportFunc = 13, + T_SubscriptingRef = 14, + T_FuncExpr = 15, + T_NamedArgExpr = 16, + T_OpExpr = 17, + T_DistinctExpr = 18, + T_NullIfExpr = 19, + T_ScalarArrayOpExpr = 20, + T_BoolExpr = 21, + T_SubLink = 22, + T_SubPlan = 23, + T_AlternativeSubPlan = 24, + T_FieldSelect = 25, + T_FieldStore = 26, + T_RelabelType = 27, + T_CoerceViaIO = 28, + T_ArrayCoerceExpr = 29, + T_ConvertRowtypeExpr = 30, + T_CollateExpr = 31, + T_CaseExpr = 32, + T_CaseWhen = 33, + T_CaseTestExpr = 34, + T_ArrayExpr = 35, + T_RowExpr = 36, + T_RowCompareExpr = 37, + T_CoalesceExpr = 38, + T_MinMaxExpr = 39, + T_SQLValueFunction = 40, + T_XmlExpr = 41, + T_JsonFormat = 42, + T_JsonReturning = 43, + T_JsonValueExpr = 44, + T_JsonConstructorExpr = 45, + T_JsonIsPredicate = 46, + T_JsonBehavior = 47, + T_JsonExpr = 48, + T_JsonTablePath = 49, + T_JsonTablePathScan = 50, + T_JsonTableSiblingJoin = 51, + T_NullTest = 52, + T_BooleanTest = 53, + T_MergeAction = 54, + T_CoerceToDomain = 55, + T_CoerceToDomainValue = 56, + T_SetToDefault = 57, + T_CurrentOfExpr = 58, + T_NextValueExpr = 59, + T_InferenceElem = 60, + T_ReturningExpr = 61, + T_GraphLabelRef = 62, + T_GraphPropertyRef = 63, + T_TargetEntry = 64, + T_RangeTblRef = 65, + T_JoinExpr = 66, + T_FromExpr = 67, + T_OnConflictExpr = 68, + T_ForPortionOfExpr = 69, + T_Query = 70, + T_TypeName = 71, + T_ColumnRef = 72, + T_ParamRef = 73, + T_A_Expr = 74, + T_A_Const = 75, + T_TypeCast = 76, + T_CollateClause = 77, + T_RoleSpec = 78, + T_FuncCall = 79, + T_A_Star = 80, + T_A_Indices = 81, + T_A_Indirection = 82, + T_A_ArrayExpr = 83, + T_ResTarget = 84, + T_MultiAssignRef = 85, + T_SortBy = 86, + T_WindowDef = 87, + T_RangeSubselect = 88, + T_RangeFunction = 89, + T_RangeTableFunc = 90, + T_RangeTableFuncCol = 91, + T_RangeGraphTable = 92, + T_RangeTableSample = 93, + T_ColumnDef = 94, + T_TableLikeClause = 95, + T_IndexElem = 96, + T_DefElem = 97, + T_LockingClause = 98, + T_XmlSerialize = 99, + T_PartitionElem = 100, + T_PartitionSpec = 101, + T_PartitionBoundSpec = 102, + T_PartitionRangeDatum = 103, + T_SinglePartitionSpec = 104, + T_PartitionCmd = 105, + T_GraphPattern = 106, + T_GraphElementPattern = 107, + T_RangeTblEntry = 108, + T_RTEPermissionInfo = 109, + T_RangeTblFunction = 110, + T_TableSampleClause = 111, + T_WithCheckOption = 112, + T_SortGroupClause = 113, + T_GroupingSet = 114, + T_WindowClause = 115, + T_RowMarkClause = 116, + T_ForPortionOfClause = 117, + T_WithClause = 118, + T_InferClause = 119, + T_OnConflictClause = 120, + T_CTESearchClause = 121, + T_CTECycleClause = 122, + T_CommonTableExpr = 123, + T_MergeWhenClause = 124, + T_ReturningOption = 125, + T_ReturningClause = 126, + T_TriggerTransition = 127, + T_JsonOutput = 128, + T_JsonArgument = 129, + T_JsonFuncExpr = 130, + T_JsonTablePathSpec = 131, + T_JsonTable = 132, + T_JsonTableColumn = 133, + T_JsonKeyValue = 134, + T_JsonParseExpr = 135, + T_JsonScalarExpr = 136, + T_JsonSerializeExpr = 137, + T_JsonObjectConstructor = 138, + T_JsonArrayConstructor = 139, + T_JsonArrayQueryConstructor = 140, + T_JsonAggConstructor = 141, + T_JsonObjectAgg = 142, + T_JsonArrayAgg = 143, + T_RawStmt = 144, + T_InsertStmt = 145, + T_DeleteStmt = 146, + T_UpdateStmt = 147, + T_MergeStmt = 148, + T_SelectStmt = 149, + T_SetOperationStmt = 150, + T_ReturnStmt = 151, + T_PLAssignStmt = 152, + T_CreateSchemaStmt = 153, + T_AlterTableStmt = 154, + T_AlterTableCmd = 155, + T_ATAlterConstraint = 156, + T_ReplicaIdentityStmt = 157, + T_AlterCollationStmt = 158, + T_AlterDomainStmt = 159, + T_GrantStmt = 160, + T_ObjectWithArgs = 161, + T_AccessPriv = 162, + T_GrantRoleStmt = 163, + T_AlterDefaultPrivilegesStmt = 164, + T_CopyStmt = 165, + T_VariableSetStmt = 166, + T_VariableShowStmt = 167, + T_CreateStmt = 168, + T_Constraint = 169, + T_CreateTableSpaceStmt = 170, + T_DropTableSpaceStmt = 171, + T_AlterTableSpaceOptionsStmt = 172, + T_AlterTableMoveAllStmt = 173, + T_CreateExtensionStmt = 174, + T_AlterExtensionStmt = 175, + T_AlterExtensionContentsStmt = 176, + T_CreateFdwStmt = 177, + T_AlterFdwStmt = 178, + T_CreateForeignServerStmt = 179, + T_AlterForeignServerStmt = 180, + T_CreateForeignTableStmt = 181, + T_CreateUserMappingStmt = 182, + T_AlterUserMappingStmt = 183, + T_DropUserMappingStmt = 184, + T_ImportForeignSchemaStmt = 185, + T_CreatePolicyStmt = 186, + T_AlterPolicyStmt = 187, + T_CreateAmStmt = 188, + T_CreateTrigStmt = 189, + T_CreateEventTrigStmt = 190, + T_AlterEventTrigStmt = 191, + T_CreatePLangStmt = 192, + T_CreateRoleStmt = 193, + T_AlterRoleStmt = 194, + T_AlterRoleSetStmt = 195, + T_DropRoleStmt = 196, + T_CreateSeqStmt = 197, + T_AlterSeqStmt = 198, + T_DefineStmt = 199, + T_CreateDomainStmt = 200, + T_CreateOpClassStmt = 201, + T_CreateOpClassItem = 202, + T_CreateOpFamilyStmt = 203, + T_AlterOpFamilyStmt = 204, + T_DropStmt = 205, + T_TruncateStmt = 206, + T_CommentStmt = 207, + T_SecLabelStmt = 208, + T_DeclareCursorStmt = 209, + T_ClosePortalStmt = 210, + T_FetchStmt = 211, + T_IndexStmt = 212, + T_CreateStatsStmt = 213, + T_StatsElem = 214, + T_AlterStatsStmt = 215, + T_CreateFunctionStmt = 216, + T_FunctionParameter = 217, + T_AlterFunctionStmt = 218, + T_DoStmt = 219, + T_InlineCodeBlock = 220, + T_CallStmt = 221, + T_CallContext = 222, + T_RenameStmt = 223, + T_AlterObjectDependsStmt = 224, + T_AlterObjectSchemaStmt = 225, + T_AlterOwnerStmt = 226, + T_AlterOperatorStmt = 227, + T_AlterTypeStmt = 228, + T_RuleStmt = 229, + T_NotifyStmt = 230, + T_ListenStmt = 231, + T_UnlistenStmt = 232, + T_TransactionStmt = 233, + T_CompositeTypeStmt = 234, + T_CreateEnumStmt = 235, + T_CreateRangeStmt = 236, + T_AlterEnumStmt = 237, + T_ViewStmt = 238, + T_LoadStmt = 239, + T_CreatedbStmt = 240, + T_AlterDatabaseStmt = 241, + T_AlterDatabaseRefreshCollStmt = 242, + T_AlterDatabaseSetStmt = 243, + T_DropdbStmt = 244, + T_AlterSystemStmt = 245, + T_VacuumStmt = 246, + T_VacuumRelation = 247, + T_RepackStmt = 248, + T_ExplainStmt = 249, + T_CreateTableAsStmt = 250, + T_RefreshMatViewStmt = 251, + T_CheckPointStmt = 252, + T_DiscardStmt = 253, + T_LockStmt = 254, + T_ConstraintsSetStmt = 255, + T_ReindexStmt = 256, + T_CreateConversionStmt = 257, + T_CreateCastStmt = 258, + T_CreatePropGraphStmt = 259, + T_PropGraphVertex = 260, + T_PropGraphEdge = 261, + T_PropGraphLabelAndProperties = 262, + T_PropGraphProperties = 263, + T_AlterPropGraphStmt = 264, + T_CreateTransformStmt = 265, + T_PrepareStmt = 266, + T_ExecuteStmt = 267, + T_DeallocateStmt = 268, + T_DropOwnedStmt = 269, + T_ReassignOwnedStmt = 270, + T_AlterTSDictionaryStmt = 271, + T_AlterTSConfigurationStmt = 272, + T_PublicationTable = 273, + T_PublicationObjSpec = 274, + T_PublicationAllObjSpec = 275, + T_CreatePublicationStmt = 276, + T_AlterPublicationStmt = 277, + T_CreateSubscriptionStmt = 278, + T_AlterSubscriptionStmt = 279, + T_DropSubscriptionStmt = 280, + T_WaitStmt = 281, + T_PlannerGlobal = 282, + T_PlannerInfo = 283, + T_RelOptInfo = 284, + T_RelAggInfo = 285, + T_IndexOptInfo = 286, + T_ForeignKeyOptInfo = 287, + T_StatisticExtInfo = 288, + T_JoinDomain = 289, + T_EquivalenceClass = 290, + T_EquivalenceMember = 291, + T_PathKey = 292, + T_GroupByOrdering = 293, + T_PathTarget = 294, + T_ParamPathInfo = 295, + T_Path = 296, + T_IndexPath = 297, + T_IndexClause = 298, + T_BitmapHeapPath = 299, + T_BitmapAndPath = 300, + T_BitmapOrPath = 301, + T_TidPath = 302, + T_TidRangePath = 303, + T_SubqueryScanPath = 304, + T_ForeignPath = 305, + T_CustomPath = 306, + T_AppendPath = 307, + T_MergeAppendPath = 308, + T_GroupResultPath = 309, + T_MaterialPath = 310, + T_MemoizePath = 311, + T_GatherPath = 312, + T_GatherMergePath = 313, + T_NestPath = 314, + T_MergePath = 315, + T_HashPath = 316, + T_ProjectionPath = 317, + T_ProjectSetPath = 318, + T_SortPath = 319, + T_IncrementalSortPath = 320, + T_GroupPath = 321, + T_UniquePath = 322, + T_AggPath = 323, + T_GroupingSetData = 324, + T_RollupData = 325, + T_GroupingSetsPath = 326, + T_MinMaxAggPath = 327, + T_WindowAggPath = 328, + T_SetOpPath = 329, + T_RecursiveUnionPath = 330, + T_LockRowsPath = 331, + T_ModifyTablePath = 332, + T_LimitPath = 333, + T_RestrictInfo = 334, + T_PlaceHolderVar = 335, + T_SpecialJoinInfo = 336, + T_OuterJoinClauseInfo = 337, + T_AppendRelInfo = 338, + T_RowIdentityVarInfo = 339, + T_PlaceHolderInfo = 340, + T_MinMaxAggInfo = 341, + T_AggClauseInfo = 342, + T_GroupingExprInfo = 343, + T_PlannerParamItem = 344, + T_AggInfo = 345, + T_AggTransInfo = 346, + T_UniqueRelInfo = 347, + T_PlannedStmt = 348, + T_Result = 349, + T_ProjectSet = 350, + T_ModifyTable = 351, + T_Append = 352, + T_MergeAppend = 353, + T_RecursiveUnion = 354, + T_BitmapAnd = 355, + T_BitmapOr = 356, + T_SeqScan = 357, + T_SampleScan = 358, + T_IndexScan = 359, + T_IndexOnlyScan = 360, + T_BitmapIndexScan = 361, + T_BitmapHeapScan = 362, + T_TidScan = 363, + T_TidRangeScan = 364, + T_SubqueryScan = 365, + T_FunctionScan = 366, + T_ValuesScan = 367, + T_TableFuncScan = 368, + T_CteScan = 369, + T_NamedTuplestoreScan = 370, + T_WorkTableScan = 371, + T_ForeignScan = 372, + T_CustomScan = 373, + T_NestLoop = 374, + T_NestLoopParam = 375, + T_MergeJoin = 376, + T_HashJoin = 377, + T_Material = 378, + T_Memoize = 379, + T_Sort = 380, + T_IncrementalSort = 381, + T_Group = 382, + T_Agg = 383, + T_WindowAgg = 384, + T_Unique = 385, + T_Gather = 386, + T_GatherMerge = 387, + T_Hash = 388, + T_SetOp = 389, + T_LockRows = 390, + T_Limit = 391, + T_PlanRowMark = 392, + T_PartitionPruneInfo = 393, + T_PartitionedRelPruneInfo = 394, + T_PartitionPruneStepOp = 395, + T_PartitionPruneStepCombine = 396, + T_PlanInvalItem = 397, + T_SubPlanRTInfo = 398, + T_ElidedNode = 399, + T_ExprState = 400, + T_IndexInfo = 401, + T_ExprContext = 402, + T_ReturnSetInfo = 403, + T_ProjectionInfo = 404, + T_JunkFilter = 405, + T_OnConflictActionState = 406, + T_MergeActionState = 407, + T_ForPortionOfState = 408, + T_ResultRelInfo = 409, + T_EState = 410, + T_WindowFuncExprState = 411, + T_SetExprState = 412, + T_SubPlanState = 413, + T_DomainConstraintState = 414, + T_ResultState = 415, + T_ProjectSetState = 416, + T_ModifyTableState = 417, + T_AppendState = 418, + T_MergeAppendState = 419, + T_RecursiveUnionState = 420, + T_BitmapAndState = 421, + T_BitmapOrState = 422, + T_ScanState = 423, + T_SeqScanState = 424, + T_SampleScanState = 425, + T_IndexScanState = 426, + T_IndexOnlyScanState = 427, + T_BitmapIndexScanState = 428, + T_BitmapHeapScanState = 429, + T_TidScanState = 430, + T_TidRangeScanState = 431, + T_SubqueryScanState = 432, + T_FunctionScanState = 433, + T_ValuesScanState = 434, + T_TableFuncScanState = 435, + T_CteScanState = 436, + T_NamedTuplestoreScanState = 437, + T_WorkTableScanState = 438, + T_ForeignScanState = 439, + T_CustomScanState = 440, + T_JoinState = 441, + T_NestLoopState = 442, + T_MergeJoinState = 443, + T_HashJoinState = 444, + T_MaterialState = 445, + T_MemoizeState = 446, + T_SortState = 447, + T_IncrementalSortState = 448, + T_GroupState = 449, + T_AggState = 450, + T_WindowAggState = 451, + T_UniqueState = 452, + T_GatherState = 453, + T_GatherMergeState = 454, + T_HashState = 455, + T_SetOpState = 456, + T_LockRowsState = 457, + T_LimitState = 458, + T_IndexAmRoutine = 459, + T_TableAmRoutine = 460, + T_TsmRoutine = 461, + T_EventTriggerData = 462, + T_TriggerData = 463, + T_TupleTableSlot = 464, + T_FdwRoutine = 465, + T_Bitmapset = 466, + T_ExtensibleNode = 467, + T_ErrorSaveContext = 468, + T_IdentifySystemCmd = 469, + T_BaseBackupCmd = 470, + T_CreateReplicationSlotCmd = 471, + T_DropReplicationSlotCmd = 472, + T_AlterReplicationSlotCmd = 473, + T_StartReplicationCmd = 474, + T_ReadReplicationSlotCmd = 475, + T_TimeLineHistoryCmd = 476, + T_UploadManifestCmd = 477, + T_SupportRequestSimplify = 478, + T_SupportRequestSimplifyAggref = 479, + T_SupportRequestInlineInFrom = 480, + T_SupportRequestSelectivity = 481, + T_SupportRequestCost = 482, + T_SupportRequestRows = 483, + T_SupportRequestIndexCondition = 484, + T_SupportRequestWFuncMonotonic = 485, + T_SupportRequestOptimizeWindowClause = 486, + T_SupportRequestModifyInPlace = 487, + T_Integer = 488, + T_Float = 489, + T_Boolean = 490, + T_String = 491, + T_BitString = 492, + T_ForeignKeyCacheInfo = 493, + T_IntList = 494, + T_OidList = 495, + T_XidList = 496, + T_AllocSetContext = 497, + T_GenerationContext = 498, + T_SlabContext = 499, + T_BumpContext = 500, + T_TIDBitmap = 501, + T_WindowObjectData = 502, \ No newline at end of file diff --git a/src/include/parser/parsenodes.h b/src/include/parser/parsenodes.h index 7608230b9..c0953fbb1 100644 --- a/src/include/parser/parsenodes.h +++ b/src/include/parser/parsenodes.h @@ -12,8 +12,8 @@ * identifying statement boundaries in multi-statement source strings. * * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/parsenodes.h @@ -114,10 +114,13 @@ typedef Oid RelFileNumber; * Planning converts a Query tree into a Plan tree headed by a PlannedStmt * node --- the Query structure is not used by the executor. * - * All the fields ignored for the query jumbling are not semantically - * significant (such as alias names), as is ignored anything that can - * be deduced from child nodes (else we'd just be double-hashing that - * piece of information). + * We ignore fields for query jumbling if they are not semantically + * significant (such as alias names). We also ignore anything that can + * be deduced from other fields or child nodes, else we'd just be + * double-hashing that piece of information. In some places query jumbling + * deliberately ignores fields that are semantically significant, such as + * Const values, because we have made a policy decision to combine queries + * that differ only in those respects. */ typedef struct Query { @@ -130,8 +133,8 @@ typedef struct Query /* * query identifier (can be set by plugins); ignored for equal, as it - * might not be set; also not stored. This is the result of the query - * jumble, hence ignored. + * might not be set; also not stored. This is the output of query + * jumbling, hence it must be ignored as an input. * * We store this as a signed value as this is the form it's displayed to * users in places such as EXPLAIN and pg_stat_statements. Primarily this @@ -147,11 +150,13 @@ typedef struct Query /* * rtable index of target relation for INSERT/UPDATE/DELETE/MERGE; 0 for - * SELECT. This is ignored in the query jumble as unrelated to the - * compilation of the query ID. + * SELECT. */ int resultRelation pg_node_attr(query_jumble_ignore); + /* FOR PORTION OF clause for UPDATE/DELETE */ + ForPortionOfExpr *forPortionOf; + /* has aggregates in tlist or havingQual */ bool hasAggs pg_node_attr(query_jumble_ignore); /* has window functions in tlist */ @@ -205,7 +210,7 @@ typedef struct Query /* OVERRIDING clause */ OverridingKind override pg_node_attr(query_jumble_ignore); - OnConflictExpr *onConflict; /* ON CONFLICT DO [NOTHING | UPDATE] */ + OnConflictExpr *onConflict; /* ON CONFLICT DO NOTHING/SELECT/UPDATE */ /* * The following three fields describe the contents of the RETURNING list @@ -219,7 +224,7 @@ typedef struct Query List *returningList; /* return-values list (of TargetEntry) */ List *groupClause; /* a list of SortGroupClause's */ - bool groupDistinct; /* is the group by clause distinct? */ + bool groupDistinct; /* was GROUP BY DISTINCT used? */ List *groupingSets; /* a list of GroupingSet's if present */ @@ -457,6 +462,7 @@ typedef struct FuncCall List *agg_order; /* ORDER BY (list of SortBy) */ Node *agg_filter; /* FILTER clause, if any */ struct WindowDef *over; /* OVER clause, if any */ + int ignore_nulls; /* ignore nulls for window function */ bool agg_within_group; /* ORDER BY appeared in WITHIN GROUP */ bool agg_star; /* argument was really '*' */ bool agg_distinct; /* arguments were labeled DISTINCT */ @@ -713,6 +719,19 @@ typedef struct RangeTableFuncCol ParseLoc location; /* token location, or -1 if unknown */ } RangeTableFuncCol; +/* + * RangeGraphTable - raw form of GRAPH_TABLE clause + */ +typedef struct RangeGraphTable +{ + NodeTag type; + RangeVar *graph_name; + struct GraphPattern *graph_pattern; + List *columns; + Alias *alias; /* table alias & optional column aliases */ + ParseLoc location; /* token location, or -1 if unknown */ +} RangeGraphTable; + /* * RangeTableSample - TABLESAMPLE appearing in a raw FROM clause * @@ -783,7 +802,7 @@ typedef struct TableLikeClause { NodeTag type; RangeVar *relation; - bits32 options; /* OR of TableLikeOption flags */ + uint32 options; /* OR of TableLikeOption flags */ Oid relationOid; /* If table has been looked up, its OID */ } TableLikeClause; @@ -819,6 +838,7 @@ typedef struct IndexElem List *opclassopts; /* opclass-specific options, or NIL */ SortByDir ordering; /* ASC/DESC/default */ SortByNulls nulls_ordering; /* FIRST/LAST/default */ + ParseLoc location; /* token location, or -1 if unknown */ } IndexElem; /* @@ -969,16 +989,78 @@ typedef struct PartitionRangeDatum } PartitionRangeDatum; /* - * PartitionCmd - info for ALTER TABLE/INDEX ATTACH/DETACH PARTITION commands + * PartitionDesc - info about a single partition for the ALTER TABLE SPLIT + * PARTITION command */ -typedef struct PartitionCmd +typedef struct SinglePartitionSpec { NodeTag type; - RangeVar *name; /* name of partition to attach/detach */ + + RangeVar *name; /* name of partition */ PartitionBoundSpec *bound; /* FOR VALUES, if attaching */ +} SinglePartitionSpec; + +/* + * PartitionCmd - info for ALTER TABLE/INDEX ATTACH/DETACH PARTITION and for + * ALTER TABLE SPLIT/MERGE PARTITION(S) commands + */ +typedef struct PartitionCmd +{ + NodeTag type; + + /* name of partition to attach/detach/merge/split */ + RangeVar *name; + + /* FOR VALUES, if attaching */ + PartitionBoundSpec *bound; + + /* + * list of partitions to be split/merged, used in ALTER TABLE MERGE + * PARTITIONS and ALTER TABLE SPLIT PARTITIONS. For merge partitions, + * partlist is a list of RangeVar; For split partition, it is a list of + * SinglePartitionSpec. + */ + List *partlist; + bool concurrent; } PartitionCmd; +/* + * Nodes for graph pattern + */ + +typedef struct GraphPattern +{ + NodeTag type; + List *path_pattern_list; + Node *whereClause; +} GraphPattern; + +typedef enum GraphElementPatternKind +{ + VERTEX_PATTERN, + EDGE_PATTERN_LEFT, + EDGE_PATTERN_RIGHT, + EDGE_PATTERN_ANY, + PAREN_EXPR, +} GraphElementPatternKind; + +#define IS_EDGE_PATTERN(kind) ((kind) == EDGE_PATTERN_ANY || \ + (kind) == EDGE_PATTERN_RIGHT || \ + (kind) == EDGE_PATTERN_LEFT) + +typedef struct GraphElementPattern +{ + NodeTag type; + GraphElementPatternKind kind; + const char *variable; + Node *labelexpr; + List *subexpr; + Node *whereClause; + List *quantifier; + ParseLoc location; +} GraphElementPattern; + /**************************************************************************** * Nodes for a Query tree ****************************************************************************/ @@ -1051,6 +1133,7 @@ typedef enum RTEKind RTE_VALUES, /* VALUES (), (), ... */ RTE_CTE, /* common table expr (WITH list element) */ RTE_NAMEDTUPLESTORE, /* tuplestore, e.g. for AFTER triggers */ + RTE_GRAPH_TABLE, /* GRAPH_TABLE clause */ RTE_RESULT, /* RTE represents an empty FROM clause; such * RTEs are added by the planner, they're not * present during parsing or rewriting */ @@ -1194,7 +1277,7 @@ typedef struct RangeTblEntry /* * join_using_alias is an alias clause attached directly to JOIN/USING. It - * is different from the alias field (below) in that it does not hide the + * is different from the alias field (above) in that it does not hide the * range variables of the tables being joined. */ Alias *join_using_alias pg_node_attr(query_jumble_ignore); @@ -1217,6 +1300,12 @@ typedef struct RangeTblEntry */ TableFunc *tablefunc; + /* + * Fields valid for a graph table RTE (else NULL): + */ + GraphPattern *graph_pattern; + List *graph_table_columns; + /* * Fields valid for a values RTE (else NIL): */ @@ -1270,7 +1359,7 @@ typedef struct RangeTblEntry * Fields valid for a GROUP RTE (else NIL): */ /* list of grouping expressions */ - List *groupexprs pg_node_attr(query_jumble_ignore); + List *groupexprs; /* * Fields valid in all RTEs: @@ -1344,8 +1433,6 @@ typedef struct RTEPermissionInfo * time. We do however remember how many columns we thought the type had * (including dropped columns!), so that we can successfully ignore any * columns added after the query was parsed. - * - * The query jumbling only needs to track the function expression. */ typedef struct RangeTblFunction { @@ -1393,7 +1480,8 @@ typedef enum WCOKind WCO_VIEW_CHECK, /* WCO on an auto-updatable view */ WCO_RLS_INSERT_CHECK, /* RLS INSERT WITH CHECK policy */ WCO_RLS_UPDATE_CHECK, /* RLS UPDATE WITH CHECK policy */ - WCO_RLS_CONFLICT_CHECK, /* RLS ON CONFLICT DO UPDATE USING policy */ + WCO_RLS_CONFLICT_CHECK, /* RLS ON CONFLICT DO SELECT/UPDATE USING + * policy */ WCO_RLS_MERGE_UPDATE_CHECK, /* RLS MERGE UPDATE USING policy */ WCO_RLS_MERGE_DELETE_CHECK, /* RLS MERGE DELETE USING policy */ } WCOKind; @@ -1563,9 +1651,6 @@ typedef struct GroupingSet * When refname isn't null, the partitionClause is always copied from there; * the orderClause might or might not be copied (see copiedOrder); the framing * options are never copied, per spec. - * - * The information relevant for the query jumbling is the partition clause - * type and its bounds. */ typedef struct WindowClause { @@ -1616,6 +1701,22 @@ typedef struct RowMarkClause bool pushedDown; /* pushed down from higher query level? */ } RowMarkClause; +/* + * ForPortionOfClause + * representation of FOR PORTION OF FROM TO + * or FOR PORTION OF () + */ +typedef struct ForPortionOfClause +{ + NodeTag type; + char *range_name; /* column name of the range/multirange */ + ParseLoc location; /* token location, or -1 if unknown */ + ParseLoc target_location; /* token location, or -1 if unknown */ + Node *target; /* Expr from FOR PORTION OF col (...) syntax */ + Node *target_start; /* Expr from FROM ... TO ... syntax */ + Node *target_end; /* Expr from FROM ... TO ... syntax */ +} ForPortionOfClause; + /* * WithClause - * representation of WITH clause @@ -1655,9 +1756,10 @@ typedef struct InferClause typedef struct OnConflictClause { NodeTag type; - OnConflictAction action; /* DO NOTHING or UPDATE? */ + OnConflictAction action; /* DO NOTHING, SELECT, or UPDATE */ InferClause *infer; /* Optional index inference clause */ - List *targetList; /* the target list (of ResTarget) */ + LockClauseStrength lockStrength; /* lock strength for DO SELECT */ + List *targetList; /* target list (of ResTarget) for DO UPDATE */ Node *whereClause; /* qualifications */ ParseLoc location; /* token location, or -1 if unknown */ } OnConflictClause; @@ -1722,7 +1824,7 @@ typedef struct CommonTableExpr /* * Number of RTEs referencing this CTE (excluding internal - * self-references), irrelevant for query jumbling. + * self-references). */ int cterefcount pg_node_attr(query_jumble_ignore); /* list of output column names */ @@ -2129,6 +2231,7 @@ typedef struct DeleteStmt Node *whereClause; /* qualifications */ ReturningClause *returningClause; /* RETURNING clause */ WithClause *withClause; /* WITH clause */ + ForPortionOfClause *forPortionOf; /* FOR PORTION OF clause */ } DeleteStmt; /* ---------------------- @@ -2144,6 +2247,7 @@ typedef struct UpdateStmt List *fromClause; /* optional from clause for more tables */ ReturningClause *returningClause; /* RETURNING clause */ WithClause *withClause; /* WITH clause */ + ForPortionOfClause *forPortionOf; /* FOR PORTION OF clause */ } UpdateStmt; /* ---------------------- @@ -2260,7 +2364,7 @@ typedef struct SetOperationStmt Node *rarg; /* right child */ /* Eventually add fields for CORRESPONDING spec here */ - /* Fields derived during parse analysis (irrelevant for query jumbling): */ + /* Fields derived during parse analysis: */ /* OID list of output column type OIDs */ List *colTypes pg_node_attr(query_jumble_ignore); /* integer list of output column typmods */ @@ -2354,6 +2458,7 @@ typedef enum ObjectType OBJECT_PARAMETER_ACL, OBJECT_POLICY, OBJECT_PROCEDURE, + OBJECT_PROPGRAPH, OBJECT_PUBLICATION, OBJECT_PUBLICATION_NAMESPACE, OBJECT_PUBLICATION_REL, @@ -2478,6 +2583,8 @@ typedef enum AlterTableType AT_AttachPartition, /* ATTACH PARTITION */ AT_DetachPartition, /* DETACH PARTITION */ AT_DetachPartitionFinalize, /* DETACH PARTITION FINALIZE */ + AT_SplitPartition, /* SPLIT PARTITION */ + AT_MergePartitions, /* MERGE PARTITIONS */ AT_AddIdentity, /* ADD IDENTITY */ AT_SetIdentity, /* SET identity column options */ AT_DropIdentity, /* DROP IDENTITY */ @@ -2541,17 +2648,20 @@ typedef struct AlterCollationStmt * this command. * ---------------------- */ +typedef enum AlterDomainType +{ + AD_AlterDefault = 'T', /* SET|DROP DEFAULT */ + AD_DropNotNull = 'N', /* DROP NOT NULL */ + AD_SetNotNull = 'O', /* SET NOT NULL */ + AD_AddConstraint = 'C', /* ADD CONSTRAINT */ + AD_DropConstraint = 'X', /* DROP CONSTRAINT */ + AD_ValidateConstraint = 'V', /* VALIDATE CONSTRAINT */ +} AlterDomainType; + typedef struct AlterDomainStmt { NodeTag type; - char subtype; /*------------ - * T = alter column default - * N = alter column drop not null - * O = alter column set not null - * C = add constraint - * X = drop constraint - *------------ - */ + AlterDomainType subtype; /* subtype of command */ List *typeName; /* domain to work on */ char *name; /* column or constraint name to act on */ Node *def; /* definition of default or constraint */ @@ -2583,7 +2693,7 @@ typedef struct GrantStmt /* privileges == NIL denotes ALL PRIVILEGES */ List *grantees; /* list of RoleSpec nodes */ bool grant_option; /* grant or revoke grant option */ - RoleSpec *grantor; + RoleSpec *grantor; /* GRANTED BY clause, or NULL if none */ DropBehavior behavior; /* drop behavior (for REVOKE) */ } GrantStmt; @@ -2633,7 +2743,7 @@ typedef struct AccessPriv * Note: because of the parsing ambiguity with the GRANT * statement, granted_roles is a list of AccessPriv; the execution code * should complain if any column lists appear. grantee_roles is a list - * of role names, as String values. + * of role names, as RoleSpec values. * ---------------------- */ typedef struct GrantRoleStmt @@ -3427,15 +3537,44 @@ typedef enum FetchDirection FETCH_RELATIVE, } FetchDirection; +typedef enum FetchDirectionKeywords +{ + FETCH_KEYWORD_NONE = 0, + FETCH_KEYWORD_NEXT, + FETCH_KEYWORD_PRIOR, + FETCH_KEYWORD_FIRST, + FETCH_KEYWORD_LAST, + FETCH_KEYWORD_ABSOLUTE, + FETCH_KEYWORD_RELATIVE, + FETCH_KEYWORD_ALL, + FETCH_KEYWORD_FORWARD, + FETCH_KEYWORD_FORWARD_ALL, + FETCH_KEYWORD_BACKWARD, + FETCH_KEYWORD_BACKWARD_ALL, +} FetchDirectionKeywords; + #define FETCH_ALL LONG_MAX typedef struct FetchStmt { NodeTag type; FetchDirection direction; /* see above */ - long howMany; /* number of rows, or position argument */ - char *portalname; /* name of portal (cursor) */ - bool ismove; /* true if MOVE */ + /* number of rows, or position argument */ + long howMany pg_node_attr(query_jumble_ignore); + /* name of portal (cursor) */ + char *portalname; + /* true if MOVE */ + bool ismove; + + /* + * Set when a direction_keyword (e.g., FETCH FORWARD) is used, to + * distinguish it from a numeric variant (e.g., FETCH 1) for the purpose + * of query jumbling. + */ + FetchDirectionKeywords direction_keyword; + + /* token location, or -1 if unknown */ + ParseLoc location pg_node_attr(query_jumble_location); } FetchStmt; /* ---------------------- @@ -3601,8 +3740,6 @@ typedef struct InlineCodeBlock * list contains copies of the expressions for all output arguments, in the * order of the procedure's declared arguments. (outargs is never evaluated, * but is useful to the caller as a reference for what to assign to.) - * The transformed call state is not relevant in the query jumbling, only the - * function call is. * ---------------------- */ typedef struct CallStmt @@ -3921,18 +4058,6 @@ typedef struct AlterSystemStmt VariableSetStmt *setstmt; /* SET subcommand */ } AlterSystemStmt; -/* ---------------------- - * Cluster Statement (support pbrown's cluster index implementation) - * ---------------------- - */ -typedef struct ClusterStmt -{ - NodeTag type; - RangeVar *relation; /* relation being indexed, or NULL if all */ - char *indexname; /* original index defined */ - List *params; /* list of DefElem nodes */ -} ClusterStmt; - /* ---------------------- * Vacuum and Analyze Statements * @@ -3957,7 +4082,7 @@ typedef struct VacuumStmt NodeTag type; List *options; /* list of DefElem nodes */ List *rels; /* list of VacuumRelation, or NIL for all */ - bool is_vacuumcmd; /* true for VACUUM, false for ANALYZE */ + bool is_vacuumcmd; /* true for VACUUM, false otherwise */ } VacuumStmt; /* @@ -4013,6 +4138,27 @@ typedef struct VacuumRelation List *va_cols; /* list of column names, or NIL for all */ } VacuumRelation; +/* ---------------------- + * Repack Statement + * ---------------------- + */ +typedef enum RepackCommand +{ + REPACK_COMMAND_CLUSTER = 1, + REPACK_COMMAND_REPACK, + REPACK_COMMAND_VACUUMFULL, +} RepackCommand; + +typedef struct RepackStmt +{ + NodeTag type; + RepackCommand command; /* type of command being run */ + VacuumRelation *relation; /* relation being repacked */ + char *indexname; /* order tuples by this index */ + bool usingindex; /* whether USING INDEX is specified */ + List *params; /* list of DefElem nodes */ +} RepackStmt; + /* ---------------------- * Explain Statement * @@ -4070,6 +4216,7 @@ typedef struct RefreshMatViewStmt typedef struct CheckPointStmt { NodeTag type; + List *options; /* list of DefElem nodes */ } CheckPointStmt; /* ---------------------- @@ -4165,6 +4312,88 @@ typedef struct CreateCastStmt bool inout; } CreateCastStmt; +/* ---------------------- + * CREATE PROPERTY GRAPH Statement + * ---------------------- + */ +typedef struct CreatePropGraphStmt +{ + NodeTag type; + RangeVar *pgname; + List *vertex_tables; + List *edge_tables; +} CreatePropGraphStmt; + +typedef struct PropGraphVertex +{ + NodeTag type; + RangeVar *vtable; + List *vkey; + List *labels; + ParseLoc location; +} PropGraphVertex; + +typedef struct PropGraphEdge +{ + NodeTag type; + RangeVar *etable; + List *ekey; + List *esrckey; + char *esrcvertex; + List *esrcvertexcols; + List *edestkey; + char *edestvertex; + List *edestvertexcols; + List *labels; + ParseLoc location; +} PropGraphEdge; + +typedef struct PropGraphLabelAndProperties +{ + NodeTag type; + const char *label; + struct PropGraphProperties *properties; + ParseLoc location; +} PropGraphLabelAndProperties; + +typedef struct PropGraphProperties +{ + NodeTag type; + List *properties; + bool all; + ParseLoc location; +} PropGraphProperties; + +/* ---------------------- + * ALTER PROPERTY GRAPH Statement + * ---------------------- + */ + +typedef enum AlterPropGraphElementKind +{ + PROPGRAPH_ELEMENT_KIND_VERTEX = 1, + PROPGRAPH_ELEMENT_KIND_EDGE = 2, +} AlterPropGraphElementKind; + +typedef struct AlterPropGraphStmt +{ + NodeTag type; + RangeVar *pgname; + bool missing_ok; + List *add_vertex_tables; + List *add_edge_tables; + List *drop_vertex_tables; + List *drop_edge_tables; + DropBehavior drop_behavior; + AlterPropGraphElementKind element_kind; + const char *element_alias; + List *add_labels; + const char *drop_label; + const char *alter_label; + PropGraphProperties *add_properties; + List *drop_properties; +} AlterPropGraphStmt; + /* ---------------------- * CREATE TRANSFORM Statement * ---------------------- @@ -4287,9 +4516,10 @@ typedef struct AlterTSConfigurationStmt typedef struct PublicationTable { NodeTag type; - RangeVar *relation; /* relation to be published */ + RangeVar *relation; /* publication relation */ Node *whereClause; /* qualifications */ List *columns; /* List of columns in a publication table */ + bool except; /* True if listed in the EXCEPT clause */ } PublicationTable; /* @@ -4298,6 +4528,7 @@ typedef struct PublicationTable typedef enum PublicationObjSpecType { PUBLICATIONOBJ_TABLE, /* A table */ + PUBLICATIONOBJ_EXCEPT_TABLE, /* A table in the EXCEPT clause */ PUBLICATIONOBJ_TABLES_IN_SCHEMA, /* All tables in schema */ PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA, /* All tables in first element of * search_path */ @@ -4313,6 +4544,23 @@ typedef struct PublicationObjSpec ParseLoc location; /* token location, or -1 if unknown */ } PublicationObjSpec; +/* + * Types of objects supported by FOR ALL publications + */ +typedef enum PublicationAllObjType +{ + PUBLICATION_ALL_TABLES, + PUBLICATION_ALL_SEQUENCES, +} PublicationAllObjType; + +typedef struct PublicationAllObjSpec +{ + NodeTag type; + PublicationAllObjType pubobjtype; /* type of this publication object */ + List *except_tables; /* tables specified in the EXCEPT clause */ + ParseLoc location; /* token location, or -1 if unknown */ +} PublicationAllObjSpec; + typedef struct CreatePublicationStmt { NodeTag type; @@ -4320,6 +4568,8 @@ typedef struct CreatePublicationStmt List *options; /* List of DefElem nodes */ List *pubobjects; /* Optional list of publication objects */ bool for_all_tables; /* Special publication for all tables in db */ + bool for_all_sequences; /* Special publication for all sequences + * in db */ } CreatePublicationStmt; typedef enum AlterPublicationAction @@ -4342,15 +4592,17 @@ typedef struct AlterPublicationStmt * objects. */ List *pubobjects; /* Optional list of publication objects */ - bool for_all_tables; /* Special publication for all tables in db */ AlterPublicationAction action; /* What action to perform with the given * objects */ + bool for_all_tables; /* True if ALL TABLES is specified */ + bool for_all_sequences; /* True if ALL SEQUENCES is specified */ } AlterPublicationStmt; typedef struct CreateSubscriptionStmt { NodeTag type; char *subname; /* Name of the subscription */ + char *servername; /* Server name of publisher */ char *conninfo; /* Connection string to publisher */ List *publication; /* One or more publication to subscribe to */ List *options; /* List of DefElem nodes */ @@ -4359,11 +4611,13 @@ typedef struct CreateSubscriptionStmt typedef enum AlterSubscriptionType { ALTER_SUBSCRIPTION_OPTIONS, + ALTER_SUBSCRIPTION_SERVER, ALTER_SUBSCRIPTION_CONNECTION, ALTER_SUBSCRIPTION_SET_PUBLICATION, ALTER_SUBSCRIPTION_ADD_PUBLICATION, ALTER_SUBSCRIPTION_DROP_PUBLICATION, - ALTER_SUBSCRIPTION_REFRESH, + ALTER_SUBSCRIPTION_REFRESH_PUBLICATION, + ALTER_SUBSCRIPTION_REFRESH_SEQUENCES, ALTER_SUBSCRIPTION_ENABLED, ALTER_SUBSCRIPTION_SKIP, } AlterSubscriptionType; @@ -4373,6 +4627,7 @@ typedef struct AlterSubscriptionStmt NodeTag type; AlterSubscriptionType kind; /* ALTER_SUBSCRIPTION_OPTIONS, etc */ char *subname; /* Name of the subscription */ + char *servername; /* Server name of publisher */ char *conninfo; /* Connection string to publisher */ List *publication; /* One or more publication to subscribe to */ List *options; /* List of DefElem nodes */ @@ -4386,4 +4641,12 @@ typedef struct DropSubscriptionStmt DropBehavior behavior; /* RESTRICT or CASCADE behavior */ } DropSubscriptionStmt; +typedef struct WaitStmt +{ + NodeTag type; + char *lsn_literal; /* LSN string from grammar */ + List *options; /* List of DefElem nodes */ +} WaitStmt; + + #endif /* PARSENODES_H */ diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h index 70a08f145..2e6299c4b 100644 --- a/src/include/parser/parser.h +++ b/src/include/parser/parser.h @@ -5,8 +5,8 @@ * * This is the external API for the raw lexing/parsing functions. * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parser.h @@ -53,10 +53,8 @@ typedef enum BACKSLASH_QUOTE_SAFE_ENCODING, } BackslashQuoteType; -/* GUC variables in scan.l (every one of these is a bad idea :-() */ +/* GUC variable in scan.l */ extern PGDLLIMPORT int backslash_quote; -extern PGDLLIMPORT bool escape_string_warning; -extern PGDLLIMPORT bool standard_conforming_strings; /* Primary entry point for the raw parsing functions */ extern List *raw_parser(const char *str, RawParseMode mode, int len, bool *error, bool use_minimal); diff --git a/src/include/parser/pg_class.h b/src/include/parser/pg_class.h index 82438dede..9e2ce9a3a 100644 --- a/src/include/parser/pg_class.h +++ b/src/include/parser/pg_class.h @@ -4,8 +4,8 @@ * definition of the "relation" system catalog (pg_class) * * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_class.h @@ -24,6 +24,8 @@ #include "catalog/genbki.h" #include "catalog/pg_class_d.h" /* IWYU pragma: export */ +BEGIN_CATALOG_STRUCT + CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,RelationRelation_Rowtype_Id) BKI_SCHEMA_MACRO { /* oid */ @@ -139,6 +141,8 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat #endif } FormData_pg_class; +END_CATALOG_STRUCT + /* Size of fixed part of pg_class tuples, not counting var-length fields */ #define CLASS_TUPLE_SIZE \ (offsetof(FormData_pg_class,relminmxid) + sizeof(TransactionId)) @@ -168,6 +172,7 @@ MAKE_SYSCACHE(RELNAMENSP, pg_class_relname_nsp_index, 128); #define RELKIND_FOREIGN_TABLE 'f' /* foreign table */ #define RELKIND_PARTITIONED_TABLE 'p' /* partitioned table */ #define RELKIND_PARTITIONED_INDEX 'I' /* partitioned index */ +#define RELKIND_PROPGRAPH 'g' /* property graph */ #endif /* NOT_USED_IN_PGPOOL */ diff --git a/src/include/parser/pg_config_manual.h b/src/include/parser/pg_config_manual.h index cbea7dc1d..a8c2adcf3 100644 --- a/src/include/parser/pg_config_manual.h +++ b/src/include/parser/pg_config_manual.h @@ -6,8 +6,8 @@ * for developers. If you edit any of these, be sure to do a *full* * rebuild (and an initdb if noted). * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/pg_config_manual.h @@ -37,6 +37,16 @@ */ #define DEFAULT_XLOG_SEG_SIZE (16*1024*1024) +/* + * SLRU segment size. A page is the same BLCKSZ as is used everywhere else in + * Postgres. The segment size can be chosen somewhat arbitrarily; we make it + * 32 pages by default, or 256Kb, i.e. 1M transactions for CLOG or 64K + * transactions for SUBTRANS. + * + * Changing this requires an initdb. + */ +#define SLRU_PAGES_PER_SEGMENT 32 + /* * Maximum length for identifiers (e.g. table names, column names, * function names). Names actually are limited to one fewer byte than this, @@ -92,17 +102,12 @@ #define PARTITION_MAX_KEYS 32 /* - * Decide whether built-in 8-byte types, including float8, int8, and - * timestamp, are passed by value. This is on by default if sizeof(Datum) >= - * 8 (that is, on 64-bit platforms). If sizeof(Datum) < 8 (32-bit platforms), - * this must be off. We keep this here as an option so that it is easy to - * test the pass-by-reference code paths on 64-bit platforms. - * - * Changing this requires an initdb. + * This symbol is now vestigial: built-in 8-byte types, including float8, + * int8, and timestamp, are always passed by value since we require Datum + * to be wide enough to permit that. We continue to define the symbol here + * so as not to unnecessarily break extension code. */ -#if SIZEOF_VOID_P >= 8 #define USE_FLOAT8_BYVAL 1 -#endif /* diff --git a/src/include/parser/pg_list.h b/src/include/parser/pg_list.h index 99f334b84..6a29615e5 100644 --- a/src/include/parser/pg_list.h +++ b/src/include/parser/pg_list.h @@ -29,8 +29,8 @@ * always be so; be careful to use the appropriate list type for your data.) * * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/pg_list.h @@ -212,10 +212,42 @@ list_length(const List *l) /* * Convenience macros for building fixed-length lists */ -#define list_make_ptr_cell(v) ((ListCell) {.ptr_value = (v)}) -#define list_make_int_cell(v) ((ListCell) {.int_value = (v)}) -#define list_make_oid_cell(v) ((ListCell) {.oid_value = (v)}) -#define list_make_xid_cell(v) ((ListCell) {.xid_value = (v)}) + +static inline ListCell +list_make_ptr_cell(void *v) +{ + ListCell c; + + c.ptr_value = v; + return c; +} + +static inline ListCell +list_make_int_cell(int v) +{ + ListCell c; + + c.int_value = v; + return c; +} + +static inline ListCell +list_make_oid_cell(Oid v) +{ + ListCell c; + + c.oid_value = v; + return c; +} + +static inline ListCell +list_make_xid_cell(TransactionId v) +{ + ListCell c; + + c.xid_value = v; + return c; +} #define list_make1(x1) \ list_make1_impl(T_List, list_make_ptr_cell(x1)) diff --git a/src/include/parser/pg_trigger.h b/src/include/parser/pg_trigger.h index daec329dd..a7f74835d 100644 --- a/src/include/parser/pg_trigger.h +++ b/src/include/parser/pg_trigger.h @@ -4,8 +4,8 @@ * definition of the "trigger" system catalog (pg_trigger) * * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_trigger.h @@ -33,6 +33,8 @@ * to be associated with a deferrable constraint. * ---------------- */ +BEGIN_CATALOG_STRUCT + CATALOG(pg_trigger,2620,TriggerRelationId) { Oid oid; /* oid */ @@ -74,6 +76,8 @@ CATALOG(pg_trigger,2620,TriggerRelationId) #endif } FormData_pg_trigger; +END_CATALOG_STRUCT + /* ---------------- * Form_pg_trigger corresponds to a pointer to a tuple with * the format of pg_trigger relation. diff --git a/src/include/parser/pg_wchar.h b/src/include/parser/pg_wchar.h index 8612afd07..6d3ce60a5 100644 --- a/src/include/parser/pg_wchar.h +++ b/src/include/parser/pg_wchar.h @@ -3,8 +3,8 @@ * pg_wchar.h * multibyte-character support * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/mb/pg_wchar.h @@ -23,6 +23,11 @@ #ifndef PG_WCHAR_H #define PG_WCHAR_H +#include + +typedef uint16_t char16_t; +typedef uint32_t char32_t; + /* * The pg_wchar type */ @@ -40,187 +45,21 @@ typedef unsigned int pg_wchar; #define SS3 0x8f /* single shift 3 (JIS0212) */ /* - * SJIS validation macros + * EUC_TW planes */ -#define ISSJISHEAD(c) (((c) >= 0x81 && (c) <= 0x9f) || ((c) >= 0xe0 && (c) <= 0xfc)) -#define ISSJISTAIL(c) (((c) >= 0x40 && (c) <= 0x7e) || ((c) >= 0x80 && (c) <= 0xfc)) - -/*---------------------------------------------------- - * MULE Internal Encoding (MIC) - * - * This encoding follows the design used within XEmacs; it is meant to - * subsume many externally-defined character sets. Each character includes - * identification of the character set it belongs to, so the encoding is - * general but somewhat bulky. - * - * Currently PostgreSQL supports 5 types of MULE character sets: - * - * 1) 1-byte ASCII characters. Each byte is below 0x80. - * - * 2) "Official" single byte charsets such as ISO-8859-1 (Latin1). - * Each MULE character consists of 2 bytes: LC1 + C1, where LC1 is - * an identifier for the charset (in the range 0x81 to 0x8d) and C1 - * is the character code (in the range 0xa0 to 0xff). - * - * 3) "Private" single byte charsets such as SISHENG. Each MULE - * character consists of 3 bytes: LCPRV1 + LC12 + C1, where LCPRV1 - * is a private-charset flag, LC12 is an identifier for the charset, - * and C1 is the character code (in the range 0xa0 to 0xff). - * LCPRV1 is either 0x9a (if LC12 is in the range 0xa0 to 0xdf) - * or 0x9b (if LC12 is in the range 0xe0 to 0xef). - * - * 4) "Official" multibyte charsets such as JIS X0208. Each MULE - * character consists of 3 bytes: LC2 + C1 + C2, where LC2 is - * an identifier for the charset (in the range 0x90 to 0x99) and C1 - * and C2 form the character code (each in the range 0xa0 to 0xff). - * - * 5) "Private" multibyte charsets such as CNS 11643-1992 Plane 3. - * Each MULE character consists of 4 bytes: LCPRV2 + LC22 + C1 + C2, - * where LCPRV2 is a private-charset flag, LC22 is an identifier for - * the charset, and C1 and C2 form the character code (each in the range - * 0xa0 to 0xff). LCPRV2 is either 0x9c (if LC22 is in the range 0xf0 - * to 0xf4) or 0x9d (if LC22 is in the range 0xf5 to 0xfe). - * - * "Official" encodings are those that have been assigned code numbers by - * the XEmacs project; "private" encodings have Postgres-specific charset - * identifiers. - * - * See the "XEmacs Internals Manual", available at http://www.xemacs.org, - * for more details. Note that for historical reasons, Postgres' - * private-charset flag values do not match what XEmacs says they should be, - * so this isn't really exactly MULE (not that private charsets would be - * interoperable anyway). - * - * Note that XEmacs's implementation is different from what emacs does. - * We follow emacs's implementation, rather than XEmacs's. - *---------------------------------------------------- - */ - -/* - * Charset identifiers (also called "leading bytes" in the MULE documentation) - */ - -/* - * Charset IDs for official single byte encodings (0x81-0x8e) - */ -#define LC_ISO8859_1 0x81 /* ISO8859 Latin 1 */ -#define LC_ISO8859_2 0x82 /* ISO8859 Latin 2 */ -#define LC_ISO8859_3 0x83 /* ISO8859 Latin 3 */ -#define LC_ISO8859_4 0x84 /* ISO8859 Latin 4 */ -#define LC_TIS620 0x85 /* Thai (not supported yet) */ -#define LC_ISO8859_7 0x86 /* Greek (not supported yet) */ -#define LC_ISO8859_6 0x87 /* Arabic (not supported yet) */ -#define LC_ISO8859_8 0x88 /* Hebrew (not supported yet) */ -#define LC_JISX0201K 0x89 /* Japanese 1 byte kana */ -#define LC_JISX0201R 0x8a /* Japanese 1 byte Roman */ -/* Note that 0x8b seems to be unused as of Emacs 20.7. - * However, there might be a chance that 0x8b could be used - * in later versions of Emacs. - */ -#define LC_KOI8_R 0x8b /* Cyrillic KOI8-R */ -#define LC_ISO8859_5 0x8c /* ISO8859 Cyrillic */ -#define LC_ISO8859_9 0x8d /* ISO8859 Latin 5 (not supported yet) */ -#define LC_ISO8859_15 0x8e /* ISO8859 Latin 15 (not supported yet) */ -/* #define CONTROL_1 0x8f control characters (unused) */ - -/* Is a leading byte for "official" single byte encodings? */ -#define IS_LC1(c) ((unsigned char)(c) >= 0x81 && (unsigned char)(c) <= 0x8d) - -/* - * Charset IDs for official multibyte encodings (0x90-0x99) - * 0x9a-0x9d are free. 0x9e and 0x9f are reserved. - */ -#define LC_JISX0208_1978 0x90 /* Japanese Kanji, old JIS (not supported) */ -#define LC_GB2312_80 0x91 /* Chinese */ -#define LC_JISX0208 0x92 /* Japanese Kanji (JIS X 0208) */ -#define LC_KS5601 0x93 /* Korean */ -#define LC_JISX0212 0x94 /* Japanese Kanji (JIS X 0212) */ #define LC_CNS11643_1 0x95 /* CNS 11643-1992 Plane 1 */ #define LC_CNS11643_2 0x96 /* CNS 11643-1992 Plane 2 */ -#define LC_JISX0213_1 0x97 /* Japanese Kanji (JIS X 0213 Plane 1) - * (not supported) */ -#define LC_BIG5_1 0x98 /* Plane 1 Chinese traditional (not - * supported) */ -#define LC_BIG5_2 0x99 /* Plane 1 Chinese traditional (not - * supported) */ - -/* Is a leading byte for "official" multibyte encodings? */ -#define IS_LC2(c) ((unsigned char)(c) >= 0x90 && (unsigned char)(c) <= 0x99) - -/* - * Postgres-specific prefix bytes for "private" single byte encodings - * (According to the MULE docs, we should be using 0x9e for this) - */ -#define LCPRV1_A 0x9a -#define LCPRV1_B 0x9b -#define IS_LCPRV1(c) ((unsigned char)(c) == LCPRV1_A || (unsigned char)(c) == LCPRV1_B) -#define IS_LCPRV1_A_RANGE(c) \ - ((unsigned char)(c) >= 0xa0 && (unsigned char)(c) <= 0xdf) -#define IS_LCPRV1_B_RANGE(c) \ - ((unsigned char)(c) >= 0xe0 && (unsigned char)(c) <= 0xef) - -/* - * Postgres-specific prefix bytes for "private" multibyte encodings - * (According to the MULE docs, we should be using 0x9f for this) - */ -#define LCPRV2_A 0x9c -#define LCPRV2_B 0x9d -#define IS_LCPRV2(c) ((unsigned char)(c) == LCPRV2_A || (unsigned char)(c) == LCPRV2_B) -#define IS_LCPRV2_A_RANGE(c) \ - ((unsigned char)(c) >= 0xf0 && (unsigned char)(c) <= 0xf4) -#define IS_LCPRV2_B_RANGE(c) \ - ((unsigned char)(c) >= 0xf5 && (unsigned char)(c) <= 0xfe) - -/* - * Charset IDs for private single byte encodings (0xa0-0xef) - */ -#define LC_SISHENG 0xa0 /* Chinese SiSheng characters for - * PinYin/ZhuYin (not supported) */ -#define LC_IPA 0xa1 /* IPA (International Phonetic - * Association) (not supported) */ -#define LC_VISCII_LOWER 0xa2 /* Vietnamese VISCII1.1 lower-case (not - * supported) */ -#define LC_VISCII_UPPER 0xa3 /* Vietnamese VISCII1.1 upper-case (not - * supported) */ -#define LC_ARABIC_DIGIT 0xa4 /* Arabic digit (not supported) */ -#define LC_ARABIC_1_COLUMN 0xa5 /* Arabic 1-column (not supported) */ -#define LC_ASCII_RIGHT_TO_LEFT 0xa6 /* ASCII (left half of ISO8859-1) with - * right-to-left direction (not - * supported) */ -#define LC_LAO 0xa7 /* Lao characters (ISO10646 0E80..0EDF) - * (not supported) */ -#define LC_ARABIC_2_COLUMN 0xa8 /* Arabic 1-column (not supported) */ - -/* - * Charset IDs for private multibyte encodings (0xf0-0xff) - */ -#define LC_INDIAN_1_COLUMN 0xf0 /* Indian charset for 1-column width - * glyphs (not supported) */ -#define LC_TIBETAN_1_COLUMN 0xf1 /* Tibetan 1-column width glyphs (not - * supported) */ -#define LC_UNICODE_SUBSET_2 0xf2 /* Unicode characters of the range - * U+2500..U+33FF. (not supported) */ -#define LC_UNICODE_SUBSET_3 0xf3 /* Unicode characters of the range - * U+E000..U+FFFF. (not supported) */ -#define LC_UNICODE_SUBSET 0xf4 /* Unicode characters of the range - * U+0100..U+24FF. (not supported) */ -#define LC_ETHIOPIC 0xf5 /* Ethiopic characters (not supported) */ #define LC_CNS11643_3 0xf6 /* CNS 11643-1992 Plane 3 */ #define LC_CNS11643_4 0xf7 /* CNS 11643-1992 Plane 4 */ #define LC_CNS11643_5 0xf8 /* CNS 11643-1992 Plane 5 */ #define LC_CNS11643_6 0xf9 /* CNS 11643-1992 Plane 6 */ #define LC_CNS11643_7 0xfa /* CNS 11643-1992 Plane 7 */ -#define LC_INDIAN_2_COLUMN 0xfb /* Indian charset for 2-column width - * glyphs (not supported) */ -#define LC_TIBETAN 0xfc /* Tibetan (not supported) */ -/* #define FREE 0xfd free (unused) */ -/* #define FREE 0xfe free (unused) */ -/* #define FREE 0xff free (unused) */ - -/*---------------------------------------------------- - * end of MULE stuff - *---------------------------------------------------- + +/* + * SJIS validation macros */ +#define ISSJISHEAD(c) (((c) >= 0x81 && (c) <= 0x9f) || ((c) >= 0xe0 && (c) <= 0xfc)) +#define ISSJISTAIL(c) (((c) >= 0x40 && (c) <= 0x7e) || ((c) >= 0x80 && (c) <= 0xfc)) /* * PostgreSQL encoding identifiers @@ -247,7 +86,7 @@ typedef enum pg_enc PG_EUC_TW, /* EUC for Taiwan */ PG_EUC_JIS_2004, /* EUC-JIS-2004 */ PG_UTF8, /* Unicode UTF8 */ - PG_MULE_INTERNAL, /* Mule internal code */ + PG_UNUSED_1, /* (Was Mule internal code) */ PG_LATIN1, /* ISO-8859-1 Latin 1 */ PG_LATIN2, /* ISO-8859-2 Latin 2 */ PG_LATIN3, /* ISO-8859-3 Latin 3 */ @@ -291,18 +130,21 @@ typedef enum pg_enc #define PG_ENCODING_BE_LAST PG_KOI8U +#define PG_UNUSED_ENCODING(_enc) \ + ((_enc) == PG_UNUSED_1) + /* * Please use these tests before access to pg_enc2name_tbl[] * or to other places... */ #define PG_VALID_BE_ENCODING(_enc) \ - ((_enc) >= 0 && (_enc) <= PG_ENCODING_BE_LAST) + ((_enc) >= 0 && (_enc) <= PG_ENCODING_BE_LAST && !PG_UNUSED_ENCODING(_enc)) #define PG_ENCODING_IS_CLIENT_ONLY(_enc) \ ((_enc) > PG_ENCODING_BE_LAST && (_enc) < _PG_LAST_ENCODING_) #define PG_VALID_ENCODING(_enc) \ - ((_enc) >= 0 && (_enc) < _PG_LAST_ENCODING_) + ((_enc) >= 0 && (_enc) < _PG_LAST_ENCODING_ && !PG_UNUSED_ENCODING(_enc)) /* On FE are possible all encodings */ #define PG_VALID_FE_ENCODING(_enc) PG_VALID_ENCODING(_enc) @@ -533,25 +375,25 @@ typedef uint32 (*utf_local_conversion_func) (uint32 code); * Some handy functions for Unicode-specific tests. */ static inline bool -is_valid_unicode_codepoint(pg_wchar c) +is_valid_unicode_codepoint(char32_t c) { return (c > 0 && c <= 0x10FFFF); } static inline bool -is_utf16_surrogate_first(pg_wchar c) +is_utf16_surrogate_first(char32_t c) { return (c >= 0xD800 && c <= 0xDBFF); } static inline bool -is_utf16_surrogate_second(pg_wchar c) +is_utf16_surrogate_second(char32_t c) { return (c >= 0xDC00 && c <= 0xDFFF); } -static inline pg_wchar -surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second) +static inline char32_t +surrogate_pair_to_codepoint(char16_t first, char16_t second) { return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF); } @@ -562,20 +404,20 @@ surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second) * * No error checks here, c must point to a long-enough string. */ -static inline pg_wchar +static inline char32_t utf8_to_unicode(const unsigned char *c) { if ((*c & 0x80) == 0) - return (pg_wchar) c[0]; + return (char32_t) c[0]; else if ((*c & 0xe0) == 0xc0) - return (pg_wchar) (((c[0] & 0x1f) << 6) | + return (char32_t) (((c[0] & 0x1f) << 6) | (c[1] & 0x3f)); else if ((*c & 0xf0) == 0xe0) - return (pg_wchar) (((c[0] & 0x0f) << 12) | + return (char32_t) (((c[0] & 0x0f) << 12) | ((c[1] & 0x3f) << 6) | (c[2] & 0x3f)); else if ((*c & 0xf8) == 0xf0) - return (pg_wchar) (((c[0] & 0x07) << 18) | + return (char32_t) (((c[0] & 0x07) << 18) | ((c[1] & 0x3f) << 12) | ((c[2] & 0x3f) << 6) | (c[3] & 0x3f)); @@ -589,7 +431,7 @@ utf8_to_unicode(const unsigned char *c) * unicode_utf8len(c) bytes available. */ static inline unsigned char * -unicode_to_utf8(pg_wchar c, unsigned char *utf8string) +unicode_to_utf8(char32_t c, unsigned char *utf8string) { if (c <= 0x7F) { @@ -621,7 +463,7 @@ unicode_to_utf8(pg_wchar c, unsigned char *utf8string) * Number of bytes needed to represent the given char in UTF8. */ static inline int -unicode_utf8len(pg_wchar c) +unicode_utf8len(char32_t c) { if (c <= 0x7F) return 1; @@ -677,11 +519,8 @@ extern int pg_valid_server_encoding(const char *name); extern bool is_encoding_supported_by_icu(int encoding); extern const char *get_encoding_name_for_icu(int encoding); -extern unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string); -extern pg_wchar utf8_to_unicode(const unsigned char *c); extern bool pg_utf8_islegal(const unsigned char *source, int length); extern int pg_utf_mblen(const unsigned char *s); -extern int pg_mule_mblen(const unsigned char *s); /* * The remaining functions are backend-only. @@ -698,7 +537,14 @@ extern int pg_char_and_wchar_strcmp(const char *s1, const pg_wchar *s2); extern int pg_wchar_strncmp(const pg_wchar *s1, const pg_wchar *s2, size_t n); extern int pg_char_and_wchar_strncmp(const char *s1, const pg_wchar *s2, size_t n); extern size_t pg_wchar_strlen(const pg_wchar *str); +extern int pg_mblen_cstr(const char *mbstr); +extern int pg_mblen_range(const char *mbstr, const char *end); +extern int pg_mblen_with_len(const char *mbstr, int limit); +extern int pg_mblen_unbounded(const char *mbstr); + +/* deprecated */ extern int pg_mblen(const char *mbstr); + extern int pg_dsplen(const char *mbstr); extern int pg_mbstrlen(const char *mbstr); extern int pg_mbstrlen_with_len(const char *mbstr, int limit); @@ -740,8 +586,8 @@ extern char *pg_server_to_client(const char *s, int len); extern char *pg_any_to_server(const char *s, int len, int encoding); extern char *pg_server_to_any(const char *s, int len, int encoding); -extern void pg_unicode_to_server(pg_wchar c, unsigned char *s); -extern bool pg_unicode_to_server_noerror(pg_wchar c, unsigned char *s); +extern void pg_unicode_to_server(char32_t c, unsigned char *s); +extern bool pg_unicode_to_server_noerror(char32_t c, unsigned char *s); extern unsigned short BIG5toCNS(unsigned short big5, unsigned char *lc); extern unsigned short CNStoBIG5(unsigned short cns, unsigned char lc); @@ -778,16 +624,6 @@ pg_noreturn extern void report_untranslatable_char(int src_encoding, int dest_en extern int local2local(const unsigned char *l, unsigned char *p, int len, int src_encoding, int dest_encoding, const unsigned char *tab, bool noError); -extern int latin2mic(const unsigned char *l, unsigned char *p, int len, - int lc, int encoding, bool noError); -extern int mic2latin(const unsigned char *mic, unsigned char *p, int len, - int lc, int encoding, bool noError); -extern int latin2mic_with_table(const unsigned char *l, unsigned char *p, - int len, int lc, int encoding, - const unsigned char *tab, bool noError); -extern int mic2latin_with_table(const unsigned char *mic, unsigned char *p, - int len, int lc, int encoding, - const unsigned char *tab, bool noError); #ifdef WIN32 extern WCHAR * pgwin32_message_to_UTF16(const char *str, int len, int *utf16len); diff --git a/src/include/parser/primnodes.h b/src/include/parser/primnodes.h index 6fce8be0c..66af7f0f8 100644 --- a/src/include/parser/primnodes.h +++ b/src/include/parser/primnodes.h @@ -6,8 +6,8 @@ * Currently, these are mostly nodes for executable expressions * and join trees. * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/primnodes.h @@ -336,7 +336,10 @@ typedef struct Var * references). This ensures that the Const node is self-contained and makes * it more likely that equal() will see logically identical values as equal. * - * Only the constant type OID is relevant for the query jumbling. + * For query jumble, we don't want different const values changing the jumble + * result. We only jumble consttype as different const types could result in + * very different plans and execution times, which is useful to distinguish in + * extensions such as pg_stat_statements. */ typedef struct Const { @@ -363,10 +366,7 @@ typedef struct Const */ bool constbyval pg_node_attr(query_jumble_ignore); - /* - * token location, or -1 if unknown. All constants are tracked as - * locations in query jumbling, to be marked as parameters. - */ + /* token location, or -1 if unknown. */ ParseLoc location pg_node_attr(query_jumble_location); } Const; @@ -469,9 +469,6 @@ typedef struct Param * and can share the result. Aggregates with same 'transno' but different * 'aggno' can share the same transition state, only the final function needs * to be called separately. - * - * Information related to collations, transition types and internal states - * are irrelevant for the query jumbling. */ typedef struct Aggref { @@ -567,9 +564,6 @@ typedef struct Aggref * * In raw parse output we have only the args list; parse analysis fills in the * refs list, and the planner fills in the cols list. - * - * All the fields used as information for an internal state are irrelevant - * for the query jumbling. */ typedef struct GroupingFunc { @@ -592,11 +586,20 @@ typedef struct GroupingFunc } GroupingFunc; /* - * WindowFunc - * - * Collation information is irrelevant for the query jumbling, as is the - * internal state information of the node like "winstar" and "winagg". + * Null Treatment options. If specified, initially set to PARSER_IGNORE_NULLS + * which is then converted to IGNORE_NULLS if the window function allows the + * null treatment clause. */ +#define NO_NULLTREATMENT 0 +#define PARSER_IGNORE_NULLS 1 +#define PARSER_RESPECT_NULLS 2 +#define IGNORE_NULLS 3 + + /* + * WindowFunc + * + * Node type to represent a call to a window function. + */ typedef struct WindowFunc { Expr xpr; @@ -620,6 +623,8 @@ typedef struct WindowFunc bool winstar pg_node_attr(query_jumble_ignore); /* is function a simple aggregate? */ bool winagg pg_node_attr(query_jumble_ignore); + /* ignore nulls. One of the Null Treatment options */ + int ignore_nulls; /* token location, or -1 if unknown */ ParseLoc location; } WindowFunc; @@ -707,8 +712,6 @@ typedef struct MergeSupportFunc * subscripting logic. Likewise, reftypmod and refcollid will match the * container's properties in a store, but could be different in a fetch. * - * Any internal state data is ignored for the query jumbling. - * * Note: for the cases where a container is returned, if refexpr yields a R/W * expanded container, then the implementation is allowed to modify that * object in-place and return the same object. @@ -776,9 +779,6 @@ typedef enum CoercionForm /* * FuncExpr - expression node for a function call - * - * Collation information is irrelevant for the query jumbling, only the - * arguments and the function OID matter. */ typedef struct FuncExpr { @@ -843,9 +843,6 @@ typedef struct NamedArgExpr * of the node. The planner makes sure it is valid before passing the node * tree to the executor, but during parsing/planning opfuncid can be 0. * Therefore, equal() will accept a zero value as being equal to other values. - * - * Internal state information and collation data is irrelevant for the query - * jumbling. */ typedef struct OpExpr { @@ -923,9 +920,6 @@ typedef OpExpr NullIfExpr; * Similar to OpExpr, opfuncid, hashfuncid, and negfuncid are not necessarily * filled in right away, so will be ignored for equality if they are not set * yet. - * - * OID entries of the internal function types are irrelevant for the query - * jumbling, but the operator OID and the arguments are. */ typedef struct ScalarArrayOpExpr { @@ -1113,6 +1107,7 @@ typedef struct SubPlan Oid firstColCollation; /* Collation of first column of subplan * result */ /* Information about execution strategy: */ + bool isInitPlan; /* true if it's an InitPlan */ bool useHashTable; /* true to store subselect output in a hash * table (implies we are doing "IN") */ bool unknownEqFalse; /* true if it's okay to return FALSE when the @@ -1127,6 +1122,7 @@ typedef struct SubPlan List *parParam; /* indices of input Params from parent plan */ List *args; /* exprs to pass as parParam values */ /* Estimated execution costs: */ + int disabled_nodes; /* count of disabled nodes in the plan */ Cost startup_cost; /* one-time setup cost */ Cost per_call_cost; /* cost for each subplan evaluation */ } SubPlan; @@ -1745,26 +1741,38 @@ typedef struct JsonValueExpr typedef enum JsonConstructorType { JSCTOR_JSON_OBJECT = 1, - JSCTOR_JSON_ARRAY = 2, - JSCTOR_JSON_OBJECTAGG = 3, - JSCTOR_JSON_ARRAYAGG = 4, - JSCTOR_JSON_PARSE = 5, - JSCTOR_JSON_SCALAR = 6, - JSCTOR_JSON_SERIALIZE = 7, + JSCTOR_JSON_ARRAY, + JSCTOR_JSON_ARRAY_QUERY, + JSCTOR_JSON_OBJECTAGG, + JSCTOR_JSON_ARRAYAGG, + JSCTOR_JSON_PARSE, + JSCTOR_JSON_SCALAR, + JSCTOR_JSON_SERIALIZE, } JsonConstructorType; /* * JsonConstructorExpr - * wrapper over FuncExpr/Aggref/WindowFunc for SQL/JSON constructors + * + * func is the executable expression: + * - Aggref/WindowFunc for JSON_OBJECTAGG/JSON_ARRAYAGG, + * - CoalesceExpr for JSON_ARRAY_QUERY, + * - NULL for other types (the executor calls the underlying json[b]_xxx() + * functions directly). + * + * orig_query holds the user's original subquery for JSON_ARRAY(query), used + * only by ruleutils.c for deparsing; it is not walked because func is + * authoritative for all other purposes. */ typedef struct JsonConstructorExpr { Expr xpr; JsonConstructorType type; /* constructor type */ List *args; - Expr *func; /* underlying json[b]_xxx() function call */ + Expr *func; /* executable expression or NULL */ Expr *coercion; /* coercion to RETURNING type */ JsonReturning *returning; /* RETURNING clause */ + Node *orig_query; /* original subquery for deparsing */ bool absent_on_null; /* ABSENT ON NULL? */ bool unique; /* WITH UNIQUE KEYS? (JSON_OBJECT[AGG] only) */ ParseLoc location; @@ -1793,6 +1801,7 @@ typedef struct JsonIsPredicate JsonFormat *format; /* FORMAT clause, if specified */ JsonValueType item_type; /* JSON item type */ bool unique_keys; /* check key uniqueness? */ + Oid exprBaseType; /* base type of the subject expression */ ParseLoc location; /* token location, or -1 if unknown */ } JsonIsPredicate; @@ -2209,6 +2218,30 @@ typedef struct ReturningExpr Expr *retexpr; /* expression to be returned */ } ReturningExpr; +/* + * GraphLabelRef - label reference in label expression inside GRAPH_TABLE clause + */ +typedef struct GraphLabelRef +{ + NodeTag type; + Oid labelid; + ParseLoc location; +} GraphLabelRef; + +/* + * GraphPropertyRef - property reference inside GRAPH_TABLE clause + */ +typedef struct GraphPropertyRef +{ + Expr xpr; + const char *elvarname; + Oid propid; + Oid typeId; + int32 typmod; + Oid collation; + ParseLoc location; +} GraphPropertyRef; + /*-------------------- * TargetEntry - * a target entry (used in query target lists) @@ -2402,7 +2435,7 @@ typedef struct FromExpr typedef struct OnConflictExpr { NodeTag type; - OnConflictAction action; /* DO NOTHING or UPDATE? */ + OnConflictAction action; /* DO NOTHING, SELECT, or UPDATE */ /* Arbiter */ List *arbiterElems; /* unique index arbiter list (of @@ -2417,4 +2450,39 @@ typedef struct OnConflictExpr List *exclRelTlist; /* tlist of the EXCLUDED pseudo relation */ } OnConflictExpr; +/*---------- + * ForPortionOfExpr - represents a FOR PORTION OF ... expression + * + * We set up an expression to make a range from the FROM/TO bounds, + * so that we can use range operators with it. + * + * Then we set up an overlaps expression between that and the range column, + * so that we can find the rows we need to update/delete. + * + * If the user used the FROM ... TO ... syntax, we save the individual + * expressions so that we can deparse them. + * + * In the executor we'll also build an intersect expression between the + * targeted range and the range column, so that we can update the start/end + * bounds of the UPDATE'd record. + *---------- + */ +typedef struct ForPortionOfExpr +{ + NodeTag type; + Var *rangeVar; /* Range column */ + char *range_name; /* Range name */ + Node *targetFrom; /* FOR PORTION OF FROM bound, if given */ + Node *targetTo; /* FOR PORTION OF TO bound, if given */ + Node *targetRange; /* FOR PORTION OF bounds as a range/multirange */ + Oid rangeType; /* (base)type of targetRange */ + bool isDomain; /* Is rangeVar a domain? */ + Node *overlapsExpr; /* range && targetRange */ + List *rangeTargetList; /* List of TargetEntrys to set the time + * column(s) */ + Oid withoutPortionProc; /* SRF proc for old_range - target_range */ + ParseLoc location; /* token location, or -1 if unknown */ + ParseLoc targetLocation; /* token location, or -1 if unknown */ +} ForPortionOfExpr; + #endif /* PRIMNODES_H */ diff --git a/src/include/parser/scanner.h b/src/include/parser/scanner.h index 69deaeb48..1f1fcfdf0 100644 --- a/src/include/parser/scanner.h +++ b/src/include/parser/scanner.h @@ -8,8 +8,8 @@ * higher-level API provided by parser.h. * * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/scanner.h @@ -87,8 +87,6 @@ typedef struct core_yy_extra_type * prevailing GUC settings. */ int backslash_quote; - bool escape_string_warning; - bool standard_conforming_strings; /* * literalbuf is used to accumulate literal values when multiple rules are @@ -112,8 +110,7 @@ typedef struct core_yy_extra_type /* first part of UTF16 surrogate pair for Unicode escapes */ int32 utf16_first_part; - /* state variables for literal-lexing warnings */ - bool warn_on_first_escape; + /* true if we need to verify valid encoding of current literal string */ bool saw_non_ascii; } core_yy_extra_type; diff --git a/src/include/parser/scansup.h b/src/include/parser/scansup.h index ef5e618be..d32f99b50 100644 --- a/src/include/parser/scansup.h +++ b/src/include/parser/scansup.h @@ -3,8 +3,8 @@ * scansup.h * scanner support routines used by the core lexer * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/scansup.h diff --git a/src/include/parser/stringinfo.h b/src/include/parser/stringinfo.h index 1897c96bb..e9a6c0359 100644 --- a/src/include/parser/stringinfo.h +++ b/src/include/parser/stringinfo.h @@ -8,8 +8,8 @@ * (null-terminated text) or arbitrary binary data. All storage is allocated * with palloc() (falling back to malloc in frontend code). * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/lib/stringinfo.h @@ -245,7 +245,7 @@ extern void resetStringInfo(StringInfo str); * to str if necessary. This is sort of like a combination of sprintf and * strcat. */ -extern void appendStringInfo(StringInfo str, const char *fmt,...) pg_attribute_printf(2, 3); +extern void appendStringInfo(StringInfo str, const char *fmt, ...) pg_attribute_printf(2, 3); /*------------------------ * appendStringInfoVA diff --git a/src/include/parser/unicode_east_asian_fw_table.h b/src/include/parser/unicode_east_asian_fw_table.h index db8bd0ad8..48c239f28 100644 --- a/src/include/parser/unicode_east_asian_fw_table.h +++ b/src/include/parser/unicode_east_asian_fw_table.h @@ -61,10 +61,10 @@ static const struct mbinterval east_asian_fw[] = { {0xFF01, 0xFF60}, {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4}, - {0x16FF0, 0x16FF1}, - {0x17000, 0x187F7}, - {0x18800, 0x18CD5}, - {0x18CFF, 0x18D08}, + {0x16FF0, 0x16FF6}, + {0x17000, 0x18CD5}, + {0x18CFF, 0x18D1E}, + {0x18D80, 0x18DF2}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, @@ -106,7 +106,7 @@ static const struct mbinterval east_asian_fw[] = { {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2}, - {0x1F6D5, 0x1F6D7}, + {0x1F6D5, 0x1F6D8}, {0x1F6DC, 0x1F6DF}, {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6FC}, @@ -116,11 +116,12 @@ static const struct mbinterval east_asian_fw[] = { {0x1F93C, 0x1F945}, {0x1F947, 0x1F9FF}, {0x1FA70, 0x1FA7C}, - {0x1FA80, 0x1FA89}, - {0x1FA8F, 0x1FAC6}, - {0x1FACE, 0x1FADC}, - {0x1FADF, 0x1FAE9}, - {0x1FAF0, 0x1FAF8}, + {0x1FA80, 0x1FA8A}, + {0x1FA8E, 0x1FAC6}, + {0x1FAC8, 0x1FAC8}, + {0x1FACD, 0x1FADC}, + {0x1FADF, 0x1FAEA}, + {0x1FAEF, 0x1FAF8}, {0x20000, 0x2FFFD}, {0x30000, 0x3FFFD}, }; diff --git a/src/include/parser/unicode_nonspacing_table.h b/src/include/parser/unicode_nonspacing_table.h index d67f5b3f2..dec117c0c 100644 --- a/src/include/parser/unicode_nonspacing_table.h +++ b/src/include/parser/unicode_nonspacing_table.h @@ -212,7 +212,7 @@ static const struct mbinterval nonspacing[] = { {0x10D24, 0x10D27}, {0x10D69, 0x10D6D}, {0x10EAB, 0x10EAC}, - {0x10EFC, 0x10EFF}, + {0x10EFA, 0x10EFF}, {0x10F46, 0x10F50}, {0x10F82, 0x10F85}, {0x11001, 0x11001}, @@ -286,6 +286,9 @@ static const struct mbinterval nonspacing[] = { {0x11A59, 0x11A5B}, {0x11A8A, 0x11A96}, {0x11A98, 0x11A99}, + {0x11B60, 0x11B60}, + {0x11B62, 0x11B64}, + {0x11B66, 0x11B66}, {0x11C30, 0x11C3D}, {0x11C3F, 0x11C3F}, {0x11C92, 0x11CA7}, @@ -332,6 +335,10 @@ static const struct mbinterval nonspacing[] = { {0x1E2EC, 0x1E2EF}, {0x1E4EC, 0x1E4EF}, {0x1E5EE, 0x1E5EF}, + {0x1E6E3, 0x1E6E3}, + {0x1E6E6, 0x1E6E6}, + {0x1E6EE, 0x1E6EF}, + {0x1E6F5, 0x1E6F5}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A}, {0xE0001, 0xE01EF}, diff --git a/src/include/parser/value.h b/src/include/parser/value.h index 0734c4ea2..12bc9242f 100644 --- a/src/include/parser/value.h +++ b/src/include/parser/value.h @@ -4,8 +4,8 @@ * interface for value nodes * * - * Copyright (c) 2003-2025, PgPool Global Development Group - * Copyright (c) 2003-2025, PostgreSQL Global Development Group + * Copyright (c) 2003-2026, PgPool Global Development Group + * Copyright (c) 2003-2026, PostgreSQL Global Development Group * * src/include/nodes/value.h * diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 70960fd08..d55e1b257 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -183,27 +183,37 @@ typedef enum * prevents gcc from making the unreachability deduction at optlevel -O0. *---------- */ + #ifdef HAVE__BUILTIN_CONSTANT_P -#define ereport_domain(elevel, domain, rest) \ + +#define ereport_domain(elevel, domain, ...) \ do { \ - if (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \ - errfinish rest; \ - if (__builtin_constant_p(elevel) && (elevel) >= ERROR && (elevel) != FRONTEND_ONLY_ERROR) \ + const int elevel_ = (elevel); \ + if (errstart(elevel_, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \ + errfinish(__VA_ARGS__); \ + if (__builtin_constant_p(elevel_) && \ + (elevel_) >= ERROR && \ + (elevel_) != FRONTEND_ONLY_ERROR) \ pg_unreachable(); \ - } while(0) -#else /* !HAVE__BUILTIN_CONSTANT_P */ -#define ereport_domain(elevel, domain, rest) \ + } while (0) + +#else /* !HAVE__BUILTIN_CONSTANT_P */ + +#define ereport_domain(elevel, domain, ...) \ do { \ const int elevel_ = (elevel); \ if (errstart(elevel_, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \ - errfinish rest; \ - if (elevel_ >= ERROR && elevel_ != FRONTEND_ONLY_ERROR) \ + errfinish(__VA_ARGS__); \ + if (elevel_ >= ERROR && \ + (elevel_) != FRONTEND_ONLY_ERROR) \ pg_unreachable(); \ - } while(0) -#endif /* HAVE__BUILTIN_CONSTANT_P */ + } while (0) + +#endif /* HAVE__BUILTIN_CONSTANT_P */ + -#define ereport(elevel, rest) \ - ereport_domain(elevel, TEXTDOMAIN, rest) +#define ereport(elevel, ...) \ + ereport_domain(elevel, TEXTDOMAIN, __VA_ARGS__) #define TEXTDOMAIN NULL diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h index 541e8e57e..84af2839b 100644 --- a/src/include/utils/palloc.h +++ b/src/include/utils/palloc.h @@ -84,6 +84,11 @@ extern void *palloc_extended(Size size, int flags); extern void *repalloc(void *pointer, Size size); extern void pfree(void *pointer); +/* + * Allocate space for an object of the specified type. + */ +#define palloc_object(type) ((type *) palloc(sizeof(type))) + /* Higher-limit allocators. */ extern void *MemoryContextAllocHuge(MemoryContext context, Size size); extern void *repalloc_huge(void *pointer, Size size); diff --git a/src/parser/copyfuncs.c b/src/parser/copyfuncs.c index 9cbbbe4f0..afb9d7574 100644 --- a/src/parser/copyfuncs.c +++ b/src/parser/copyfuncs.c @@ -11,8 +11,8 @@ * be handled easily in a simple depth-first traversal. * * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -4038,10 +4038,10 @@ _copyCallStmt(const CallStmt *from) return newnode; } -static ClusterStmt * -_copyClusterStmt(const ClusterStmt *from) +static RepackStmt * +_copyRepackStmt(const RepackStmt *from) { - ClusterStmt *newnode = makeNode(ClusterStmt); + RepackStmt *newnode = makeNode(RepackStmt); COPY_NODE_FIELD(relation); COPY_STRING_FIELD(indexname); @@ -6093,8 +6093,8 @@ copyObjectImpl(const void *from) case T_CallStmt: retval = _copyCallStmt(from); break; - case T_ClusterStmt: - retval = _copyClusterStmt(from); + case T_RepackStmt: + retval = _copyRepackStmt(from); break; case T_CopyStmt: retval = _copyCopyStmt(from); @@ -6628,7 +6628,7 @@ copyObjectImpl(const void *from) default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(from)); - retval = 0; /* keep compiler quiet */ + retval = NULL; /* keep compiler quiet */ break; } diff --git a/src/parser/gram.y b/src/parser/gram.y index 8052ced8d..2dae08fbd 100644 --- a/src/parser/gram.y +++ b/src/parser/gram.y @@ -6,8 +6,8 @@ * gram.y * POSTGRESQL BISON rules/actions * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -221,7 +221,7 @@ static void doNegateFloat(Float *v); static Node *makeAndExpr(Node *lexpr, Node *rexpr, int location); static Node *makeOrExpr(Node *lexpr, Node *rexpr, int location); static Node *makeNotExpr(Node *expr, int location); -static Node *makeAArrayExpr(List *elements, int location, int end_location); +static Node *makeAArrayExpr(List *elements, int location, int location_end); static Node *makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod, int location); static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, @@ -239,6 +239,11 @@ static void processCASbits(int cas_bits, int location, const char *constrType, bool *not_valid, bool *no_inherit, core_yyscan_t yyscanner); static PartitionStrategy parsePartitionStrategy(char *strategy, int location, core_yyscan_t yyscanner); +static void preprocess_pub_all_objtype_list(List *all_objects_list, + List **pubobjects, + bool *all_tables, + bool *all_sequences, + core_yyscan_t yyscanner); static void preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner); static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); @@ -295,8 +300,10 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); PartitionElem *partelem; PartitionSpec *partspec; PartitionBoundSpec *partboundspec; + SinglePartitionSpec *singlepartspec; RoleSpec *rolespec; PublicationObjSpec *publicationobjectspec; + PublicationAllObjSpec *publicationallobjectspec; struct SelectLimit *selectlimit; SetQuantifier setquantifier; struct GroupClause *groupclause; @@ -318,13 +325,14 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); AlterCompositeTypeStmt AlterUserMappingStmt AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt AlterStatsStmt AlterDefaultPrivilegesStmt DefACLAction - AnalyzeStmt CallStmt ClosePortalStmt ClusterStmt CommentStmt + AnalyzeStmt CallStmt ClosePortalStmt CommentStmt ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt CreateDomainStmt CreateExtensionStmt CreateGroupStmt CreateOpClassStmt CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt CreateSchemaStmt CreateSeqStmt CreateStmt CreateStatsStmt CreateTableSpaceStmt CreateFdwStmt CreateForeignServerStmt CreateForeignTableStmt CreateAssertionStmt CreateTransformStmt CreateTrigStmt CreateEventTrigStmt + CreatePropGraphStmt AlterPropGraphStmt CreateUserStmt CreateUserMappingStmt CreateRoleStmt CreatePolicyStmt CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt DoStmt DropOpClassStmt DropOpFamilyStmt DropStmt @@ -335,13 +343,13 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); GrantStmt GrantRoleStmt ImportForeignSchemaStmt IndexStmt InsertStmt ListenStmt LoadStmt LockStmt MergeStmt NotifyStmt ExplainableStmt PreparableStmt CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt - RemoveFuncStmt RemoveOperStmt RenameStmt ReturnStmt RevokeStmt RevokeRoleStmt + RemoveFuncStmt RemoveOperStmt RenameStmt RepackStmt ReturnStmt RevokeStmt RevokeRoleStmt RuleActionStmt RuleActionStmtOrEmpty RuleStmt SecLabelStmt SelectStmt TransactionStmt TransactionStmtLegacy TruncateStmt UnlistenStmt UpdateStmt VacuumStmt VariableResetStmt VariableSetStmt VariableShowStmt - ViewStmt CheckPointStmt CreateConversionStmt + ViewStmt WaitStmt CheckPointStmt CreateConversionStmt DeallocateStmt PrepareStmt ExecuteStmt DropOwnedStmt ReassignOwnedStmt AlterTSConfigurationStmt AlterTSDictionaryStmt @@ -355,8 +363,14 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type opt_single_name %type opt_qualified_name -%type opt_concurrently +%type opt_concurrently opt_usingindex %type opt_drop_behavior +%type opt_utility_option_list +%type opt_wait_with_clause +%type utility_option_list +%type utility_option_elem +%type utility_option_name +%type utility_option_arg %type alter_column_default opclass_item opclass_drop alter_using %type add_drop opt_asc_desc opt_nulls_order @@ -377,10 +391,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); create_extension_opt_item alter_extension_opt_item %type opt_lock lock_type cast_context -%type utility_option_name -%type utility_option_elem -%type utility_option_list -%type utility_option_arg %type drop_option %type opt_or_replace opt_no opt_grant_grant_option @@ -484,7 +494,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); transform_element_list transform_type_list TriggerTransitions TriggerReferencing vacuum_relation_list opt_vacuum_relation_list - drop_option_list pub_obj_list + drop_option_list pub_obj_list pub_all_obj_type_list + pub_except_obj_list opt_pub_except_clause %type returning_clause %type returning_option @@ -511,7 +522,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type OptNoLog %type OnCommitOption -%type for_locking_strength +%type for_locking_strength opt_for_locking_strength %type for_locking_item %type for_locking_clause opt_for_locking_clause for_locking_items %type locked_rels_list @@ -586,6 +597,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type relation_expr %type extended_relation_expr %type relation_expr_opt_alias +%type for_portion_of_opt_alias +%type for_portion_of_clause %type tablesample_clause opt_repeatable_clause %type target_el set_target insert_column_item @@ -595,7 +608,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type generic_option_list alter_generic_option_list %type reindex_target_relation reindex_target_all -%type opt_reindex_option_list %type copy_generic_opt_arg copy_generic_opt_arg_list_item %type copy_generic_opt_elem @@ -623,6 +635,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type var_value zone_value %type auth_ident RoleSpec opt_granted_by %type PublicationObjSpec +%type PublicationExceptObjSpec +%type PublicationAllObjSpec %type unreserved_keyword type_func_name_keyword %type col_name_keyword reserved_keyword @@ -647,8 +661,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type opt_provider security_label -%type xml_attribute_el -%type xml_attribute_list xml_attributes +%type labeled_expr +%type labeled_expr_list xml_attributes %type xml_root_version opt_xml_root_standalone %type xmlexists_argument %type document_or_content @@ -670,7 +684,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type window_clause window_definition_list opt_partition_clause %type window_definition over_clause window_specification opt_frame_clause frame_extent frame_bound -%type opt_window_exclusion_clause +%type null_treatment opt_window_exclusion_clause %type opt_existing_window_name %type opt_if_not_exists %type opt_unique_null_treatment @@ -679,6 +693,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type part_elem %type part_params %type PartitionBoundSpec +%type SinglePartitionSpec +%type partitions_list %type hash_partbound %type hash_partbound_elem @@ -710,6 +726,35 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); json_object_constructor_null_clause_opt json_array_constructor_null_clause_opt +%type vertex_tables_clause edge_tables_clause + opt_vertex_tables_clause opt_edge_tables_clause + vertex_table_list + opt_graph_table_key_clause + edge_table_list + source_vertex_table destination_vertex_table + opt_element_table_label_and_properties + label_and_properties_list + add_label_list +%type vertex_table_definition edge_table_definition +%type opt_propgraph_table_alias +%type element_table_label_clause +%type label_and_properties element_table_properties + add_label +%type vertex_or_edge + +%type opt_graph_pattern_quantifier + path_pattern_list + path_pattern + path_pattern_expression + path_term +%type graph_pattern + path_factor + path_primary + opt_is_label_expression + label_expression + label_disjunction + label_term +%type opt_colid /* * Non-keyword token types. These are hard-wired into the "flex" lexer. @@ -753,22 +798,22 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS - DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC + DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC DESTINATION DETACH DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP - EACH ELSE EMPTY_P ENABLE_P ENCODING ENCRYPTED END_P ENFORCED ENUM_P ERROR_P - ESCAPE EVENT EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN - EXPRESSION EXTENSION EXTERNAL EXTRACT + EACH EDGE ELSE EMPTY_P ENABLE_P ENCODING ENCRYPTED END_P ENFORCED ENUM_P + ERROR_P ESCAPE EVENT EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS + EXPLAIN EXPRESSION EXTENSION EXTERNAL EXTRACT FALSE_P FAMILY FETCH FILTER FINALIZE FIRST_P FLOAT_P FOLLOWING FOR FORCE FOREIGN FORMAT FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS - GENERATED GLOBAL GRANT GRANTED GREATEST GROUP_P GROUPING GROUPS + GENERATED GLOBAL GRANT GRANTED GRAPH GRAPH_TABLE GREATEST GROUP_P GROUPING GROUPS HANDLER HAVING HEADER_P HOLD HOUR_P - IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE + IDENTITY_P IF_P IGNORE_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE INCLUDING INCREMENT INDENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION @@ -780,12 +825,12 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); LABEL LANGUAGE LARGE_P LAST_P LATERAL_P LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL - LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOGGED + LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOGGED LSN_P MAPPING MATCH MATCHED MATERIALIZED MAXVALUE MERGE MERGE_ACTION METHOD MINUTE_P MINVALUE MODE MONTH_P MOVE - NAME_P NAMES NATIONAL NATURAL NCHAR NESTED NEW NEXT NFC NFD NFKC NFKD NO + NAME_P NAMES NATIONAL NATURAL NCHAR NESTED NEW NEXT NFC NFD NFKC NFKD NO NODE NONE NORMALIZE NORMALIZED NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NULLS_P NUMERIC @@ -794,22 +839,22 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); ORDER ORDINALITY OTHERS OUT_P OUTER_P OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER - PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD PATH PGPOOL - PERIOD PLACING PLAN PLANS POLICY + PARALLEL PARAMETER PARSER PARTIAL PARTITION PARTITIONS PASSING PASSWORD PATH PGPOOL + PERIOD PLACING PLAN PLANS POLICY PORTION POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY - PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION + PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PROPERTIES PROPERTY PUBLICATION QUOTE QUOTES RANGE READ REAL REASSIGN RECURSIVE REF_P REFERENCES REFERENCING - REFRESH REINDEX RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA - RESET RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP + REFRESH REINDEX RELATIONSHIP RELATIVE_P RELEASE RENAME REPACK REPEATABLE REPLACE REPLICA + RESET RESPECT_P RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP ROUTINE ROUTINES ROW ROWS RULE SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW - SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SOURCE SQL_P STABLE STANDALONE_P + SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SPLIT SOURCE SQL_P STABLE STANDALONE_P START STATEMENT STATISTICS STDIN STDOUT STORAGE STORED STRICT_P STRING_P STRIP_P SUBSCRIPTION SUBSTRING SUPPORT SYMMETRIC SYSID SYSTEM_P SYSTEM_USER @@ -822,9 +867,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); UNLISTEN UNLOGGED UNTIL UPDATE USER USING VACUUM VALID VALIDATE VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING - VERBOSE VERSION_P VIEW VIEWS VIRTUAL VOLATILE + VERBOSE VERSION_P VERTEX VIEW VIEWS VIRTUAL VOLATILE - WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE + WAIT WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE @@ -914,13 +959,16 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); * json_predicate_type_constraint and json_key_uniqueness_constraint_opt * productions (see comments there). * + * TO is assigned the same precedence as IDENT, to support the opt_interval + * production (see comment there). + * * Like the UNBOUNDED PRECEDING/FOLLOWING case, NESTED is assigned a lower * precedence than PATH to fix ambiguity in the json_table production. */ %nonassoc UNBOUNDED NESTED /* ideally would have same precedence as IDENT */ %nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP - SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT PATH -%left Op OPERATOR /* multi-character ops and user-defined operators */ + SET KEYS OBJECT_P SCALAR TO USING VALUE_P WITH WITHOUT PATH +%left Op OPERATOR RIGHT_ARROW '|' /* multi-character ops and user-defined operators */ %left '+' '-' %left '*' '/' '%' %left '^' @@ -1047,6 +1095,7 @@ stmt: | AlterOperatorStmt | AlterTypeStmt | AlterPolicyStmt + | AlterPropGraphStmt | AlterSeqStmt | AlterSystemStmt | AlterTableStmt @@ -1064,7 +1113,6 @@ stmt: | CallStmt | CheckPointStmt | ClosePortalStmt - | ClusterStmt | CommentStmt | ConstraintsSetStmt | CopyStmt @@ -1087,6 +1135,7 @@ stmt: | AlterOpFamilyStmt | CreatePolicyStmt | CreatePLangStmt + | CreatePropGraphStmt | CreateSchemaStmt | CreateSeqStmt | CreateStmt @@ -1138,6 +1187,7 @@ stmt: | RemoveFuncStmt | RemoveOperStmt | RenameStmt + | RepackStmt | RevokeStmt | RevokeRoleStmt | RuleStmt @@ -1152,6 +1202,7 @@ stmt: | VariableSetStmt | VariableShowStmt | ViewStmt + | WaitStmt | /*EMPTY*/ { $$ = NULL; } ; @@ -1174,12 +1225,52 @@ opt_concurrently: | /*EMPTY*/ { $$ = false; } ; +opt_usingindex: + USING INDEX { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; + opt_drop_behavior: CASCADE { $$ = DROP_CASCADE; } | RESTRICT { $$ = DROP_RESTRICT; } | /* EMPTY */ { $$ = DROP_RESTRICT; /* default */ } ; +opt_utility_option_list: + '(' utility_option_list ')' { $$ = $2; } + | /* EMPTY */ { $$ = NULL; } + ; + +utility_option_list: + utility_option_elem + { + $$ = list_make1($1); + } + | utility_option_list ',' utility_option_elem + { + $$ = lappend($1, $3); + } + ; + +utility_option_elem: + utility_option_name utility_option_arg + { + $$ = makeDefElem($1, $2, @1); + } + ; + +utility_option_name: + NonReservedWord { $$ = $1; } + | analyze_keyword { $$ = "analyze"; } + | FORMAT_LA { $$ = "format"; } + ; + +utility_option_arg: + opt_boolean_or_string { $$ = (Node *) makeString($1); } + | NumericOnly { $$ = (Node *) $1; } + | /* EMPTY */ { $$ = NULL; } + ; + /***************************************************************************** * * CALL statement @@ -1626,8 +1717,11 @@ OptSchemaEltList: schema_stmt: CreateStmt | IndexStmt + | CreateDomainStmt + | CreateFunctionStmt | CreateSeqStmt | CreateTrigStmt + | DefineStmt | GrantStmt | ViewStmt ; @@ -1727,6 +1821,26 @@ generic_set: n->location = @3; $$ = n; } + | var_name TO NULL_P + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = $1; + n->args = list_make1(makeNullAConst(@3)); + n->location = @3; + $$ = n; + } + | var_name '=' NULL_P + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = $1; + n->args = list_make1(makeNullAConst(@3)); + n->location = @3; + $$ = n; + } | var_name TO DEFAULT { VariableSetStmt *n = makeNode(VariableSetStmt); @@ -2107,11 +2221,12 @@ constraints_set_mode: * Checkpoint statement */ CheckPointStmt: - CHECKPOINT + CHECKPOINT opt_utility_option_list { CheckPointStmt *n = makeNode(CheckPointStmt); $$ = (Node *) n; + n->options = $2; } ; @@ -2400,6 +2515,23 @@ alter_table_cmds: | alter_table_cmds ',' alter_table_cmd { $$ = lappend($1, $3); } ; +partitions_list: + SinglePartitionSpec { $$ = list_make1($1); } + | partitions_list ',' SinglePartitionSpec { $$ = lappend($1, $3); } + ; + +SinglePartitionSpec: + PARTITION qualified_name PartitionBoundSpec + { + SinglePartitionSpec *n = makeNode(SinglePartitionSpec); + + n->name = $2; + n->bound = $3; + + $$ = n; + } + ; + partition_cmd: /* ALTER TABLE ATTACH PARTITION FOR VALUES */ ATTACH PARTITION qualified_name PartitionBoundSpec @@ -2410,6 +2542,7 @@ partition_cmd: n->subtype = AT_AttachPartition; cmd->name = $3; cmd->bound = $4; + cmd->partlist = NIL; cmd->concurrent = false; n->def = (Node *) cmd; @@ -2424,6 +2557,7 @@ partition_cmd: n->subtype = AT_DetachPartition; cmd->name = $3; cmd->bound = NULL; + cmd->partlist = NIL; cmd->concurrent = $4; n->def = (Node *) cmd; @@ -2437,6 +2571,35 @@ partition_cmd: n->subtype = AT_DetachPartitionFinalize; cmd->name = $3; cmd->bound = NULL; + cmd->partlist = NIL; + cmd->concurrent = false; + n->def = (Node *) cmd; + $$ = (Node *) n; + } + /* ALTER TABLE SPLIT PARTITION INTO () */ + | SPLIT PARTITION qualified_name INTO '(' partitions_list ')' + { + AlterTableCmd *n = makeNode(AlterTableCmd); + PartitionCmd *cmd = makeNode(PartitionCmd); + + n->subtype = AT_SplitPartition; + cmd->name = $3; + cmd->bound = NULL; + cmd->partlist = $6; + cmd->concurrent = false; + n->def = (Node *) cmd; + $$ = (Node *) n; + } + /* ALTER TABLE MERGE PARTITIONS () INTO */ + | MERGE PARTITIONS '(' qualified_name_list ')' INTO qualified_name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + PartitionCmd *cmd = makeNode(PartitionCmd); + + n->subtype = AT_MergePartitions; + cmd->name = $7; + cmd->bound = NULL; + cmd->partlist = $4; cmd->concurrent = false; n->def = (Node *) cmd; $$ = (Node *) n; @@ -2453,6 +2616,7 @@ index_partition_cmd: n->subtype = AT_AttachPartition; cmd->name = $3; cmd->bound = NULL; + cmd->partlist = NIL; cmd->concurrent = false; n->def = (Node *) cmd; @@ -3443,7 +3607,7 @@ ClosePortalStmt: * COPY ( query ) TO file [WITH] [(options)] * * where 'query' can be one of: - * { SELECT | UPDATE | INSERT | DELETE } + * { SELECT | UPDATE | INSERT | DELETE | MERGE } * * and 'file' can be one of: * { PROGRAM 'command' | STDIN | STDOUT | 'filename' } @@ -3484,6 +3648,7 @@ CopyStmt: COPY opt_binary qualified_name opt_column_list ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("WHERE clause not allowed with COPY TO"), + errhint("Try the COPY (SELECT ... WHERE ...) TO variant."), parser_errposition(@11))); n->options = NIL; @@ -3570,6 +3735,10 @@ copy_opt_item: { $$ = makeDefElem("format", (Node *) makeString("csv"), @1); } + | JSON + { + $$ = makeDefElem("format", (Node *) makeString("json"), @1); + } | HEADER_P { $$ = makeDefElem("header", (Node *) makeBoolean(true), @1); @@ -3652,6 +3821,10 @@ copy_generic_opt_elem: { $$ = makeDefElem($1, $2, @1); } + | FORMAT_LA copy_generic_opt_arg + { + $$ = makeDefElem("format", $2, @1); + } ; copy_generic_opt_arg: @@ -4570,19 +4743,19 @@ OptWhereClause: key_actions: key_update { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); n->updateAction = $1; - n->deleteAction = palloc(sizeof(KeyAction)); + n->deleteAction = palloc_object(KeyAction); n->deleteAction->action = FKCONSTR_ACTION_NOACTION; n->deleteAction->cols = NIL; $$ = n; } | key_delete { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); - n->updateAction = palloc(sizeof(KeyAction)); + n->updateAction = palloc_object(KeyAction); n->updateAction->action = FKCONSTR_ACTION_NOACTION; n->updateAction->cols = NIL; n->deleteAction = $1; @@ -4590,7 +4763,7 @@ key_actions: } | key_update key_delete { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); n->updateAction = $1; n->deleteAction = $2; @@ -4598,7 +4771,7 @@ key_actions: } | key_delete key_update { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); n->updateAction = $2; n->deleteAction = $1; @@ -4606,12 +4779,12 @@ key_actions: } | /*EMPTY*/ { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); - n->updateAction = palloc(sizeof(KeyAction)); + n->updateAction = palloc_object(KeyAction); n->updateAction->action = FKCONSTR_ACTION_NOACTION; n->updateAction->cols = NIL; - n->deleteAction = palloc(sizeof(KeyAction)); + n->deleteAction = palloc_object(KeyAction); n->deleteAction->action = FKCONSTR_ACTION_NOACTION; n->deleteAction->cols = NIL; $$ = n; @@ -4639,7 +4812,7 @@ key_delete: ON DELETE_P key_action key_action: NO ACTION { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_NOACTION; n->cols = NIL; @@ -4647,7 +4820,7 @@ key_action: } | RESTRICT { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_RESTRICT; n->cols = NIL; @@ -4655,7 +4828,7 @@ key_action: } | CASCADE { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_CASCADE; n->cols = NIL; @@ -4663,7 +4836,7 @@ key_action: } | SET NULL_P opt_column_list { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_SETNULL; n->cols = $3; @@ -4671,7 +4844,7 @@ key_action: } | SET DEFAULT opt_column_list { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_SETDEFAULT; n->cols = $3; @@ -5543,6 +5716,8 @@ fdw_option: | NO HANDLER { $$ = makeDefElem("handler", NULL, @1); } | VALIDATOR handler_name { $$ = makeDefElem("validator", (Node *) $2, @1); } | NO VALIDATOR { $$ = makeDefElem("validator", NULL, @1); } + | CONNECTION handler_name { $$ = makeDefElem("connection", (Node *) $2, @1); } + | NO CONNECTION { $$ = makeDefElem("connection", NULL, @1); } ; fdw_options: @@ -5868,7 +6043,7 @@ import_qualification_type: import_qualification: import_qualification_type '(' relation_expr_list ')' { - ImportQual *n = (ImportQual *) palloc(sizeof(ImportQual)); + ImportQual *n = palloc_object(ImportQual); n->type = $1; n->table_names = $3; @@ -5876,7 +6051,7 @@ import_qualification: } | /*EMPTY*/ { - ImportQual *n = (ImportQual *) palloc(sizeof(ImportQual)); + ImportQual *n = palloc_object(ImportQual); n->type = FDW_IMPORT_SCHEMA_ALL; n->table_names = NIL; $$ = n; @@ -6121,6 +6296,26 @@ CreateTrigStmt: EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')' { CreateTrigStmt *n = makeNode(CreateTrigStmt); + bool dummy; + + if (($11 & CAS_NOT_VALID) != 0) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constraint triggers cannot be marked %s", + "NOT VALID"), + parser_errposition(@11)); + if (($11 & CAS_NO_INHERIT) != 0) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constraint triggers cannot be marked %s", + "NO INHERIT"), + parser_errposition(@11)); + if (($11 & CAS_NOT_ENFORCED) != 0) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constraint triggers cannot be marked %s", + "NOT ENFORCED"), + parser_errposition(@11)); n->replace = $2; if (n->replace) /* not supported, see CreateTrigger */ @@ -6140,7 +6335,7 @@ CreateTrigStmt: n->whenClause = $15; n->transitionRels = NIL; processCASbits($11, @11, "TRIGGER", - &n->deferrable, &n->initdeferred, NULL, + &n->deferrable, &n->initdeferred, &dummy, NULL, NULL, yyscanner); n->constrrel = $10; $$ = (Node *) n; @@ -7135,6 +7330,7 @@ object_type_any_name: | MATERIALIZED VIEW { $$ = OBJECT_MATVIEW; } | INDEX { $$ = OBJECT_INDEX; } | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; } + | PROPERTY GRAPH { $$ = OBJECT_PROPGRAPH; } | COLLATION { $$ = OBJECT_COLLATION; } | CONVERSION_P { $$ = OBJECT_CONVERSION; } | STATISTICS { $$ = OBJECT_STATISTIC_EXT; } @@ -7563,6 +7759,8 @@ fetch_args: cursor_name n->portalname = $1; n->direction = FETCH_FORWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_NONE; $$ = (Node *) n; } | from_in cursor_name @@ -7572,6 +7770,19 @@ fetch_args: cursor_name n->portalname = $2; n->direction = FETCH_FORWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_NONE; + $$ = (Node *) n; + } + | SignedIconst opt_from_in cursor_name + { + FetchStmt *n = makeNode(FetchStmt); + + n->portalname = $3; + n->direction = FETCH_FORWARD; + n->howMany = $1; + n->location = @1; + n->direction_keyword = FETCH_KEYWORD_NONE; $$ = (Node *) n; } | NEXT opt_from_in cursor_name @@ -7581,6 +7792,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_NEXT; $$ = (Node *) n; } | PRIOR opt_from_in cursor_name @@ -7590,6 +7803,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_BACKWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_PRIOR; $$ = (Node *) n; } | FIRST_P opt_from_in cursor_name @@ -7599,6 +7814,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_ABSOLUTE; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_FIRST; $$ = (Node *) n; } | LAST_P opt_from_in cursor_name @@ -7608,6 +7825,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_ABSOLUTE; n->howMany = -1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_LAST; $$ = (Node *) n; } | ABSOLUTE_P SignedIconst opt_from_in cursor_name @@ -7617,6 +7836,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_ABSOLUTE; n->howMany = $2; + n->location = @2; + n->direction_keyword = FETCH_KEYWORD_ABSOLUTE; $$ = (Node *) n; } | RELATIVE_P SignedIconst opt_from_in cursor_name @@ -7626,15 +7847,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_RELATIVE; n->howMany = $2; - $$ = (Node *) n; - } - | SignedIconst opt_from_in cursor_name - { - FetchStmt *n = makeNode(FetchStmt); - - n->portalname = $3; - n->direction = FETCH_FORWARD; - n->howMany = $1; + n->location = @2; + n->direction_keyword = FETCH_KEYWORD_RELATIVE; $$ = (Node *) n; } | ALL opt_from_in cursor_name @@ -7644,6 +7858,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = FETCH_ALL; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_ALL; $$ = (Node *) n; } | FORWARD opt_from_in cursor_name @@ -7653,6 +7869,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_FORWARD; $$ = (Node *) n; } | FORWARD SignedIconst opt_from_in cursor_name @@ -7662,6 +7880,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_FORWARD; n->howMany = $2; + n->location = @2; + n->direction_keyword = FETCH_KEYWORD_FORWARD; $$ = (Node *) n; } | FORWARD ALL opt_from_in cursor_name @@ -7671,6 +7891,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_FORWARD; n->howMany = FETCH_ALL; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_FORWARD_ALL; $$ = (Node *) n; } | BACKWARD opt_from_in cursor_name @@ -7680,6 +7902,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_BACKWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_BACKWARD; $$ = (Node *) n; } | BACKWARD SignedIconst opt_from_in cursor_name @@ -7689,6 +7913,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_BACKWARD; n->howMany = $2; + n->location = @2; + n->direction_keyword = FETCH_KEYWORD_BACKWARD; $$ = (Node *) n; } | BACKWARD ALL opt_from_in cursor_name @@ -7698,6 +7924,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_BACKWARD; n->howMany = FETCH_ALL; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_BACKWARD_ALL; $$ = (Node *) n; } ; @@ -7877,7 +8105,7 @@ parameter_name: privilege_target: qualified_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TABLE; @@ -7886,7 +8114,7 @@ privilege_target: } | TABLE qualified_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TABLE; @@ -7895,7 +8123,7 @@ privilege_target: } | SEQUENCE qualified_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_SEQUENCE; @@ -7904,7 +8132,7 @@ privilege_target: } | FOREIGN DATA_P WRAPPER name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_FDW; @@ -7913,7 +8141,7 @@ privilege_target: } | FOREIGN SERVER name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_FOREIGN_SERVER; @@ -7922,7 +8150,7 @@ privilege_target: } | FUNCTION function_with_argtypes_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_FUNCTION; @@ -7931,7 +8159,7 @@ privilege_target: } | PROCEDURE function_with_argtypes_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_PROCEDURE; @@ -7940,7 +8168,7 @@ privilege_target: } | ROUTINE function_with_argtypes_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_ROUTINE; @@ -7949,7 +8177,7 @@ privilege_target: } | DATABASE name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_DATABASE; @@ -7958,7 +8186,7 @@ privilege_target: } | DOMAIN_P any_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_DOMAIN; @@ -7967,7 +8195,7 @@ privilege_target: } | LANGUAGE name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_LANGUAGE; @@ -7976,7 +8204,7 @@ privilege_target: } | LARGE_P OBJECT_P NumericOnly_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_LARGEOBJECT; @@ -7985,15 +8213,24 @@ privilege_target: } | PARAMETER parameter_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_PARAMETER_ACL; n->objs = $2; $$ = n; } + | PROPERTY GRAPH qualified_name_list + { + PrivTarget *n = palloc_object(PrivTarget); + + n->targtype = ACL_TARGET_OBJECT; + n->objtype = OBJECT_PROPGRAPH; + n->objs = $3; + $$ = n; + } | SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_SCHEMA; @@ -8002,7 +8239,7 @@ privilege_target: } | TABLESPACE name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TABLESPACE; @@ -8011,7 +8248,7 @@ privilege_target: } | TYPE_P any_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TYPE; @@ -8020,7 +8257,7 @@ privilege_target: } | ALL TABLES IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_TABLE; @@ -8029,7 +8266,7 @@ privilege_target: } | ALL SEQUENCES IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_SEQUENCE; @@ -8038,7 +8275,7 @@ privilege_target: } | ALL FUNCTIONS IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_FUNCTION; @@ -8047,7 +8284,7 @@ privilege_target: } | ALL PROCEDURES IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_PROCEDURE; @@ -8056,7 +8293,7 @@ privilege_target: } | ALL ROUTINES IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_ROUTINE; @@ -8365,6 +8602,7 @@ index_elem_options: $$->opclassopts = NIL; $$->ordering = $3; $$->nulls_ordering = $4; + /* location will be filled in index_elem production */ } | opt_collate any_name reloptions opt_asc_desc opt_nulls_order { @@ -8377,6 +8615,7 @@ index_elem_options: $$->opclassopts = $3; $$->ordering = $4; $$->nulls_ordering = $5; + /* location will be filled in index_elem production */ } ; @@ -8389,16 +8628,19 @@ index_elem: ColId index_elem_options { $$ = $2; $$->name = $1; + $$->location = @1; } | func_expr_windowless index_elem_options { $$ = $2; $$->expr = $1; + $$->location = @1; } | '(' a_expr ')' index_elem_options { $$ = $4; $$->expr = $2; + $$->location = @1; } ; @@ -9315,6 +9557,370 @@ opt_if_exists: IF_P EXISTS { $$ = true; } ; +/***************************************************************************** + * + * CREATE PROPERTY GRAPH + * ALTER PROPERTY GRAPH + * + *****************************************************************************/ + +CreatePropGraphStmt: CREATE OptTemp PROPERTY GRAPH qualified_name opt_vertex_tables_clause opt_edge_tables_clause + { + CreatePropGraphStmt *n = makeNode(CreatePropGraphStmt); + + n->pgname = $5; + n->pgname->relpersistence = $2; + n->vertex_tables = $6; + n->edge_tables = $7; + + $$ = (Node *)n; + } + ; + +opt_vertex_tables_clause: + vertex_tables_clause { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +vertex_tables_clause: + vertex_synonym TABLES '(' vertex_table_list ')' { $$ = $4; } + ; + +vertex_synonym: NODE | VERTEX + ; + +vertex_table_list: vertex_table_definition { $$ = list_make1($1); } + | vertex_table_list ',' vertex_table_definition { $$ = lappend($1, $3); } + ; + +vertex_table_definition: qualified_name opt_propgraph_table_alias opt_graph_table_key_clause + opt_element_table_label_and_properties + { + PropGraphVertex *n = makeNode(PropGraphVertex); + + $1->alias = $2; + n->vtable = $1; + n->vkey = $3; + n->labels = $4; + n->location = @1; + + $$ = (Node *) n; + } + ; + +opt_propgraph_table_alias: + AS name + { + $$ = makeNode(Alias); + $$->aliasname = $2; + } + | /*EMPTY*/ { $$ = NULL; } + ; + +opt_graph_table_key_clause: + KEY '(' columnList ')' { $$ = $3; } + | /*EMPTY*/ { $$ = NIL; } + ; + +opt_edge_tables_clause: + edge_tables_clause { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +edge_tables_clause: + edge_synonym TABLES '(' edge_table_list ')' { $$ = $4; } + ; + +edge_synonym: EDGE | RELATIONSHIP + ; + +edge_table_list: edge_table_definition { $$ = list_make1($1); } + | edge_table_list ',' edge_table_definition { $$ = lappend($1, $3); } + ; + +edge_table_definition: qualified_name opt_propgraph_table_alias opt_graph_table_key_clause + source_vertex_table destination_vertex_table opt_element_table_label_and_properties + { + PropGraphEdge *n = makeNode(PropGraphEdge); + + $1->alias = $2; + n->etable = $1; + n->ekey = $3; + n->esrckey = linitial($4); + n->esrcvertex = lsecond($4); + n->esrcvertexcols = lthird($4); + n->edestkey = linitial($5); + n->edestvertex = lsecond($5); + n->edestvertexcols = lthird($5); + n->labels = $6; + n->location = @1; + + $$ = (Node *) n; + } + ; + +source_vertex_table: SOURCE name + { + $$ = list_make3(NULL, $2, NULL); + } + | SOURCE KEY '(' columnList ')' REFERENCES name '(' columnList ')' + { + $$ = list_make3($4, $7, $9); + } + ; + +destination_vertex_table: DESTINATION name + { + $$ = list_make3(NULL, $2, NULL); + } + | DESTINATION KEY '(' columnList ')' REFERENCES name '(' columnList ')' + { + $$ = list_make3($4, $7, $9); + } + ; + +opt_element_table_label_and_properties: + element_table_properties + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + + lp->properties = (PropGraphProperties *) $1; + lp->location = @1; + + $$ = list_make1(lp); + } + | label_and_properties_list + { + $$ = $1; + } + | /*EMPTY*/ + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->all = true; + pr->location = -1; + lp->properties = pr; + lp->location = -1; + + $$ = list_make1(lp); + } + ; + +element_table_properties: + NO PROPERTIES + { + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->properties = NIL; + pr->location = @1; + + $$ = (Node *) pr; + } + | PROPERTIES ALL COLUMNS + /* + * SQL standard also allows "PROPERTIES ARE ALL COLUMNS", but that + * would require making ARE a keyword, which seems a bit much for + * such a marginal use. Could be added later if needed. + */ + { + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->all = true; + pr->location = @1; + + $$ = (Node *) pr; + } + | PROPERTIES '(' labeled_expr_list ')' + { + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->properties = $3; + pr->location = @1; + + $$ = (Node *) pr; + } + ; + +label_and_properties_list: + label_and_properties + { + $$ = list_make1($1); + } + | label_and_properties_list label_and_properties + { + $$ = lappend($1, $2); + } + ; + +label_and_properties: + element_table_label_clause + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->all = true; + pr->location = -1; + + lp->label = $1; + lp->properties = pr; + lp->location = @1; + + $$ = (Node *) lp; + } + | element_table_label_clause element_table_properties + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + + lp->label = $1; + lp->properties = (PropGraphProperties *) $2; + lp->location = @1; + + $$ = (Node *) lp; + } + ; + +element_table_label_clause: + LABEL name + { + $$ = $2; + } + | DEFAULT LABEL + { + $$ = NULL; + } + ; + +AlterPropGraphStmt: + ALTER PROPERTY GRAPH qualified_name ADD_P vertex_tables_clause + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->add_vertex_tables = $6; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ADD_P vertex_tables_clause ADD_P edge_tables_clause + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->add_vertex_tables = $6; + n->add_edge_tables = $8; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ADD_P edge_tables_clause + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->add_edge_tables = $6; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name DROP vertex_synonym TABLES '(' name_list ')' opt_drop_behavior + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->drop_vertex_tables = $9; + n->drop_behavior = $11; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name DROP edge_synonym TABLES '(' name_list ')' opt_drop_behavior + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->drop_edge_tables = $9; + n->drop_behavior = $11; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ALTER vertex_or_edge TABLE name + add_label_list + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->element_kind = $6; + n->element_alias = $8; + n->add_labels = $9; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ALTER vertex_or_edge TABLE name + DROP LABEL name opt_drop_behavior + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->element_kind = $6; + n->element_alias = $8; + n->drop_label = $11; + n->drop_behavior = $12; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ALTER vertex_or_edge TABLE name + ALTER LABEL name ADD_P PROPERTIES '(' labeled_expr_list ')' + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + PropGraphProperties *pr = makeNode(PropGraphProperties); + + n->pgname = $4; + n->element_kind = $6; + n->element_alias = $8; + n->alter_label = $11; + + pr->properties = $15; + pr->location = @13; + n->add_properties = pr; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ALTER vertex_or_edge TABLE name + ALTER LABEL name DROP PROPERTIES '(' name_list ')' opt_drop_behavior + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->element_kind = $6; + n->element_alias = $8; + n->alter_label = $11; + n->drop_properties = $15; + n->drop_behavior = $17; + + $$ = (Node *) n; + } + ; + +vertex_or_edge: + vertex_synonym { $$ = PROPGRAPH_ELEMENT_KIND_VERTEX; } + | edge_synonym { $$ = PROPGRAPH_ELEMENT_KIND_EDGE; } + ; + +add_label_list: + add_label { $$ = list_make1($1); } + | add_label_list add_label { $$ = lappend($1, $2); } + ; + +add_label: ADD_P LABEL name element_table_properties + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + + lp->label = $3; + lp->properties = (PropGraphProperties *) $4; + lp->location = @1; + + $$ = (Node *) lp; + } + ; + + /***************************************************************************** * * CREATE TRANSFORM / DROP TRANSFORM @@ -9375,7 +9981,7 @@ DropTransformStmt: DROP TRANSFORM opt_if_exists FOR Typename LANGUAGE name opt_d *****************************************************************************/ ReindexStmt: - REINDEX opt_reindex_option_list reindex_target_relation opt_concurrently qualified_name + REINDEX opt_utility_option_list reindex_target_relation opt_concurrently qualified_name { ReindexStmt *n = makeNode(ReindexStmt); @@ -9388,7 +9994,7 @@ ReindexStmt: makeDefElem("concurrently", NULL, @4)); $$ = (Node *) n; } - | REINDEX opt_reindex_option_list SCHEMA opt_concurrently name + | REINDEX opt_utility_option_list SCHEMA opt_concurrently name { ReindexStmt *n = makeNode(ReindexStmt); @@ -9401,7 +10007,7 @@ ReindexStmt: makeDefElem("concurrently", NULL, @4)); $$ = (Node *) n; } - | REINDEX opt_reindex_option_list reindex_target_all opt_concurrently opt_single_name + | REINDEX opt_utility_option_list reindex_target_all opt_concurrently opt_single_name { ReindexStmt *n = makeNode(ReindexStmt); @@ -9423,10 +10029,6 @@ reindex_target_all: SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; } | DATABASE { $$ = REINDEX_OBJECT_DATABASE; } ; -opt_reindex_option_list: - '(' utility_option_list ')' { $$ = $2; } - | /* EMPTY */ { $$ = NULL; } - ; /***************************************************************************** * @@ -9615,6 +10217,16 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name n->missing_ok = false; $$ = (Node *) n; } + | ALTER PROPERTY GRAPH qualified_name RENAME TO name + { + RenameStmt *n = makeNode(RenameStmt); + + n->renameType = OBJECT_PROPGRAPH; + n->relation = $4; + n->newname = $7; + n->missing_ok = false; + $$ = (Node *)n; + } | ALTER PUBLICATION name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); @@ -10240,6 +10852,26 @@ AlterObjectSchemaStmt: n->missing_ok = false; $$ = (Node *) n; } + | ALTER PROPERTY GRAPH qualified_name SET SCHEMA name + { + AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + + n->objectType = OBJECT_PROPGRAPH; + n->relation = $4; + n->newschema = $7; + n->missing_ok = false; + $$ = (Node *)n; + } + | ALTER PROPERTY GRAPH IF_P EXISTS qualified_name SET SCHEMA name + { + AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + + n->objectType = OBJECT_PROPGRAPH; + n->relation = $6; + n->newschema = $9; + n->missing_ok = true; + $$ = (Node *)n; + } | ALTER ROUTINE function_with_argtypes SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); @@ -10583,6 +11215,15 @@ AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec n->newowner = $6; $$ = (Node *) n; } + | ALTER PROPERTY GRAPH qualified_name OWNER TO RoleSpec + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + + n->objectType = OBJECT_PROPGRAPH; + n->relation = $4; + n->newowner = $7; + $$ = (Node *) n; + } | ALTER ROUTINE function_with_argtypes OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); @@ -10698,7 +11339,12 @@ AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec * * CREATE PUBLICATION name [WITH options] * - * CREATE PUBLICATION FOR ALL TABLES [WITH options] + * CREATE PUBLICATION FOR ALL pub_all_obj_type [, ...] [WITH options] + * + * pub_all_obj_type is one of: + * + * TABLES [EXCEPT (TABLE table [, ...] )] + * SEQUENCES * * CREATE PUBLICATION FOR pub_obj [, ...] [WITH options] * @@ -10718,13 +11364,16 @@ CreatePublicationStmt: n->options = $4; $$ = (Node *) n; } - | CREATE PUBLICATION name FOR ALL TABLES opt_definition + | CREATE PUBLICATION name FOR pub_all_obj_type_list opt_definition { CreatePublicationStmt *n = makeNode(CreatePublicationStmt); n->pubname = $3; - n->options = $7; - n->for_all_tables = true; + preprocess_pub_all_objtype_list($5, &n->pubobjects, + &n->for_all_tables, + &n->for_all_sequences, + yyscanner); + n->options = $6; $$ = (Node *) n; } | CREATE PUBLICATION name FOR pub_obj_list opt_definition @@ -10836,6 +11485,51 @@ pub_obj_list: PublicationObjSpec { $$ = lappend($1, $3); } ; +opt_pub_except_clause: + EXCEPT '(' TABLE pub_except_obj_list ')' { $$ = $4; } + | /*EMPTY*/ { $$ = NIL; } + ; + +PublicationAllObjSpec: + ALL TABLES opt_pub_except_clause + { + $$ = makeNode(PublicationAllObjSpec); + $$->pubobjtype = PUBLICATION_ALL_TABLES; + $$->except_tables = $3; + $$->location = @1; + } + | ALL SEQUENCES + { + $$ = makeNode(PublicationAllObjSpec); + $$->pubobjtype = PUBLICATION_ALL_SEQUENCES; + $$->location = @1; + } + ; + +pub_all_obj_type_list: PublicationAllObjSpec + { $$ = list_make1($1); } + | pub_all_obj_type_list ',' PublicationAllObjSpec + { $$ = lappend($1, $3); } + ; + +PublicationExceptObjSpec: + relation_expr + { + $$ = makeNode(PublicationObjSpec); + $$->pubobjtype = PUBLICATIONOBJ_EXCEPT_TABLE; + $$->pubtable = makeNode(PublicationTable); + $$->pubtable->except = true; + $$->pubtable->relation = $1; + $$->location = @1; + } + ; + +pub_except_obj_list: PublicationExceptObjSpec + { $$ = list_make1($1); } + | pub_except_obj_list ',' opt_table PublicationExceptObjSpec + { $$ = lappend($1, $4); } + ; + /***************************************************************************** * * ALTER PUBLICATION name SET ( options ) @@ -10846,11 +11540,18 @@ pub_obj_list: PublicationObjSpec * * ALTER PUBLICATION name SET pub_obj [, ...] * + * ALTER PUBLICATION name SET pub_all_obj_type [, ...] + * * pub_obj is one of: * * TABLE table_name [, ...] * TABLES IN SCHEMA schema_name [, ...] * + * pub_all_obj_type is one of: + * + * ALL TABLES [ EXCEPT ( TABLE table_name [, ...] ) ] + * ALL SEQUENCES + * *****************************************************************************/ AlterPublicationStmt: @@ -10860,6 +11561,7 @@ AlterPublicationStmt: n->pubname = $3; n->options = $5; + n->for_all_tables = false; $$ = (Node *) n; } | ALTER PUBLICATION name ADD_P pub_obj_list @@ -10870,6 +11572,7 @@ AlterPublicationStmt: n->pubobjects = $5; preprocess_pubobj_list(n->pubobjects, yyscanner); n->action = AP_AddObjects; + n->for_all_tables = false; $$ = (Node *) n; } | ALTER PUBLICATION name SET pub_obj_list @@ -10880,6 +11583,19 @@ AlterPublicationStmt: n->pubobjects = $5; preprocess_pubobj_list(n->pubobjects, yyscanner); n->action = AP_SetObjects; + n->for_all_tables = false; + $$ = (Node *) n; + } + | ALTER PUBLICATION name SET pub_all_obj_type_list + { + AlterPublicationStmt *n = makeNode(AlterPublicationStmt); + + n->pubname = $3; + n->action = AP_SetObjects; + preprocess_pub_all_objtype_list($5, &n->pubobjects, + &n->for_all_tables, + &n->for_all_sequences, + yyscanner); $$ = (Node *) n; } | ALTER PUBLICATION name DROP pub_obj_list @@ -10890,6 +11606,7 @@ AlterPublicationStmt: n->pubobjects = $5; preprocess_pubobj_list(n->pubobjects, yyscanner); n->action = AP_DropObjects; + n->for_all_tables = false; $$ = (Node *) n; } ; @@ -10911,6 +11628,16 @@ CreateSubscriptionStmt: n->options = $8; $$ = (Node *) n; } + | CREATE SUBSCRIPTION name SERVER name PUBLICATION name_list opt_definition + { + CreateSubscriptionStmt *n = + makeNode(CreateSubscriptionStmt); + n->subname = $3; + n->servername = $5; + n->publication = $7; + n->options = $8; + $$ = (Node *) n; + } ; /***************************************************************************** @@ -10927,27 +11654,46 @@ AlterSubscriptionStmt: n->kind = ALTER_SUBSCRIPTION_OPTIONS; n->subname = $3; - n->options = $5; + n->options = $5; + $$ = (Node *) n; + } + | ALTER SUBSCRIPTION name CONNECTION Sconst + { + AlterSubscriptionStmt *n = + makeNode(AlterSubscriptionStmt); + + n->kind = ALTER_SUBSCRIPTION_CONNECTION; + n->subname = $3; + n->conninfo = $5; + $$ = (Node *) n; + } + | ALTER SUBSCRIPTION name SERVER name + { + AlterSubscriptionStmt *n = + makeNode(AlterSubscriptionStmt); + + n->kind = ALTER_SUBSCRIPTION_SERVER; + n->subname = $3; + n->servername = $5; $$ = (Node *) n; } - | ALTER SUBSCRIPTION name CONNECTION Sconst + | ALTER SUBSCRIPTION name REFRESH PUBLICATION opt_definition { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_CONNECTION; + n->kind = ALTER_SUBSCRIPTION_REFRESH_PUBLICATION; n->subname = $3; - n->conninfo = $5; + n->options = $6; $$ = (Node *) n; } - | ALTER SUBSCRIPTION name REFRESH PUBLICATION opt_definition + | ALTER SUBSCRIPTION name REFRESH SEQUENCES { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_REFRESH; + n->kind = ALTER_SUBSCRIPTION_REFRESH_SEQUENCES; n->subname = $3; - n->options = $6; $$ = (Node *) n; } | ALTER SUBSCRIPTION name ADD_P PUBLICATION name_list opt_definition @@ -11713,7 +12459,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'T'; + n->subtype = AD_AlterDefault; n->typeName = $3; n->def = $4; $$ = (Node *) n; @@ -11723,7 +12469,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'N'; + n->subtype = AD_DropNotNull; n->typeName = $3; $$ = (Node *) n; } @@ -11732,7 +12478,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'O'; + n->subtype = AD_SetNotNull; n->typeName = $3; $$ = (Node *) n; } @@ -11741,7 +12487,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'C'; + n->subtype = AD_AddConstraint; n->typeName = $3; n->def = $5; $$ = (Node *) n; @@ -11751,7 +12497,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'X'; + n->subtype = AD_DropConstraint; n->typeName = $3; n->name = $6; n->behavior = $7; @@ -11763,7 +12509,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'X'; + n->subtype = AD_DropConstraint; n->typeName = $3; n->name = $8; n->behavior = $9; @@ -11775,7 +12521,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'V'; + n->subtype = AD_ValidateConstraint; n->typeName = $3; n->name = $6; $$ = (Node *) n; @@ -11908,65 +12654,110 @@ CreateConversionStmt: /***************************************************************************** * * QUERY: + * REPACK [ (options) ] [ [ ] [ USING INDEX ] ] + * + * obsolete variants: * CLUSTER (options) [ [ USING ] ] * CLUSTER [VERBOSE] [ [ USING ] ] * CLUSTER [VERBOSE] ON (for pre-8.3) * *****************************************************************************/ -ClusterStmt: - CLUSTER '(' utility_option_list ')' qualified_name cluster_index_specification +RepackStmt: + REPACK opt_utility_option_list vacuum_relation USING INDEX name { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); - n->relation = $5; + n->command = REPACK_COMMAND_REPACK; + n->relation = (VacuumRelation *) $3; n->indexname = $6; - n->params = $3; + n->usingindex = true; + n->params = $2; + $$ = (Node *) n; + } + | REPACK opt_utility_option_list vacuum_relation opt_usingindex + { + RepackStmt *n = makeNode(RepackStmt); + + n->command = REPACK_COMMAND_REPACK; + n->relation = (VacuumRelation *) $3; + n->indexname = NULL; + n->usingindex = $4; + n->params = $2; $$ = (Node *) n; } - | CLUSTER '(' utility_option_list ')' + | REPACK opt_utility_option_list opt_usingindex { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); + n->command = REPACK_COMMAND_REPACK; n->relation = NULL; n->indexname = NULL; + n->usingindex = $3; + n->params = $2; + $$ = (Node *) n; + } + | CLUSTER '(' utility_option_list ')' qualified_name cluster_index_specification + { + RepackStmt *n = makeNode(RepackStmt); + + n->command = REPACK_COMMAND_CLUSTER; + n->relation = makeNode(VacuumRelation); + n->relation->relation = $5; + n->indexname = $6; + n->usingindex = true; n->params = $3; $$ = (Node *) n; } + | CLUSTER opt_utility_option_list + { + RepackStmt *n = makeNode(RepackStmt); + + n->command = REPACK_COMMAND_CLUSTER; + n->relation = NULL; + n->indexname = NULL; + n->usingindex = true; + n->params = $2; + $$ = (Node *) n; + } /* unparenthesized VERBOSE kept for pre-14 compatibility */ | CLUSTER opt_verbose qualified_name cluster_index_specification { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); - n->relation = $3; + n->command = REPACK_COMMAND_CLUSTER; + n->relation = makeNode(VacuumRelation); + n->relation->relation = $3; n->indexname = $4; - n->params = NIL; + n->usingindex = true; if ($2) - n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + n->params = list_make1(makeDefElem("verbose", NULL, @2)); $$ = (Node *) n; } /* unparenthesized VERBOSE kept for pre-17 compatibility */ - | CLUSTER opt_verbose + | CLUSTER VERBOSE { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); + n->command = REPACK_COMMAND_CLUSTER; n->relation = NULL; n->indexname = NULL; - n->params = NIL; - if ($2) - n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + n->usingindex = true; + n->params = list_make1(makeDefElem("verbose", NULL, @2)); $$ = (Node *) n; } /* kept for pre-8.3 compatibility */ | CLUSTER opt_verbose name ON qualified_name { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); - n->relation = $5; + n->command = REPACK_COMMAND_CLUSTER; + n->relation = makeNode(VacuumRelation); + n->relation->relation = $5; n->indexname = $3; - n->params = NIL; + n->usingindex = true; if ($2) - n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + n->params = list_make1(makeDefElem("verbose", NULL, @2)); $$ = (Node *) n; } ; @@ -12017,64 +12808,31 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose opt_analyze opt_vacuum_relati } ; -AnalyzeStmt: analyze_keyword opt_verbose opt_vacuum_relation_list +AnalyzeStmt: analyze_keyword opt_utility_option_list opt_vacuum_relation_list { VacuumStmt *n = makeNode(VacuumStmt); - n->options = NIL; - if ($2) - n->options = lappend(n->options, - makeDefElem("verbose", NULL, @2)); + n->options = $2; n->rels = $3; n->is_vacuumcmd = false; $$ = (Node *) n; } - | analyze_keyword '(' utility_option_list ')' opt_vacuum_relation_list + | analyze_keyword VERBOSE opt_vacuum_relation_list { VacuumStmt *n = makeNode(VacuumStmt); - n->options = $3; - n->rels = $5; + n->options = list_make1(makeDefElem("verbose", NULL, @2)); + n->rels = $3; n->is_vacuumcmd = false; $$ = (Node *) n; } ; -utility_option_list: - utility_option_elem - { - $$ = list_make1($1); - } - | utility_option_list ',' utility_option_elem - { - $$ = lappend($1, $3); - } - ; - analyze_keyword: ANALYZE | ANALYSE /* British */ ; -utility_option_elem: - utility_option_name utility_option_arg - { - $$ = makeDefElem($1, $2, @1); - } - ; - -utility_option_name: - NonReservedWord { $$ = $1; } - | analyze_keyword { $$ = "analyze"; } - | FORMAT_LA { $$ = "format"; } - ; - -utility_option_arg: - opt_boolean_or_string { $$ = (Node *) makeString($1); } - | NumericOnly { $$ = (Node *) $1; } - | /* EMPTY */ { $$ = NULL; } - ; - opt_analyze: analyze_keyword { $$ = true; } | /*EMPTY*/ { $$ = false; } @@ -12405,12 +13163,24 @@ insert_column_item: ; opt_on_conflict: + ON CONFLICT opt_conf_expr DO SELECT opt_for_locking_strength where_clause + { + $$ = makeNode(OnConflictClause); + $$->action = ONCONFLICT_SELECT; + $$->infer = $3; + $$->targetList = NIL; + $$->lockStrength = $6; + $$->whereClause = $7; + $$->location = @1; + } + | ON CONFLICT opt_conf_expr DO UPDATE SET set_clause_list where_clause { $$ = makeNode(OnConflictClause); $$->action = ONCONFLICT_UPDATE; $$->infer = $3; $$->targetList = $7; + $$->lockStrength = LCS_NONE; $$->whereClause = $8; $$->location = @1; } @@ -12421,6 +13191,7 @@ opt_on_conflict: $$->action = ONCONFLICT_NOTHING; $$->infer = $3; $$->targetList = NIL; + $$->lockStrength = LCS_NONE; $$->whereClause = NULL; $$->location = @1; } @@ -12516,6 +13287,21 @@ DeleteStmt: opt_with_clause DELETE_P FROM relation_expr_opt_alias n->withClause = $1; $$ = (Node *) n; } + | opt_with_clause DELETE_P FROM relation_expr + for_portion_of_clause for_portion_of_opt_alias + using_clause where_or_current_clause returning_clause + { + DeleteStmt *n = makeNode(DeleteStmt); + + n->relation = $4; + n->forPortionOf = (ForPortionOfClause *) $5; + n->relation->alias = $6; + n->usingClause = $7; + n->whereClause = $8; + n->returningClause = $9; + n->withClause = $1; + $$ = (Node *) n; + } ; using_clause: @@ -12540,6 +13326,25 @@ LockStmt: LOCK_P opt_table relation_expr_list opt_lock opt_nowait n->nowait = $5; $$ = (Node *) n; } + | opt_with_clause UPDATE relation_expr + for_portion_of_clause for_portion_of_opt_alias + SET set_clause_list + from_clause + where_or_current_clause + returning_clause + { + UpdateStmt *n = makeNode(UpdateStmt); + + n->relation = $3; + n->forPortionOf = (ForPortionOfClause *) $4; + n->relation->alias = $5; + n->targetList = $7; + n->fromClause = $8; + n->whereClause = $9; + n->returningClause = $10; + n->withClause = $1; + $$ = (Node *) n; + } ; opt_lock: IN_P lock_type MODE { $$ = $2; } @@ -13356,7 +14161,7 @@ select_limit: } | offset_clause { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = $1; n->limitCount = NULL; @@ -13376,7 +14181,7 @@ opt_select_limit: limit_clause: LIMIT select_limit_value { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = $2; @@ -13404,7 +14209,7 @@ limit_clause: */ | FETCH first_or_next select_fetch_first_value row_or_rows ONLY { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = $3; @@ -13416,7 +14221,7 @@ limit_clause: } | FETCH first_or_next select_fetch_first_value row_or_rows WITH TIES { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = $3; @@ -13428,7 +14233,7 @@ limit_clause: } | FETCH first_or_next row_or_rows ONLY { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = makeIntConst(1, -1); @@ -13440,7 +14245,7 @@ limit_clause: } | FETCH first_or_next row_or_rows WITH TIES { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = makeIntConst(1, -1); @@ -13535,7 +14340,7 @@ first_or_next: FIRST_P { $$ = 0; } group_clause: GROUP_P BY set_quantifier group_by_list { - GroupClause *n = (GroupClause *) palloc(sizeof(GroupClause)); + GroupClause *n = palloc_object(GroupClause); n->distinct = $3 == SET_QUANTIFIER_DISTINCT; n->list = $4; @@ -13543,7 +14348,7 @@ group_clause: } | /*EMPTY*/ { - GroupClause *n = (GroupClause *) palloc(sizeof(GroupClause)); + GroupClause *n = palloc_object(GroupClause); n->distinct = false; n->list = NIL; @@ -13637,6 +14442,11 @@ for_locking_strength: | FOR KEY SHARE { $$ = LCS_FORKEYSHARE; } ; +opt_for_locking_strength: + for_locking_strength { $$ = $1; } + | /* EMPTY */ { $$ = LCS_NONE; } + ; + locked_rels_list: OF qualified_name_list { $$ = $2; } | /* EMPTY */ { $$ = NIL; } @@ -13733,6 +14543,17 @@ table_ref: relation_expr opt_alias_clause n->alias = $3; $$ = (Node *) n; } + | GRAPH_TABLE '(' qualified_name MATCH graph_pattern COLUMNS '(' labeled_expr_list ')' ')' opt_alias_clause + { + RangeGraphTable *n = makeNode(RangeGraphTable); + + n->graph_name = $3; + n->graph_pattern = castNode(GraphPattern, $5); + n->columns = $8; + n->alias = $11; + n->location = @1; + $$ = (Node *) n; + } | select_with_parens opt_alias_clause { RangeSubselect *n = makeNode(RangeSubselect); @@ -14074,6 +14895,55 @@ relation_expr_opt_alias: relation_expr %prec UMINUS } ; +/* + * If an UPDATE/DELETE has FOR PORTION OF, then the relation_expr is separated + * from its potential alias by the for_portion_of_clause. So this production + * handles the potential alias in those cases. We need to solve the same + * problems as relation_expr_opt_alias, in particular resolving a shift/reduce + * conflict where "set set" could be an alias plus the SET keyword, or the SET + * keyword then a column name. As above, we force the latter interpretation by + * giving the non-alias choice a higher precedence. + */ +for_portion_of_opt_alias: + AS ColId + { + Alias *alias = makeNode(Alias); + + alias->aliasname = $2; + $$ = alias; + } + | BareColLabel + { + Alias *alias = makeNode(Alias); + + alias->aliasname = $1; + $$ = alias; + } + | /* empty */ %prec UMINUS { $$ = NULL; } + ; + +for_portion_of_clause: + FOR PORTION OF ColId '(' a_expr ')' + { + ForPortionOfClause *n = makeNode(ForPortionOfClause); + n->range_name = $4; + n->location = @4; + n->target = $6; + n->target_location = @6; + $$ = (Node *) n; + } + | FOR PORTION OF ColId FROM a_expr TO a_expr + { + ForPortionOfClause *n = makeNode(ForPortionOfClause); + n->range_name = $4; + n->location = @4; + n->target_start = $6; + n->target_end = $8; + n->target_location = @5; + $$ = (Node *) n; + } + ; + /* * TABLESAMPLE decoration in a FROM item */ @@ -14914,16 +15784,25 @@ opt_timezone: | /*EMPTY*/ { $$ = false; } ; +/* + * We need to handle this shift/reduce conflict: + * FOR PORTION OF valid_at FROM t + INTERVAL '1' YEAR TO MONTH. + * We don't see far enough ahead to know if there is another TO coming. + * We prefer to interpret this as FROM (t + INTERVAL '1' YEAR TO MONTH), + * i.e. to shift. + * That gives the user the option of adding parentheses to get the other meaning. + * If we reduced, intervals could never have a TO. + */ opt_interval: - YEAR_P + YEAR_P %prec IS { $$ = list_make1(makeIntConst(INTERVAL_MASK(YEAR), @1)); } | MONTH_P { $$ = list_make1(makeIntConst(INTERVAL_MASK(MONTH), @1)); } - | DAY_P + | DAY_P %prec IS { $$ = list_make1(makeIntConst(INTERVAL_MASK(DAY), @1)); } - | HOUR_P + | HOUR_P %prec IS { $$ = list_make1(makeIntConst(INTERVAL_MASK(HOUR), @1)); } - | MINUTE_P + | MINUTE_P %prec IS { $$ = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), @1)); } | interval_second { $$ = $1; } @@ -15084,6 +15963,10 @@ a_expr: c_expr { $$ = $1; } { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $3, @2); } | a_expr NOT_EQUALS a_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, $3, @2); } + | a_expr RIGHT_ARROW a_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "->", $1, $3, @2); } + | a_expr '|' a_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", $1, $3, @2); } | a_expr qual_Op a_expr %prec Op { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); } @@ -15475,7 +16358,7 @@ a_expr: c_expr { $$ = $1; } { JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1); - $$ = makeJsonIsPredicate($1, format, $3, $4, @1); + $$ = makeJsonIsPredicate($1, format, $3, $4, InvalidOid, @1); } /* * Required by SQL/JSON, but there are conflicts @@ -15484,7 +16367,7 @@ a_expr: c_expr { $$ = $1; } IS json_predicate_type_constraint json_key_uniqueness_constraint_opt %prec IS { - $$ = makeJsonIsPredicate($1, $2, $4, $5, @1); + $$ = makeJsonIsPredicate($1, $2, $4, $5, InvalidOid, @1); } */ | a_expr IS NOT @@ -15493,7 +16376,7 @@ a_expr: c_expr { $$ = $1; } { JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1); - $$ = makeNotExpr(makeJsonIsPredicate($1, format, $4, $5, @1), @1); + $$ = makeNotExpr(makeJsonIsPredicate($1, format, $4, $5, InvalidOid, @1), @1); } /* * Required by SQL/JSON, but there are conflicts @@ -15503,7 +16386,7 @@ a_expr: c_expr { $$ = $1; } json_predicate_type_constraint json_key_uniqueness_constraint_opt %prec IS { - $$ = makeNotExpr(makeJsonIsPredicate($1, $2, $5, $6, @1), @1); + $$ = makeNotExpr(makeJsonIsPredicate($1, $2, $5, $6, InvalidOid, @1), @1); } */ | DEFAULT @@ -15564,6 +16447,10 @@ b_expr: c_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $3, @2); } | b_expr NOT_EQUALS b_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, $3, @2); } + | b_expr RIGHT_ARROW b_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "->", $1, $3, @2); } + | b_expr '|' b_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", $1, $3, @2); } | b_expr qual_Op b_expr %prec Op { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); } | qual_Op b_expr %prec Op @@ -15823,7 +16710,7 @@ func_application: func_name '(' ')' * (Note that many of the special SQL functions wouldn't actually make any * sense as functional index entries, but we ignore that consideration here.) */ -func_expr: func_application within_group_clause filter_clause over_clause +func_expr: func_application within_group_clause filter_clause null_treatment over_clause { FuncCall *n = (FuncCall *) $1; @@ -15856,7 +16743,8 @@ func_expr: func_application within_group_clause filter_clause over_clause n->agg_within_group = true; } n->agg_filter = $3; - n->over = $4; + n->ignore_nulls = $4; + n->over = $5; $$ = (Node *) n; } | json_aggregate_func filter_clause over_clause @@ -16145,7 +17033,7 @@ func_expr_common_subexpr: COERCE_SQL_SYNTAX, @1); } - | XMLFOREST '(' xml_attribute_list ')' + | XMLFOREST '(' labeled_expr_list ')' { $$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NIL, @1); } @@ -16370,14 +17258,14 @@ opt_xml_root_standalone: ',' STANDALONE_P YES_P { $$ = makeIntConst(XML_STANDALONE_OMITTED, -1); } ; -xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; } +xml_attributes: XMLATTRIBUTES '(' labeled_expr_list ')' { $$ = $3; } ; -xml_attribute_list: xml_attribute_el { $$ = list_make1($1); } - | xml_attribute_list ',' xml_attribute_el { $$ = lappend($1, $3); } +labeled_expr_list: labeled_expr { $$ = list_make1($1); } + | labeled_expr_list ',' labeled_expr { $$ = lappend($1, $3); } ; -xml_attribute_el: a_expr AS ColLabel +labeled_expr: a_expr AS ColLabel { $$ = makeNode(ResTarget); $$->name = $3; @@ -16434,6 +17322,26 @@ xml_passing_mech: | BY VALUE_P ; +/***************************************************************************** + * + * WAIT FOR LSN + * + *****************************************************************************/ + +WaitStmt: + WAIT FOR LSN_P Sconst opt_wait_with_clause + { + WaitStmt *n = makeNode(WaitStmt); + n->lsn_literal = $4; + n->options = $5; + $$ = (Node *) n; + } + ; + +opt_wait_with_clause: + WITH '(' utility_option_list ')' { $$ = $3; } + | /*EMPTY*/ { $$ = NIL; } + ; /* * Aggregate decoration clauses @@ -16452,6 +17360,12 @@ filter_clause: /* * Window Definitions */ +null_treatment: + IGNORE_P NULLS_P { $$ = PARSER_IGNORE_NULLS; } + | RESPECT_P NULLS_P { $$ = PARSER_RESPECT_NULLS; } + | /*EMPTY*/ { $$ = NO_NULLTREATMENT; } + ; + window_clause: WINDOW window_definition_list { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } @@ -16732,6 +17646,8 @@ MathOp: '+' { $$ = "+"; } | LESS_EQUALS { $$ = "<="; } | GREATER_EQUALS { $$ = ">="; } | NOT_EQUALS { $$ = "<>"; } + | RIGHT_ARROW { $$ = "->"; } + | '|' { $$ = "|"; } ; qual_Op: Op @@ -17312,6 +18228,214 @@ json_array_aggregate_order_by_clause_opt: | /* EMPTY */ { $$ = NIL; } ; + +/***************************************************************************** + * + * graph patterns + * + *****************************************************************************/ + +graph_pattern: + path_pattern_list where_clause + { + GraphPattern *gp = makeNode(GraphPattern); + + gp->path_pattern_list = $1; + gp->whereClause = $2; + $$ = (Node *) gp; + } + ; + +path_pattern_list: + path_pattern { $$ = list_make1($1); } + | path_pattern_list ',' path_pattern { $$ = lappend($1, $3); } + ; + +path_pattern: + path_pattern_expression { $$ = $1; } + ; + +/* + * path pattern expression + */ + +path_pattern_expression: + path_term { $$ = $1; } + /* | path_multiset_alternation */ + /* | path_pattern_union */ + ; + +path_term: + path_factor { $$ = list_make1($1); } + | path_term path_factor { $$ = lappend($1, $2); } + ; + +path_factor: + path_primary opt_graph_pattern_quantifier + { + GraphElementPattern *gep = (GraphElementPattern *) $1; + + gep->quantifier = $2; + + $$ = (Node *) gep; + } + ; + +path_primary: + '(' opt_colid opt_is_label_expression where_clause ')' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = VERTEX_PATTERN; + gep->variable = $2; + gep->labelexpr = $3; + gep->whereClause = $4; + gep->location = @1; + + $$ = (Node *) gep; + } + /* full edge pointing left: <-[ xxx ]- */ + | '<' '-' '[' opt_colid opt_is_label_expression where_clause ']' '-' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_LEFT; + gep->variable = $4; + gep->labelexpr = $5; + gep->whereClause = $6; + gep->location = @1; + + $$ = (Node *) gep; + } + /* full edge pointing right: -[ xxx ]-> */ + | '-' '[' opt_colid opt_is_label_expression where_clause ']' '-' '>' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_RIGHT; + gep->variable = $3; + gep->labelexpr = $4; + gep->whereClause = $5; + gep->location = @1; + + $$ = (Node *) gep; + } + | '-' '[' opt_colid opt_is_label_expression where_clause ']' RIGHT_ARROW + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_RIGHT; + gep->variable = $3; + gep->labelexpr = $4; + gep->whereClause = $5; + gep->location = @1; + + $$ = (Node *) gep; + } + /* full edge any direction: -[ xxx ]- */ + | '-' '[' opt_colid opt_is_label_expression where_clause ']' '-' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_ANY; + gep->variable = $3; + gep->labelexpr = $4; + gep->whereClause = $5; + gep->location = @1; + + $$ = (Node *) gep; + } + /* abbreviated edge patterns */ + | '<' '-' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_LEFT; + gep->location = @1; + + $$ = (Node *) gep; + } + | '-' '>' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_RIGHT; + gep->location = @1; + + $$ = (Node *) gep; + } + | RIGHT_ARROW + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_RIGHT; + gep->location = @1; + + $$ = (Node *) gep; + } + | '-' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_ANY; + gep->location = @1; + + $$ = (Node *) gep; + } + | '(' path_pattern_expression where_clause ')' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = PAREN_EXPR; + gep->subexpr = $2; + gep->whereClause = $3; + gep->location = @1; + + $$ = (Node *) gep; + } + ; + +opt_colid: + ColId { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; + +opt_is_label_expression: + IS label_expression { $$ = $2; } + | /*EMPTY*/ { $$ = NULL; } + ; + +/* + * graph pattern quantifier + */ + +opt_graph_pattern_quantifier: + '{' Iconst '}' { $$ = list_make2_int($2, $2); } + | '{' ',' Iconst '}' { $$ = list_make2_int(0, $3); } + | '{' Iconst ',' Iconst '}' { $$ = list_make2_int($2, $4); } + | /*EMPTY*/ { $$ = NULL; } + ; + +/* + * label expression + */ + +label_expression: + label_term + | label_disjunction + ; + +label_disjunction: + label_expression '|' label_term + { $$ = makeOrExpr($1, $3, @2); } + ; + +label_term: + name + { $$ = makeColumnRef($1, NIL, @1, yyscanner); } + ; + + /***************************************************************************** * * target list for SELECT @@ -17832,6 +18956,7 @@ unreserved_keyword: | DELIMITERS | DEPENDS | DEPTH + | DESTINATION | DETACH | DICTIONARY | DISABLE_P @@ -17841,6 +18966,7 @@ unreserved_keyword: | DOUBLE_P | DROP | EACH + | EDGE | EMPTY_P | ENABLE_P | ENCODING @@ -17871,6 +18997,7 @@ unreserved_keyword: | GENERATED | GLOBAL | GRANTED + | GRAPH | GROUPS | HANDLER | HEADER_P @@ -17878,6 +19005,7 @@ unreserved_keyword: | HOUR_P | IDENTITY_P | IF_P + | IGNORE_P | IMMEDIATE | IMMUTABLE | IMPLICIT_P @@ -17913,6 +19041,7 @@ unreserved_keyword: | LOCK_P | LOCKED | LOGGED + | LSN_P | MAPPING | MATCH | MATCHED @@ -17935,6 +19064,7 @@ unreserved_keyword: | NFKC | NFKD | NO + | NODE | NORMALIZED | NOTHING | NOTIFY @@ -17961,6 +19091,7 @@ unreserved_keyword: | PARSER | PARTIAL | PARTITION + | PARTITIONS | PASSING | PASSWORD | PATH @@ -17968,6 +19099,7 @@ unreserved_keyword: | PLAN | PLANS | POLICY + | PORTION | PRECEDING | PREPARE | PREPARED @@ -17978,6 +19110,8 @@ unreserved_keyword: | PROCEDURE | PROCEDURES | PROGRAM + | PROPERTIES + | PROPERTY | PUBLICATION | QUOTE | QUOTES @@ -17989,13 +19123,16 @@ unreserved_keyword: | REFERENCING | REFRESH | REINDEX + | RELATIONSHIP | RELATIVE_P | RELEASE | RENAME + | REPACK | REPEATABLE | REPLACE | REPLICA | RESET + | RESPECT_P | RESTART | RESTRICT | RETURN @@ -18029,6 +19166,7 @@ unreserved_keyword: | SKIP | SNAPSHOT | SOURCE + | SPLIT | SQL_P | STABLE | STANDALONE_P @@ -18078,10 +19216,12 @@ unreserved_keyword: | VALUE_P | VARYING | VERSION_P + | VERTEX | VIEW | VIEWS | VIRTUAL | VOLATILE + | WAIT | WHITESPACE_P | WITHIN | WITHOUT @@ -18117,6 +19257,7 @@ col_name_keyword: | EXISTS | EXTRACT | FLOAT_P + | GRAPH_TABLE | GREATEST | GROUPING | INOUT @@ -18408,6 +19549,7 @@ bare_label_keyword: | DEPENDS | DEPTH | DESC + | DESTINATION | DETACH | DICTIONARY | DISABLE_P @@ -18419,6 +19561,7 @@ bare_label_keyword: | DOUBLE_P | DROP | EACH + | EDGE | ELSE | EMPTY_P | ENABLE_P @@ -18457,6 +19600,8 @@ bare_label_keyword: | GENERATED | GLOBAL | GRANTED + | GRAPH + | GRAPH_TABLE | GREATEST | GROUPING | GROUPS @@ -18528,6 +19673,7 @@ bare_label_keyword: | LOCK_P | LOCKED | LOGGED + | LSN_P | MAPPING | MATCH | MATCHED @@ -18552,6 +19698,7 @@ bare_label_keyword: | NFKC | NFKD | NO + | NODE | NONE | NORMALIZE | NORMALIZED @@ -18588,6 +19735,7 @@ bare_label_keyword: | PARSER | PARTIAL | PARTITION + | PARTITIONS | PASSING | PASSWORD | PATH @@ -18596,6 +19744,7 @@ bare_label_keyword: | PLAN | PLANS | POLICY + | PORTION | POSITION | PRECEDING | PREPARE @@ -18608,6 +19757,8 @@ bare_label_keyword: | PROCEDURE | PROCEDURES | PROGRAM + | PROPERTIES + | PROPERTY | PUBLICATION | QUOTE | QUOTES @@ -18621,9 +19772,11 @@ bare_label_keyword: | REFERENCING | REFRESH | REINDEX + | RELATIONSHIP | RELATIVE_P | RELEASE | RENAME + | REPACK | REPEATABLE | REPLACE | REPLICA @@ -18668,6 +19821,7 @@ bare_label_keyword: | SNAPSHOT | SOME | SOURCE + | SPLIT | SQL_P | STABLE | STANDALONE_P @@ -18735,10 +19889,12 @@ bare_label_keyword: | VARIADIC | VERBOSE | VERSION_P + | VERTEX | VIEW | VIEWS | VIRTUAL | VOLATILE + | WAIT | WHEN | WHITESPACE_P | WORK @@ -19645,6 +20801,49 @@ parsePartitionStrategy(char *strategy, int location, core_yyscan_t yyscanner) } +/* + * Process all_objects_list to set all_tables and/or all_sequences. + * Also, checks if the pub_object_type has been specified more than once. + */ +static void +preprocess_pub_all_objtype_list(List *all_objects_list, List **pubobjects, + bool *all_tables, bool *all_sequences, + core_yyscan_t yyscanner) +{ + if (!all_objects_list) + return; + + *all_tables = false; + *all_sequences = false; + + foreach_ptr(PublicationAllObjSpec, obj, all_objects_list) + { + if (obj->pubobjtype == PUBLICATION_ALL_TABLES) + { + if (*all_tables) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid publication object list"), + errdetail("ALL TABLES can be specified only once."), + parser_errposition(obj->location)); + + *all_tables = true; + *pubobjects = list_concat(*pubobjects, obj->except_tables); + } + else if (obj->pubobjtype == PUBLICATION_ALL_SEQUENCES) + { + if (*all_sequences) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid publication object list"), + errdetail("ALL SEQUENCES can be specified only once."), + parser_errposition(obj->location)); + + *all_sequences = true; + } + } +} + /* * Process pubobjspec_list to check for errors in any of the objects and * convert PUBLICATIONOBJ_CONTINUATION into appropriate PublicationObjSpecType. diff --git a/src/parser/gram_minimal.y b/src/parser/gram_minimal.y index dc540e1c9..96c7b44a8 100644 --- a/src/parser/gram_minimal.y +++ b/src/parser/gram_minimal.y @@ -6,8 +6,8 @@ * gram.y * POSTGRESQL BISON rules/actions * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -221,7 +221,7 @@ static void doNegateFloat(Float *v); static Node *makeAndExpr(Node *lexpr, Node *rexpr, int location); static Node *makeOrExpr(Node *lexpr, Node *rexpr, int location); static Node *makeNotExpr(Node *expr, int location); -static Node *makeAArrayExpr(List *elements, int location, int end_location); +static Node *makeAArrayExpr(List *elements, int location, int location_end); static Node *makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod, int location); static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, @@ -239,6 +239,11 @@ static void processCASbits(int cas_bits, int location, const char *constrType, bool *not_valid, bool *no_inherit, core_yyscan_t yyscanner); static PartitionStrategy parsePartitionStrategy(char *strategy, int location, core_yyscan_t yyscanner); +static void preprocess_pub_all_objtype_list(List *all_objects_list, + List **pubobjects, + bool *all_tables, + bool *all_sequences, + core_yyscan_t yyscanner); static void preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner); static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); @@ -295,8 +300,10 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); PartitionElem *partelem; PartitionSpec *partspec; PartitionBoundSpec *partboundspec; + SinglePartitionSpec *singlepartspec; RoleSpec *rolespec; PublicationObjSpec *publicationobjectspec; + PublicationAllObjSpec *publicationallobjectspec; struct SelectLimit *selectlimit; SetQuantifier setquantifier; struct GroupClause *groupclause; @@ -318,13 +325,14 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); AlterCompositeTypeStmt AlterUserMappingStmt AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt AlterStatsStmt AlterDefaultPrivilegesStmt DefACLAction - AnalyzeStmt CallStmt ClosePortalStmt ClusterStmt CommentStmt + AnalyzeStmt CallStmt ClosePortalStmt CommentStmt ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt CreateDomainStmt CreateExtensionStmt CreateGroupStmt CreateOpClassStmt CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt CreateSchemaStmt CreateSeqStmt CreateStmt CreateStatsStmt CreateTableSpaceStmt CreateFdwStmt CreateForeignServerStmt CreateForeignTableStmt CreateAssertionStmt CreateTransformStmt CreateTrigStmt CreateEventTrigStmt + CreatePropGraphStmt AlterPropGraphStmt CreateUserStmt CreateUserMappingStmt CreateRoleStmt CreatePolicyStmt CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt DoStmt DropOpClassStmt DropOpFamilyStmt DropStmt @@ -336,14 +344,14 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); InsertStmtShort ListenStmt LoadStmt LockStmt MergeStmt NotifyStmt ExplainableStmt PreparableStmt CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt - RemoveFuncStmt RemoveOperStmt RenameStmt ReturnStmt RevokeStmt RevokeRoleStmt + RemoveFuncStmt RemoveOperStmt RenameStmt RepackStmt ReturnStmt RevokeStmt RevokeRoleStmt RuleActionStmt RuleActionStmtOrEmpty RuleStmt SecLabelStmt SelectStmt TransactionStmt TransactionStmtLegacy TruncateStmt UnlistenStmt UpdateStmt UpdateStmtShort VacuumStmt VariableResetStmt VariableSetStmt VariableShowStmt - ViewStmt CheckPointStmt CreateConversionStmt + ViewStmt WaitStmt CheckPointStmt CreateConversionStmt DeallocateStmt PrepareStmt ExecuteStmt DropOwnedStmt ReassignOwnedStmt AlterTSConfigurationStmt AlterTSDictionaryStmt @@ -357,8 +365,14 @@ UpdateStmtShort %type opt_single_name %type opt_qualified_name -%type opt_concurrently +%type opt_concurrently opt_usingindex %type opt_drop_behavior +%type opt_utility_option_list +%type opt_wait_with_clause +%type utility_option_list +%type utility_option_elem +%type utility_option_name +%type utility_option_arg %type alter_column_default opclass_item opclass_drop alter_using %type add_drop opt_asc_desc opt_nulls_order @@ -379,10 +393,6 @@ UpdateStmtShort create_extension_opt_item alter_extension_opt_item %type opt_lock lock_type cast_context -%type utility_option_name -%type utility_option_elem -%type utility_option_list -%type utility_option_arg %type drop_option %type opt_or_replace opt_no opt_grant_grant_option @@ -486,7 +496,8 @@ UpdateStmtShort transform_element_list transform_type_list TriggerTransitions TriggerReferencing vacuum_relation_list opt_vacuum_relation_list - drop_option_list pub_obj_list + drop_option_list pub_obj_list pub_all_obj_type_list + pub_except_obj_list opt_pub_except_clause %type returning_clause %type returning_option @@ -513,7 +524,7 @@ UpdateStmtShort %type OptNoLog %type OnCommitOption -%type for_locking_strength +%type for_locking_strength opt_for_locking_strength %type for_locking_item %type for_locking_clause opt_for_locking_clause for_locking_items %type locked_rels_list @@ -588,6 +599,8 @@ UpdateStmtShort %type relation_expr %type extended_relation_expr %type relation_expr_opt_alias +%type for_portion_of_opt_alias +%type for_portion_of_clause %type tablesample_clause opt_repeatable_clause %type target_el set_target insert_column_item @@ -597,7 +610,6 @@ UpdateStmtShort %type generic_option_list alter_generic_option_list %type reindex_target_relation reindex_target_all -%type opt_reindex_option_list %type copy_generic_opt_arg copy_generic_opt_arg_list_item %type copy_generic_opt_elem @@ -625,6 +637,8 @@ UpdateStmtShort %type var_value zone_value %type auth_ident RoleSpec opt_granted_by %type PublicationObjSpec +%type PublicationExceptObjSpec +%type PublicationAllObjSpec %type unreserved_keyword type_func_name_keyword %type col_name_keyword reserved_keyword @@ -649,8 +663,8 @@ UpdateStmtShort %type opt_provider security_label -%type xml_attribute_el -%type xml_attribute_list xml_attributes +%type labeled_expr +%type labeled_expr_list xml_attributes %type xml_root_version opt_xml_root_standalone %type xmlexists_argument %type document_or_content @@ -672,7 +686,7 @@ UpdateStmtShort %type window_clause window_definition_list opt_partition_clause %type window_definition over_clause window_specification opt_frame_clause frame_extent frame_bound -%type opt_window_exclusion_clause +%type null_treatment opt_window_exclusion_clause %type opt_existing_window_name %type opt_if_not_exists %type opt_unique_null_treatment @@ -681,6 +695,8 @@ UpdateStmtShort %type part_elem %type part_params %type PartitionBoundSpec +%type SinglePartitionSpec +%type partitions_list %type hash_partbound %type hash_partbound_elem @@ -712,6 +728,35 @@ UpdateStmtShort json_object_constructor_null_clause_opt json_array_constructor_null_clause_opt +%type vertex_tables_clause edge_tables_clause + opt_vertex_tables_clause opt_edge_tables_clause + vertex_table_list + opt_graph_table_key_clause + edge_table_list + source_vertex_table destination_vertex_table + opt_element_table_label_and_properties + label_and_properties_list + add_label_list +%type vertex_table_definition edge_table_definition +%type opt_propgraph_table_alias +%type element_table_label_clause +%type label_and_properties element_table_properties + add_label +%type vertex_or_edge + +%type opt_graph_pattern_quantifier + path_pattern_list + path_pattern + path_pattern_expression + path_term +%type graph_pattern + path_factor + path_primary + opt_is_label_expression + label_expression + label_disjunction + label_term +%type opt_colid /* * Non-keyword token types. These are hard-wired into the "flex" lexer. @@ -755,22 +800,22 @@ UpdateStmtShort CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS - DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC + DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC DESTINATION DETACH DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP - EACH ELSE EMPTY_P ENABLE_P ENCODING ENCRYPTED END_P ENFORCED ENUM_P ERROR_P - ESCAPE EVENT EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN - EXPRESSION EXTENSION EXTERNAL EXTRACT + EACH EDGE ELSE EMPTY_P ENABLE_P ENCODING ENCRYPTED END_P ENFORCED ENUM_P + ERROR_P ESCAPE EVENT EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS + EXPLAIN EXPRESSION EXTENSION EXTERNAL EXTRACT FALSE_P FAMILY FETCH FILTER FINALIZE FIRST_P FLOAT_P FOLLOWING FOR FORCE FOREIGN FORMAT FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS - GENERATED GLOBAL GRANT GRANTED GREATEST GROUP_P GROUPING GROUPS + GENERATED GLOBAL GRANT GRANTED GRAPH GRAPH_TABLE GREATEST GROUP_P GROUPING GROUPS HANDLER HAVING HEADER_P HOLD HOUR_P - IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE + IDENTITY_P IF_P IGNORE_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE INCLUDING INCREMENT INDENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION @@ -782,12 +827,12 @@ UpdateStmtShort LABEL LANGUAGE LARGE_P LAST_P LATERAL_P LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL - LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOGGED + LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOGGED LSN_P MAPPING MATCH MATCHED MATERIALIZED MAXVALUE MERGE MERGE_ACTION METHOD MINUTE_P MINVALUE MODE MONTH_P MOVE - NAME_P NAMES NATIONAL NATURAL NCHAR NESTED NEW NEXT NFC NFD NFKC NFKD NO + NAME_P NAMES NATIONAL NATURAL NCHAR NESTED NEW NEXT NFC NFD NFKC NFKD NO NODE NONE NORMALIZE NORMALIZED NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NULLS_P NUMERIC @@ -796,22 +841,22 @@ UpdateStmtShort ORDER ORDINALITY OTHERS OUT_P OUTER_P OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER - PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD PATH PGPOOL - PERIOD PLACING PLAN PLANS POLICY + PARALLEL PARAMETER PARSER PARTIAL PARTITION PARTITIONS PASSING PASSWORD PATH PGPOOL + PERIOD PLACING PLAN PLANS POLICY PORTION POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY - PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION + PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PROPERTIES PROPERTY PUBLICATION QUOTE QUOTES RANGE READ REAL REASSIGN RECURSIVE REF_P REFERENCES REFERENCING - REFRESH REINDEX RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA - RESET RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP + REFRESH REINDEX RELATIONSHIP RELATIVE_P RELEASE RENAME REPACK REPEATABLE REPLACE REPLICA + RESET RESPECT_P RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP ROUTINE ROUTINES ROW ROWS RULE SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW - SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SOURCE SQL_P STABLE STANDALONE_P + SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SPLIT SOURCE SQL_P STABLE STANDALONE_P START STATEMENT STATISTICS STDIN STDOUT STORAGE STORED STRICT_P STRING_P STRIP_P SUBSCRIPTION SUBSTRING SUPPORT SYMMETRIC SYSID SYSTEM_P SYSTEM_USER @@ -824,9 +869,9 @@ UpdateStmtShort UNLISTEN UNLOGGED UNTIL UPDATE USER USING VACUUM VALID VALIDATE VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING - VERBOSE VERSION_P VIEW VIEWS VIRTUAL VOLATILE + VERBOSE VERSION_P VERTEX VIEW VIEWS VIRTUAL VOLATILE - WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE + WAIT WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE @@ -916,13 +961,16 @@ UpdateStmtShort * json_predicate_type_constraint and json_key_uniqueness_constraint_opt * productions (see comments there). * + * TO is assigned the same precedence as IDENT, to support the opt_interval + * production (see comment there). + * * Like the UNBOUNDED PRECEDING/FOLLOWING case, NESTED is assigned a lower * precedence than PATH to fix ambiguity in the json_table production. */ %nonassoc UNBOUNDED NESTED /* ideally would have same precedence as IDENT */ %nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP - SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT PATH -%left Op OPERATOR /* multi-character ops and user-defined operators */ + SET KEYS OBJECT_P SCALAR TO USING VALUE_P WITH WITHOUT PATH +%left Op OPERATOR RIGHT_ARROW '|' /* multi-character ops and user-defined operators */ %left '+' '-' %left '*' '/' '%' %left '^' @@ -1049,6 +1097,7 @@ stmt: | AlterOperatorStmt | AlterTypeStmt | AlterPolicyStmt + | AlterPropGraphStmt | AlterSeqStmt | AlterSystemStmt | AlterTableStmt @@ -1066,7 +1115,6 @@ stmt: | CallStmt | CheckPointStmt | ClosePortalStmt - | ClusterStmt | CommentStmt | ConstraintsSetStmt | CopyStmt @@ -1089,6 +1137,7 @@ stmt: | AlterOpFamilyStmt | CreatePolicyStmt | CreatePLangStmt + | CreatePropGraphStmt | CreateSchemaStmt | CreateSeqStmt | CreateStmt @@ -1140,6 +1189,7 @@ stmt: | RemoveFuncStmt | RemoveOperStmt | RenameStmt + | RepackStmt | RevokeStmt | RevokeRoleStmt | RuleStmt @@ -1154,6 +1204,7 @@ stmt: | VariableSetStmt | VariableShowStmt | ViewStmt + | WaitStmt | /*EMPTY*/ { $$ = NULL; } ; @@ -1176,12 +1227,52 @@ opt_concurrently: | /*EMPTY*/ { $$ = false; } ; +opt_usingindex: + USING INDEX { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; + opt_drop_behavior: CASCADE { $$ = DROP_CASCADE; } | RESTRICT { $$ = DROP_RESTRICT; } | /* EMPTY */ { $$ = DROP_RESTRICT; /* default */ } ; +opt_utility_option_list: + '(' utility_option_list ')' { $$ = $2; } + | /* EMPTY */ { $$ = NULL; } + ; + +utility_option_list: + utility_option_elem + { + $$ = list_make1($1); + } + | utility_option_list ',' utility_option_elem + { + $$ = lappend($1, $3); + } + ; + +utility_option_elem: + utility_option_name utility_option_arg + { + $$ = makeDefElem($1, $2, @1); + } + ; + +utility_option_name: + NonReservedWord { $$ = $1; } + | analyze_keyword { $$ = "analyze"; } + | FORMAT_LA { $$ = "format"; } + ; + +utility_option_arg: + opt_boolean_or_string { $$ = (Node *) makeString($1); } + | NumericOnly { $$ = (Node *) $1; } + | /* EMPTY */ { $$ = NULL; } + ; + /***************************************************************************** * * CALL statement @@ -1628,8 +1719,11 @@ OptSchemaEltList: schema_stmt: CreateStmt | IndexStmt + | CreateDomainStmt + | CreateFunctionStmt | CreateSeqStmt | CreateTrigStmt + | DefineStmt | GrantStmt | ViewStmt ; @@ -1729,6 +1823,26 @@ generic_set: n->location = @3; $$ = n; } + | var_name TO NULL_P + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = $1; + n->args = list_make1(makeNullAConst(@3)); + n->location = @3; + $$ = n; + } + | var_name '=' NULL_P + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = $1; + n->args = list_make1(makeNullAConst(@3)); + n->location = @3; + $$ = n; + } | var_name TO DEFAULT { VariableSetStmt *n = makeNode(VariableSetStmt); @@ -2109,11 +2223,12 @@ constraints_set_mode: * Checkpoint statement */ CheckPointStmt: - CHECKPOINT + CHECKPOINT opt_utility_option_list { CheckPointStmt *n = makeNode(CheckPointStmt); $$ = (Node *) n; + n->options = $2; } ; @@ -2402,6 +2517,23 @@ alter_table_cmds: | alter_table_cmds ',' alter_table_cmd { $$ = lappend($1, $3); } ; +partitions_list: + SinglePartitionSpec { $$ = list_make1($1); } + | partitions_list ',' SinglePartitionSpec { $$ = lappend($1, $3); } + ; + +SinglePartitionSpec: + PARTITION qualified_name PartitionBoundSpec + { + SinglePartitionSpec *n = makeNode(SinglePartitionSpec); + + n->name = $2; + n->bound = $3; + + $$ = n; + } + ; + partition_cmd: /* ALTER TABLE ATTACH PARTITION FOR VALUES */ ATTACH PARTITION qualified_name PartitionBoundSpec @@ -2412,6 +2544,7 @@ partition_cmd: n->subtype = AT_AttachPartition; cmd->name = $3; cmd->bound = $4; + cmd->partlist = NIL; cmd->concurrent = false; n->def = (Node *) cmd; @@ -2426,6 +2559,7 @@ partition_cmd: n->subtype = AT_DetachPartition; cmd->name = $3; cmd->bound = NULL; + cmd->partlist = NIL; cmd->concurrent = $4; n->def = (Node *) cmd; @@ -2439,6 +2573,35 @@ partition_cmd: n->subtype = AT_DetachPartitionFinalize; cmd->name = $3; cmd->bound = NULL; + cmd->partlist = NIL; + cmd->concurrent = false; + n->def = (Node *) cmd; + $$ = (Node *) n; + } + /* ALTER TABLE SPLIT PARTITION INTO () */ + | SPLIT PARTITION qualified_name INTO '(' partitions_list ')' + { + AlterTableCmd *n = makeNode(AlterTableCmd); + PartitionCmd *cmd = makeNode(PartitionCmd); + + n->subtype = AT_SplitPartition; + cmd->name = $3; + cmd->bound = NULL; + cmd->partlist = $6; + cmd->concurrent = false; + n->def = (Node *) cmd; + $$ = (Node *) n; + } + /* ALTER TABLE MERGE PARTITIONS () INTO */ + | MERGE PARTITIONS '(' qualified_name_list ')' INTO qualified_name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + PartitionCmd *cmd = makeNode(PartitionCmd); + + n->subtype = AT_MergePartitions; + cmd->name = $7; + cmd->bound = NULL; + cmd->partlist = $4; cmd->concurrent = false; n->def = (Node *) cmd; $$ = (Node *) n; @@ -2455,6 +2618,7 @@ index_partition_cmd: n->subtype = AT_AttachPartition; cmd->name = $3; cmd->bound = NULL; + cmd->partlist = NIL; cmd->concurrent = false; n->def = (Node *) cmd; @@ -3445,7 +3609,7 @@ ClosePortalStmt: * COPY ( query ) TO file [WITH] [(options)] * * where 'query' can be one of: - * { SELECT | UPDATE | INSERT | DELETE } + * { SELECT | UPDATE | INSERT | DELETE | MERGE } * * and 'file' can be one of: * { PROGRAM 'command' | STDIN | STDOUT | 'filename' } @@ -3486,6 +3650,7 @@ CopyStmt: COPY opt_binary qualified_name opt_column_list ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("WHERE clause not allowed with COPY TO"), + errhint("Try the COPY (SELECT ... WHERE ...) TO variant."), parser_errposition(@11))); n->options = NIL; @@ -3572,6 +3737,10 @@ copy_opt_item: { $$ = makeDefElem("format", (Node *) makeString("csv"), @1); } + | JSON + { + $$ = makeDefElem("format", (Node *) makeString("json"), @1); + } | HEADER_P { $$ = makeDefElem("header", (Node *) makeBoolean(true), @1); @@ -3654,6 +3823,10 @@ copy_generic_opt_elem: { $$ = makeDefElem($1, $2, @1); } + | FORMAT_LA copy_generic_opt_arg + { + $$ = makeDefElem("format", $2, @1); + } ; copy_generic_opt_arg: @@ -4572,19 +4745,19 @@ OptWhereClause: key_actions: key_update { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); n->updateAction = $1; - n->deleteAction = palloc(sizeof(KeyAction)); + n->deleteAction = palloc_object(KeyAction); n->deleteAction->action = FKCONSTR_ACTION_NOACTION; n->deleteAction->cols = NIL; $$ = n; } | key_delete { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); - n->updateAction = palloc(sizeof(KeyAction)); + n->updateAction = palloc_object(KeyAction); n->updateAction->action = FKCONSTR_ACTION_NOACTION; n->updateAction->cols = NIL; n->deleteAction = $1; @@ -4592,7 +4765,7 @@ key_actions: } | key_update key_delete { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); n->updateAction = $1; n->deleteAction = $2; @@ -4600,7 +4773,7 @@ key_actions: } | key_delete key_update { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); n->updateAction = $2; n->deleteAction = $1; @@ -4608,12 +4781,12 @@ key_actions: } | /*EMPTY*/ { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); - n->updateAction = palloc(sizeof(KeyAction)); + n->updateAction = palloc_object(KeyAction); n->updateAction->action = FKCONSTR_ACTION_NOACTION; n->updateAction->cols = NIL; - n->deleteAction = palloc(sizeof(KeyAction)); + n->deleteAction = palloc_object(KeyAction); n->deleteAction->action = FKCONSTR_ACTION_NOACTION; n->deleteAction->cols = NIL; $$ = n; @@ -4641,7 +4814,7 @@ key_delete: ON DELETE_P key_action key_action: NO ACTION { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_NOACTION; n->cols = NIL; @@ -4649,7 +4822,7 @@ key_action: } | RESTRICT { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_RESTRICT; n->cols = NIL; @@ -4657,7 +4830,7 @@ key_action: } | CASCADE { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_CASCADE; n->cols = NIL; @@ -4665,7 +4838,7 @@ key_action: } | SET NULL_P opt_column_list { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_SETNULL; n->cols = $3; @@ -4673,7 +4846,7 @@ key_action: } | SET DEFAULT opt_column_list { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_SETDEFAULT; n->cols = $3; @@ -5545,6 +5718,8 @@ fdw_option: | NO HANDLER { $$ = makeDefElem("handler", NULL, @1); } | VALIDATOR handler_name { $$ = makeDefElem("validator", (Node *) $2, @1); } | NO VALIDATOR { $$ = makeDefElem("validator", NULL, @1); } + | CONNECTION handler_name { $$ = makeDefElem("connection", (Node *) $2, @1); } + | NO CONNECTION { $$ = makeDefElem("connection", NULL, @1); } ; fdw_options: @@ -5870,7 +6045,7 @@ import_qualification_type: import_qualification: import_qualification_type '(' relation_expr_list ')' { - ImportQual *n = (ImportQual *) palloc(sizeof(ImportQual)); + ImportQual *n = palloc_object(ImportQual); n->type = $1; n->table_names = $3; @@ -5878,7 +6053,7 @@ import_qualification: } | /*EMPTY*/ { - ImportQual *n = (ImportQual *) palloc(sizeof(ImportQual)); + ImportQual *n = palloc_object(ImportQual); n->type = FDW_IMPORT_SCHEMA_ALL; n->table_names = NIL; $$ = n; @@ -6123,6 +6298,26 @@ CreateTrigStmt: EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')' { CreateTrigStmt *n = makeNode(CreateTrigStmt); + bool dummy; + + if (($11 & CAS_NOT_VALID) != 0) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constraint triggers cannot be marked %s", + "NOT VALID"), + parser_errposition(@11)); + if (($11 & CAS_NO_INHERIT) != 0) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constraint triggers cannot be marked %s", + "NO INHERIT"), + parser_errposition(@11)); + if (($11 & CAS_NOT_ENFORCED) != 0) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constraint triggers cannot be marked %s", + "NOT ENFORCED"), + parser_errposition(@11)); n->replace = $2; if (n->replace) /* not supported, see CreateTrigger */ @@ -6142,7 +6337,7 @@ CreateTrigStmt: n->whenClause = $15; n->transitionRels = NIL; processCASbits($11, @11, "TRIGGER", - &n->deferrable, &n->initdeferred, NULL, + &n->deferrable, &n->initdeferred, &dummy, NULL, NULL, yyscanner); n->constrrel = $10; $$ = (Node *) n; @@ -7137,6 +7332,7 @@ object_type_any_name: | MATERIALIZED VIEW { $$ = OBJECT_MATVIEW; } | INDEX { $$ = OBJECT_INDEX; } | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; } + | PROPERTY GRAPH { $$ = OBJECT_PROPGRAPH; } | COLLATION { $$ = OBJECT_COLLATION; } | CONVERSION_P { $$ = OBJECT_CONVERSION; } | STATISTICS { $$ = OBJECT_STATISTIC_EXT; } @@ -7565,6 +7761,8 @@ fetch_args: cursor_name n->portalname = $1; n->direction = FETCH_FORWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_NONE; $$ = (Node *) n; } | from_in cursor_name @@ -7574,6 +7772,19 @@ fetch_args: cursor_name n->portalname = $2; n->direction = FETCH_FORWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_NONE; + $$ = (Node *) n; + } + | SignedIconst opt_from_in cursor_name + { + FetchStmt *n = makeNode(FetchStmt); + + n->portalname = $3; + n->direction = FETCH_FORWARD; + n->howMany = $1; + n->location = @1; + n->direction_keyword = FETCH_KEYWORD_NONE; $$ = (Node *) n; } | NEXT opt_from_in cursor_name @@ -7583,6 +7794,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_NEXT; $$ = (Node *) n; } | PRIOR opt_from_in cursor_name @@ -7592,6 +7805,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_BACKWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_PRIOR; $$ = (Node *) n; } | FIRST_P opt_from_in cursor_name @@ -7601,6 +7816,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_ABSOLUTE; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_FIRST; $$ = (Node *) n; } | LAST_P opt_from_in cursor_name @@ -7610,6 +7827,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_ABSOLUTE; n->howMany = -1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_LAST; $$ = (Node *) n; } | ABSOLUTE_P SignedIconst opt_from_in cursor_name @@ -7619,6 +7838,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_ABSOLUTE; n->howMany = $2; + n->location = @2; + n->direction_keyword = FETCH_KEYWORD_ABSOLUTE; $$ = (Node *) n; } | RELATIVE_P SignedIconst opt_from_in cursor_name @@ -7628,15 +7849,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_RELATIVE; n->howMany = $2; - $$ = (Node *) n; - } - | SignedIconst opt_from_in cursor_name - { - FetchStmt *n = makeNode(FetchStmt); - - n->portalname = $3; - n->direction = FETCH_FORWARD; - n->howMany = $1; + n->location = @2; + n->direction_keyword = FETCH_KEYWORD_RELATIVE; $$ = (Node *) n; } | ALL opt_from_in cursor_name @@ -7646,6 +7860,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = FETCH_ALL; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_ALL; $$ = (Node *) n; } | FORWARD opt_from_in cursor_name @@ -7655,6 +7871,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_FORWARD; $$ = (Node *) n; } | FORWARD SignedIconst opt_from_in cursor_name @@ -7664,6 +7882,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_FORWARD; n->howMany = $2; + n->location = @2; + n->direction_keyword = FETCH_KEYWORD_FORWARD; $$ = (Node *) n; } | FORWARD ALL opt_from_in cursor_name @@ -7673,6 +7893,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_FORWARD; n->howMany = FETCH_ALL; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_FORWARD_ALL; $$ = (Node *) n; } | BACKWARD opt_from_in cursor_name @@ -7682,6 +7904,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_BACKWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_BACKWARD; $$ = (Node *) n; } | BACKWARD SignedIconst opt_from_in cursor_name @@ -7691,6 +7915,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_BACKWARD; n->howMany = $2; + n->location = @2; + n->direction_keyword = FETCH_KEYWORD_BACKWARD; $$ = (Node *) n; } | BACKWARD ALL opt_from_in cursor_name @@ -7700,6 +7926,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_BACKWARD; n->howMany = FETCH_ALL; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_BACKWARD_ALL; $$ = (Node *) n; } ; @@ -7879,7 +8107,7 @@ parameter_name: privilege_target: qualified_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TABLE; @@ -7888,7 +8116,7 @@ privilege_target: } | TABLE qualified_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TABLE; @@ -7897,7 +8125,7 @@ privilege_target: } | SEQUENCE qualified_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_SEQUENCE; @@ -7906,7 +8134,7 @@ privilege_target: } | FOREIGN DATA_P WRAPPER name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_FDW; @@ -7915,7 +8143,7 @@ privilege_target: } | FOREIGN SERVER name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_FOREIGN_SERVER; @@ -7924,7 +8152,7 @@ privilege_target: } | FUNCTION function_with_argtypes_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_FUNCTION; @@ -7933,7 +8161,7 @@ privilege_target: } | PROCEDURE function_with_argtypes_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_PROCEDURE; @@ -7942,7 +8170,7 @@ privilege_target: } | ROUTINE function_with_argtypes_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_ROUTINE; @@ -7951,7 +8179,7 @@ privilege_target: } | DATABASE name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_DATABASE; @@ -7960,7 +8188,7 @@ privilege_target: } | DOMAIN_P any_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_DOMAIN; @@ -7969,7 +8197,7 @@ privilege_target: } | LANGUAGE name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_LANGUAGE; @@ -7978,7 +8206,7 @@ privilege_target: } | LARGE_P OBJECT_P NumericOnly_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_LARGEOBJECT; @@ -7987,15 +8215,24 @@ privilege_target: } | PARAMETER parameter_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_PARAMETER_ACL; n->objs = $2; $$ = n; } + | PROPERTY GRAPH qualified_name_list + { + PrivTarget *n = palloc_object(PrivTarget); + + n->targtype = ACL_TARGET_OBJECT; + n->objtype = OBJECT_PROPGRAPH; + n->objs = $3; + $$ = n; + } | SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_SCHEMA; @@ -8004,7 +8241,7 @@ privilege_target: } | TABLESPACE name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TABLESPACE; @@ -8013,7 +8250,7 @@ privilege_target: } | TYPE_P any_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TYPE; @@ -8022,7 +8259,7 @@ privilege_target: } | ALL TABLES IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_TABLE; @@ -8031,7 +8268,7 @@ privilege_target: } | ALL SEQUENCES IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_SEQUENCE; @@ -8040,7 +8277,7 @@ privilege_target: } | ALL FUNCTIONS IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_FUNCTION; @@ -8049,7 +8286,7 @@ privilege_target: } | ALL PROCEDURES IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_PROCEDURE; @@ -8058,7 +8295,7 @@ privilege_target: } | ALL ROUTINES IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_ROUTINE; @@ -8367,6 +8604,7 @@ index_elem_options: $$->opclassopts = NIL; $$->ordering = $3; $$->nulls_ordering = $4; + /* location will be filled in index_elem production */ } | opt_collate any_name reloptions opt_asc_desc opt_nulls_order { @@ -8379,6 +8617,7 @@ index_elem_options: $$->opclassopts = $3; $$->ordering = $4; $$->nulls_ordering = $5; + /* location will be filled in index_elem production */ } ; @@ -8391,16 +8630,19 @@ index_elem: ColId index_elem_options { $$ = $2; $$->name = $1; + $$->location = @1; } | func_expr_windowless index_elem_options { $$ = $2; $$->expr = $1; + $$->location = @1; } | '(' a_expr ')' index_elem_options { $$ = $4; $$->expr = $2; + $$->location = @1; } ; @@ -9317,6 +9559,370 @@ opt_if_exists: IF_P EXISTS { $$ = true; } ; +/***************************************************************************** + * + * CREATE PROPERTY GRAPH + * ALTER PROPERTY GRAPH + * + *****************************************************************************/ + +CreatePropGraphStmt: CREATE OptTemp PROPERTY GRAPH qualified_name opt_vertex_tables_clause opt_edge_tables_clause + { + CreatePropGraphStmt *n = makeNode(CreatePropGraphStmt); + + n->pgname = $5; + n->pgname->relpersistence = $2; + n->vertex_tables = $6; + n->edge_tables = $7; + + $$ = (Node *)n; + } + ; + +opt_vertex_tables_clause: + vertex_tables_clause { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +vertex_tables_clause: + vertex_synonym TABLES '(' vertex_table_list ')' { $$ = $4; } + ; + +vertex_synonym: NODE | VERTEX + ; + +vertex_table_list: vertex_table_definition { $$ = list_make1($1); } + | vertex_table_list ',' vertex_table_definition { $$ = lappend($1, $3); } + ; + +vertex_table_definition: qualified_name opt_propgraph_table_alias opt_graph_table_key_clause + opt_element_table_label_and_properties + { + PropGraphVertex *n = makeNode(PropGraphVertex); + + $1->alias = $2; + n->vtable = $1; + n->vkey = $3; + n->labels = $4; + n->location = @1; + + $$ = (Node *) n; + } + ; + +opt_propgraph_table_alias: + AS name + { + $$ = makeNode(Alias); + $$->aliasname = $2; + } + | /*EMPTY*/ { $$ = NULL; } + ; + +opt_graph_table_key_clause: + KEY '(' columnList ')' { $$ = $3; } + | /*EMPTY*/ { $$ = NIL; } + ; + +opt_edge_tables_clause: + edge_tables_clause { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +edge_tables_clause: + edge_synonym TABLES '(' edge_table_list ')' { $$ = $4; } + ; + +edge_synonym: EDGE | RELATIONSHIP + ; + +edge_table_list: edge_table_definition { $$ = list_make1($1); } + | edge_table_list ',' edge_table_definition { $$ = lappend($1, $3); } + ; + +edge_table_definition: qualified_name opt_propgraph_table_alias opt_graph_table_key_clause + source_vertex_table destination_vertex_table opt_element_table_label_and_properties + { + PropGraphEdge *n = makeNode(PropGraphEdge); + + $1->alias = $2; + n->etable = $1; + n->ekey = $3; + n->esrckey = linitial($4); + n->esrcvertex = lsecond($4); + n->esrcvertexcols = lthird($4); + n->edestkey = linitial($5); + n->edestvertex = lsecond($5); + n->edestvertexcols = lthird($5); + n->labels = $6; + n->location = @1; + + $$ = (Node *) n; + } + ; + +source_vertex_table: SOURCE name + { + $$ = list_make3(NULL, $2, NULL); + } + | SOURCE KEY '(' columnList ')' REFERENCES name '(' columnList ')' + { + $$ = list_make3($4, $7, $9); + } + ; + +destination_vertex_table: DESTINATION name + { + $$ = list_make3(NULL, $2, NULL); + } + | DESTINATION KEY '(' columnList ')' REFERENCES name '(' columnList ')' + { + $$ = list_make3($4, $7, $9); + } + ; + +opt_element_table_label_and_properties: + element_table_properties + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + + lp->properties = (PropGraphProperties *) $1; + lp->location = @1; + + $$ = list_make1(lp); + } + | label_and_properties_list + { + $$ = $1; + } + | /*EMPTY*/ + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->all = true; + pr->location = -1; + lp->properties = pr; + lp->location = -1; + + $$ = list_make1(lp); + } + ; + +element_table_properties: + NO PROPERTIES + { + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->properties = NIL; + pr->location = @1; + + $$ = (Node *) pr; + } + | PROPERTIES ALL COLUMNS + /* + * SQL standard also allows "PROPERTIES ARE ALL COLUMNS", but that + * would require making ARE a keyword, which seems a bit much for + * such a marginal use. Could be added later if needed. + */ + { + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->all = true; + pr->location = @1; + + $$ = (Node *) pr; + } + | PROPERTIES '(' labeled_expr_list ')' + { + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->properties = $3; + pr->location = @1; + + $$ = (Node *) pr; + } + ; + +label_and_properties_list: + label_and_properties + { + $$ = list_make1($1); + } + | label_and_properties_list label_and_properties + { + $$ = lappend($1, $2); + } + ; + +label_and_properties: + element_table_label_clause + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->all = true; + pr->location = -1; + + lp->label = $1; + lp->properties = pr; + lp->location = @1; + + $$ = (Node *) lp; + } + | element_table_label_clause element_table_properties + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + + lp->label = $1; + lp->properties = (PropGraphProperties *) $2; + lp->location = @1; + + $$ = (Node *) lp; + } + ; + +element_table_label_clause: + LABEL name + { + $$ = $2; + } + | DEFAULT LABEL + { + $$ = NULL; + } + ; + +AlterPropGraphStmt: + ALTER PROPERTY GRAPH qualified_name ADD_P vertex_tables_clause + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->add_vertex_tables = $6; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ADD_P vertex_tables_clause ADD_P edge_tables_clause + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->add_vertex_tables = $6; + n->add_edge_tables = $8; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ADD_P edge_tables_clause + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->add_edge_tables = $6; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name DROP vertex_synonym TABLES '(' name_list ')' opt_drop_behavior + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->drop_vertex_tables = $9; + n->drop_behavior = $11; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name DROP edge_synonym TABLES '(' name_list ')' opt_drop_behavior + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->drop_edge_tables = $9; + n->drop_behavior = $11; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ALTER vertex_or_edge TABLE name + add_label_list + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->element_kind = $6; + n->element_alias = $8; + n->add_labels = $9; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ALTER vertex_or_edge TABLE name + DROP LABEL name opt_drop_behavior + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->element_kind = $6; + n->element_alias = $8; + n->drop_label = $11; + n->drop_behavior = $12; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ALTER vertex_or_edge TABLE name + ALTER LABEL name ADD_P PROPERTIES '(' labeled_expr_list ')' + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + PropGraphProperties *pr = makeNode(PropGraphProperties); + + n->pgname = $4; + n->element_kind = $6; + n->element_alias = $8; + n->alter_label = $11; + + pr->properties = $15; + pr->location = @13; + n->add_properties = pr; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ALTER vertex_or_edge TABLE name + ALTER LABEL name DROP PROPERTIES '(' name_list ')' opt_drop_behavior + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->element_kind = $6; + n->element_alias = $8; + n->alter_label = $11; + n->drop_properties = $15; + n->drop_behavior = $17; + + $$ = (Node *) n; + } + ; + +vertex_or_edge: + vertex_synonym { $$ = PROPGRAPH_ELEMENT_KIND_VERTEX; } + | edge_synonym { $$ = PROPGRAPH_ELEMENT_KIND_EDGE; } + ; + +add_label_list: + add_label { $$ = list_make1($1); } + | add_label_list add_label { $$ = lappend($1, $2); } + ; + +add_label: ADD_P LABEL name element_table_properties + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + + lp->label = $3; + lp->properties = (PropGraphProperties *) $4; + lp->location = @1; + + $$ = (Node *) lp; + } + ; + + /***************************************************************************** * * CREATE TRANSFORM / DROP TRANSFORM @@ -9377,7 +9983,7 @@ DropTransformStmt: DROP TRANSFORM opt_if_exists FOR Typename LANGUAGE name opt_d *****************************************************************************/ ReindexStmt: - REINDEX opt_reindex_option_list reindex_target_relation opt_concurrently qualified_name + REINDEX opt_utility_option_list reindex_target_relation opt_concurrently qualified_name { ReindexStmt *n = makeNode(ReindexStmt); @@ -9390,7 +9996,7 @@ ReindexStmt: makeDefElem("concurrently", NULL, @4)); $$ = (Node *) n; } - | REINDEX opt_reindex_option_list SCHEMA opt_concurrently name + | REINDEX opt_utility_option_list SCHEMA opt_concurrently name { ReindexStmt *n = makeNode(ReindexStmt); @@ -9403,7 +10009,7 @@ ReindexStmt: makeDefElem("concurrently", NULL, @4)); $$ = (Node *) n; } - | REINDEX opt_reindex_option_list reindex_target_all opt_concurrently opt_single_name + | REINDEX opt_utility_option_list reindex_target_all opt_concurrently opt_single_name { ReindexStmt *n = makeNode(ReindexStmt); @@ -9425,10 +10031,6 @@ reindex_target_all: SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; } | DATABASE { $$ = REINDEX_OBJECT_DATABASE; } ; -opt_reindex_option_list: - '(' utility_option_list ')' { $$ = $2; } - | /* EMPTY */ { $$ = NULL; } - ; /***************************************************************************** * @@ -9617,6 +10219,16 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name n->missing_ok = false; $$ = (Node *) n; } + | ALTER PROPERTY GRAPH qualified_name RENAME TO name + { + RenameStmt *n = makeNode(RenameStmt); + + n->renameType = OBJECT_PROPGRAPH; + n->relation = $4; + n->newname = $7; + n->missing_ok = false; + $$ = (Node *)n; + } | ALTER PUBLICATION name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); @@ -10242,6 +10854,26 @@ AlterObjectSchemaStmt: n->missing_ok = false; $$ = (Node *) n; } + | ALTER PROPERTY GRAPH qualified_name SET SCHEMA name + { + AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + + n->objectType = OBJECT_PROPGRAPH; + n->relation = $4; + n->newschema = $7; + n->missing_ok = false; + $$ = (Node *)n; + } + | ALTER PROPERTY GRAPH IF_P EXISTS qualified_name SET SCHEMA name + { + AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + + n->objectType = OBJECT_PROPGRAPH; + n->relation = $6; + n->newschema = $9; + n->missing_ok = true; + $$ = (Node *)n; + } | ALTER ROUTINE function_with_argtypes SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); @@ -10585,6 +11217,15 @@ AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec n->newowner = $6; $$ = (Node *) n; } + | ALTER PROPERTY GRAPH qualified_name OWNER TO RoleSpec + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + + n->objectType = OBJECT_PROPGRAPH; + n->relation = $4; + n->newowner = $7; + $$ = (Node *) n; + } | ALTER ROUTINE function_with_argtypes OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); @@ -10700,7 +11341,12 @@ AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec * * CREATE PUBLICATION name [WITH options] * - * CREATE PUBLICATION FOR ALL TABLES [WITH options] + * CREATE PUBLICATION FOR ALL pub_all_obj_type [, ...] [WITH options] + * + * pub_all_obj_type is one of: + * + * TABLES [EXCEPT (TABLE table [, ...] )] + * SEQUENCES * * CREATE PUBLICATION FOR pub_obj [, ...] [WITH options] * @@ -10720,13 +11366,16 @@ CreatePublicationStmt: n->options = $4; $$ = (Node *) n; } - | CREATE PUBLICATION name FOR ALL TABLES opt_definition + | CREATE PUBLICATION name FOR pub_all_obj_type_list opt_definition { CreatePublicationStmt *n = makeNode(CreatePublicationStmt); n->pubname = $3; - n->options = $7; - n->for_all_tables = true; + preprocess_pub_all_objtype_list($5, &n->pubobjects, + &n->for_all_tables, + &n->for_all_sequences, + yyscanner); + n->options = $6; $$ = (Node *) n; } | CREATE PUBLICATION name FOR pub_obj_list opt_definition @@ -10838,6 +11487,51 @@ pub_obj_list: PublicationObjSpec { $$ = lappend($1, $3); } ; +opt_pub_except_clause: + EXCEPT '(' TABLE pub_except_obj_list ')' { $$ = $4; } + | /*EMPTY*/ { $$ = NIL; } + ; + +PublicationAllObjSpec: + ALL TABLES opt_pub_except_clause + { + $$ = makeNode(PublicationAllObjSpec); + $$->pubobjtype = PUBLICATION_ALL_TABLES; + $$->except_tables = $3; + $$->location = @1; + } + | ALL SEQUENCES + { + $$ = makeNode(PublicationAllObjSpec); + $$->pubobjtype = PUBLICATION_ALL_SEQUENCES; + $$->location = @1; + } + ; + +pub_all_obj_type_list: PublicationAllObjSpec + { $$ = list_make1($1); } + | pub_all_obj_type_list ',' PublicationAllObjSpec + { $$ = lappend($1, $3); } + ; + +PublicationExceptObjSpec: + relation_expr + { + $$ = makeNode(PublicationObjSpec); + $$->pubobjtype = PUBLICATIONOBJ_EXCEPT_TABLE; + $$->pubtable = makeNode(PublicationTable); + $$->pubtable->except = true; + $$->pubtable->relation = $1; + $$->location = @1; + } + ; + +pub_except_obj_list: PublicationExceptObjSpec + { $$ = list_make1($1); } + | pub_except_obj_list ',' opt_table PublicationExceptObjSpec + { $$ = lappend($1, $4); } + ; + /***************************************************************************** * * ALTER PUBLICATION name SET ( options ) @@ -10848,11 +11542,18 @@ pub_obj_list: PublicationObjSpec * * ALTER PUBLICATION name SET pub_obj [, ...] * + * ALTER PUBLICATION name SET pub_all_obj_type [, ...] + * * pub_obj is one of: * * TABLE table_name [, ...] * TABLES IN SCHEMA schema_name [, ...] * + * pub_all_obj_type is one of: + * + * ALL TABLES [ EXCEPT ( TABLE table_name [, ...] ) ] + * ALL SEQUENCES + * *****************************************************************************/ AlterPublicationStmt: @@ -10862,6 +11563,7 @@ AlterPublicationStmt: n->pubname = $3; n->options = $5; + n->for_all_tables = false; $$ = (Node *) n; } | ALTER PUBLICATION name ADD_P pub_obj_list @@ -10872,6 +11574,7 @@ AlterPublicationStmt: n->pubobjects = $5; preprocess_pubobj_list(n->pubobjects, yyscanner); n->action = AP_AddObjects; + n->for_all_tables = false; $$ = (Node *) n; } | ALTER PUBLICATION name SET pub_obj_list @@ -10882,6 +11585,19 @@ AlterPublicationStmt: n->pubobjects = $5; preprocess_pubobj_list(n->pubobjects, yyscanner); n->action = AP_SetObjects; + n->for_all_tables = false; + $$ = (Node *) n; + } + | ALTER PUBLICATION name SET pub_all_obj_type_list + { + AlterPublicationStmt *n = makeNode(AlterPublicationStmt); + + n->pubname = $3; + n->action = AP_SetObjects; + preprocess_pub_all_objtype_list($5, &n->pubobjects, + &n->for_all_tables, + &n->for_all_sequences, + yyscanner); $$ = (Node *) n; } | ALTER PUBLICATION name DROP pub_obj_list @@ -10892,6 +11608,7 @@ AlterPublicationStmt: n->pubobjects = $5; preprocess_pubobj_list(n->pubobjects, yyscanner); n->action = AP_DropObjects; + n->for_all_tables = false; $$ = (Node *) n; } ; @@ -10913,6 +11630,16 @@ CreateSubscriptionStmt: n->options = $8; $$ = (Node *) n; } + | CREATE SUBSCRIPTION name SERVER name PUBLICATION name_list opt_definition + { + CreateSubscriptionStmt *n = + makeNode(CreateSubscriptionStmt); + n->subname = $3; + n->servername = $5; + n->publication = $7; + n->options = $8; + $$ = (Node *) n; + } ; /***************************************************************************** @@ -10929,27 +11656,46 @@ AlterSubscriptionStmt: n->kind = ALTER_SUBSCRIPTION_OPTIONS; n->subname = $3; - n->options = $5; + n->options = $5; + $$ = (Node *) n; + } + | ALTER SUBSCRIPTION name CONNECTION Sconst + { + AlterSubscriptionStmt *n = + makeNode(AlterSubscriptionStmt); + + n->kind = ALTER_SUBSCRIPTION_CONNECTION; + n->subname = $3; + n->conninfo = $5; + $$ = (Node *) n; + } + | ALTER SUBSCRIPTION name SERVER name + { + AlterSubscriptionStmt *n = + makeNode(AlterSubscriptionStmt); + + n->kind = ALTER_SUBSCRIPTION_SERVER; + n->subname = $3; + n->servername = $5; $$ = (Node *) n; } - | ALTER SUBSCRIPTION name CONNECTION Sconst + | ALTER SUBSCRIPTION name REFRESH PUBLICATION opt_definition { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_CONNECTION; + n->kind = ALTER_SUBSCRIPTION_REFRESH_PUBLICATION; n->subname = $3; - n->conninfo = $5; + n->options = $6; $$ = (Node *) n; } - | ALTER SUBSCRIPTION name REFRESH PUBLICATION opt_definition + | ALTER SUBSCRIPTION name REFRESH SEQUENCES { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_REFRESH; + n->kind = ALTER_SUBSCRIPTION_REFRESH_SEQUENCES; n->subname = $3; - n->options = $6; $$ = (Node *) n; } | ALTER SUBSCRIPTION name ADD_P PUBLICATION name_list opt_definition @@ -11715,7 +12461,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'T'; + n->subtype = AD_AlterDefault; n->typeName = $3; n->def = $4; $$ = (Node *) n; @@ -11725,7 +12471,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'N'; + n->subtype = AD_DropNotNull; n->typeName = $3; $$ = (Node *) n; } @@ -11734,7 +12480,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'O'; + n->subtype = AD_SetNotNull; n->typeName = $3; $$ = (Node *) n; } @@ -11743,7 +12489,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'C'; + n->subtype = AD_AddConstraint; n->typeName = $3; n->def = $5; $$ = (Node *) n; @@ -11753,7 +12499,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'X'; + n->subtype = AD_DropConstraint; n->typeName = $3; n->name = $6; n->behavior = $7; @@ -11765,7 +12511,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'X'; + n->subtype = AD_DropConstraint; n->typeName = $3; n->name = $8; n->behavior = $9; @@ -11777,7 +12523,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'V'; + n->subtype = AD_ValidateConstraint; n->typeName = $3; n->name = $6; $$ = (Node *) n; @@ -11910,65 +12656,110 @@ CreateConversionStmt: /***************************************************************************** * * QUERY: + * REPACK [ (options) ] [ [ ] [ USING INDEX ] ] + * + * obsolete variants: * CLUSTER (options) [ [ USING ] ] * CLUSTER [VERBOSE] [ [ USING ] ] * CLUSTER [VERBOSE] ON (for pre-8.3) * *****************************************************************************/ -ClusterStmt: - CLUSTER '(' utility_option_list ')' qualified_name cluster_index_specification +RepackStmt: + REPACK opt_utility_option_list vacuum_relation USING INDEX name { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); - n->relation = $5; + n->command = REPACK_COMMAND_REPACK; + n->relation = (VacuumRelation *) $3; n->indexname = $6; - n->params = $3; + n->usingindex = true; + n->params = $2; + $$ = (Node *) n; + } + | REPACK opt_utility_option_list vacuum_relation opt_usingindex + { + RepackStmt *n = makeNode(RepackStmt); + + n->command = REPACK_COMMAND_REPACK; + n->relation = (VacuumRelation *) $3; + n->indexname = NULL; + n->usingindex = $4; + n->params = $2; $$ = (Node *) n; } - | CLUSTER '(' utility_option_list ')' + | REPACK opt_utility_option_list opt_usingindex { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); + n->command = REPACK_COMMAND_REPACK; n->relation = NULL; n->indexname = NULL; + n->usingindex = $3; + n->params = $2; + $$ = (Node *) n; + } + | CLUSTER '(' utility_option_list ')' qualified_name cluster_index_specification + { + RepackStmt *n = makeNode(RepackStmt); + + n->command = REPACK_COMMAND_CLUSTER; + n->relation = makeNode(VacuumRelation); + n->relation->relation = $5; + n->indexname = $6; + n->usingindex = true; n->params = $3; $$ = (Node *) n; } + | CLUSTER opt_utility_option_list + { + RepackStmt *n = makeNode(RepackStmt); + + n->command = REPACK_COMMAND_CLUSTER; + n->relation = NULL; + n->indexname = NULL; + n->usingindex = true; + n->params = $2; + $$ = (Node *) n; + } /* unparenthesized VERBOSE kept for pre-14 compatibility */ | CLUSTER opt_verbose qualified_name cluster_index_specification { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); - n->relation = $3; + n->command = REPACK_COMMAND_CLUSTER; + n->relation = makeNode(VacuumRelation); + n->relation->relation = $3; n->indexname = $4; - n->params = NIL; + n->usingindex = true; if ($2) - n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + n->params = list_make1(makeDefElem("verbose", NULL, @2)); $$ = (Node *) n; } /* unparenthesized VERBOSE kept for pre-17 compatibility */ - | CLUSTER opt_verbose + | CLUSTER VERBOSE { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); + n->command = REPACK_COMMAND_CLUSTER; n->relation = NULL; n->indexname = NULL; - n->params = NIL; - if ($2) - n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + n->usingindex = true; + n->params = list_make1(makeDefElem("verbose", NULL, @2)); $$ = (Node *) n; } /* kept for pre-8.3 compatibility */ | CLUSTER opt_verbose name ON qualified_name { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); - n->relation = $5; + n->command = REPACK_COMMAND_CLUSTER; + n->relation = makeNode(VacuumRelation); + n->relation->relation = $5; n->indexname = $3; - n->params = NIL; + n->usingindex = true; if ($2) - n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + n->params = list_make1(makeDefElem("verbose", NULL, @2)); $$ = (Node *) n; } ; @@ -12019,64 +12810,31 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose opt_analyze opt_vacuum_relati } ; -AnalyzeStmt: analyze_keyword opt_verbose opt_vacuum_relation_list +AnalyzeStmt: analyze_keyword opt_utility_option_list opt_vacuum_relation_list { VacuumStmt *n = makeNode(VacuumStmt); - n->options = NIL; - if ($2) - n->options = lappend(n->options, - makeDefElem("verbose", NULL, @2)); + n->options = $2; n->rels = $3; n->is_vacuumcmd = false; $$ = (Node *) n; } - | analyze_keyword '(' utility_option_list ')' opt_vacuum_relation_list + | analyze_keyword VERBOSE opt_vacuum_relation_list { VacuumStmt *n = makeNode(VacuumStmt); - n->options = $3; - n->rels = $5; + n->options = list_make1(makeDefElem("verbose", NULL, @2)); + n->rels = $3; n->is_vacuumcmd = false; $$ = (Node *) n; } ; -utility_option_list: - utility_option_elem - { - $$ = list_make1($1); - } - | utility_option_list ',' utility_option_elem - { - $$ = lappend($1, $3); - } - ; - analyze_keyword: ANALYZE | ANALYSE /* British */ ; -utility_option_elem: - utility_option_name utility_option_arg - { - $$ = makeDefElem($1, $2, @1); - } - ; - -utility_option_name: - NonReservedWord { $$ = $1; } - | analyze_keyword { $$ = "analyze"; } - | FORMAT_LA { $$ = "format"; } - ; - -utility_option_arg: - opt_boolean_or_string { $$ = (Node *) makeString($1); } - | NumericOnly { $$ = (Node *) $1; } - | /* EMPTY */ { $$ = NULL; } - ; - opt_analyze: analyze_keyword { $$ = true; } | /*EMPTY*/ { $$ = false; } @@ -12421,12 +13179,24 @@ insert_column_item: ; opt_on_conflict: + ON CONFLICT opt_conf_expr DO SELECT opt_for_locking_strength where_clause + { + $$ = makeNode(OnConflictClause); + $$->action = ONCONFLICT_SELECT; + $$->infer = $3; + $$->targetList = NIL; + $$->lockStrength = $6; + $$->whereClause = $7; + $$->location = @1; + } + | ON CONFLICT opt_conf_expr DO UPDATE SET set_clause_list where_clause { $$ = makeNode(OnConflictClause); $$->action = ONCONFLICT_UPDATE; $$->infer = $3; $$->targetList = $7; + $$->lockStrength = LCS_NONE; $$->whereClause = $8; $$->location = @1; } @@ -12437,6 +13207,7 @@ opt_on_conflict: $$->action = ONCONFLICT_NOTHING; $$->infer = $3; $$->targetList = NIL; + $$->lockStrength = LCS_NONE; $$->whereClause = NULL; $$->location = @1; } @@ -12532,6 +13303,21 @@ DeleteStmt: opt_with_clause DELETE_P FROM relation_expr_opt_alias n->withClause = $1; $$ = (Node *) n; } + | opt_with_clause DELETE_P FROM relation_expr + for_portion_of_clause for_portion_of_opt_alias + using_clause where_or_current_clause returning_clause + { + DeleteStmt *n = makeNode(DeleteStmt); + + n->relation = $4; + n->forPortionOf = (ForPortionOfClause *) $5; + n->relation->alias = $6; + n->usingClause = $7; + n->whereClause = $8; + n->returningClause = $9; + n->withClause = $1; + $$ = (Node *) n; + } ; using_clause: @@ -12556,6 +13342,25 @@ LockStmt: LOCK_P opt_table relation_expr_list opt_lock opt_nowait n->nowait = $5; $$ = (Node *) n; } + | opt_with_clause UPDATE relation_expr + for_portion_of_clause for_portion_of_opt_alias + SET set_clause_list + from_clause + where_or_current_clause + returning_clause + { + UpdateStmt *n = makeNode(UpdateStmt); + + n->relation = $3; + n->forPortionOf = (ForPortionOfClause *) $4; + n->relation->alias = $5; + n->targetList = $7; + n->fromClause = $8; + n->whereClause = $9; + n->returningClause = $10; + n->withClause = $1; + $$ = (Node *) n; + } ; opt_lock: IN_P lock_type MODE { $$ = $2; } @@ -13386,7 +14191,7 @@ select_limit: } | offset_clause { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = $1; n->limitCount = NULL; @@ -13406,7 +14211,7 @@ opt_select_limit: limit_clause: LIMIT select_limit_value { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = $2; @@ -13434,7 +14239,7 @@ limit_clause: */ | FETCH first_or_next select_fetch_first_value row_or_rows ONLY { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = $3; @@ -13446,7 +14251,7 @@ limit_clause: } | FETCH first_or_next select_fetch_first_value row_or_rows WITH TIES { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = $3; @@ -13458,7 +14263,7 @@ limit_clause: } | FETCH first_or_next row_or_rows ONLY { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = makeIntConst(1, -1); @@ -13470,7 +14275,7 @@ limit_clause: } | FETCH first_or_next row_or_rows WITH TIES { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = makeIntConst(1, -1); @@ -13565,7 +14370,7 @@ first_or_next: FIRST_P { $$ = 0; } group_clause: GROUP_P BY set_quantifier group_by_list { - GroupClause *n = (GroupClause *) palloc(sizeof(GroupClause)); + GroupClause *n = palloc_object(GroupClause); n->distinct = $3 == SET_QUANTIFIER_DISTINCT; n->list = $4; @@ -13573,7 +14378,7 @@ group_clause: } | /*EMPTY*/ { - GroupClause *n = (GroupClause *) palloc(sizeof(GroupClause)); + GroupClause *n = palloc_object(GroupClause); n->distinct = false; n->list = NIL; @@ -13667,6 +14472,11 @@ for_locking_strength: | FOR KEY SHARE { $$ = LCS_FORKEYSHARE; } ; +opt_for_locking_strength: + for_locking_strength { $$ = $1; } + | /* EMPTY */ { $$ = LCS_NONE; } + ; + locked_rels_list: OF qualified_name_list { $$ = $2; } | /* EMPTY */ { $$ = NIL; } @@ -13763,6 +14573,17 @@ table_ref: relation_expr opt_alias_clause n->alias = $3; $$ = (Node *) n; } + | GRAPH_TABLE '(' qualified_name MATCH graph_pattern COLUMNS '(' labeled_expr_list ')' ')' opt_alias_clause + { + RangeGraphTable *n = makeNode(RangeGraphTable); + + n->graph_name = $3; + n->graph_pattern = castNode(GraphPattern, $5); + n->columns = $8; + n->alias = $11; + n->location = @1; + $$ = (Node *) n; + } | select_with_parens opt_alias_clause { RangeSubselect *n = makeNode(RangeSubselect); @@ -14104,6 +14925,55 @@ relation_expr_opt_alias: relation_expr %prec UMINUS } ; +/* + * If an UPDATE/DELETE has FOR PORTION OF, then the relation_expr is separated + * from its potential alias by the for_portion_of_clause. So this production + * handles the potential alias in those cases. We need to solve the same + * problems as relation_expr_opt_alias, in particular resolving a shift/reduce + * conflict where "set set" could be an alias plus the SET keyword, or the SET + * keyword then a column name. As above, we force the latter interpretation by + * giving the non-alias choice a higher precedence. + */ +for_portion_of_opt_alias: + AS ColId + { + Alias *alias = makeNode(Alias); + + alias->aliasname = $2; + $$ = alias; + } + | BareColLabel + { + Alias *alias = makeNode(Alias); + + alias->aliasname = $1; + $$ = alias; + } + | /* empty */ %prec UMINUS { $$ = NULL; } + ; + +for_portion_of_clause: + FOR PORTION OF ColId '(' a_expr ')' + { + ForPortionOfClause *n = makeNode(ForPortionOfClause); + n->range_name = $4; + n->location = @4; + n->target = $6; + n->target_location = @6; + $$ = (Node *) n; + } + | FOR PORTION OF ColId FROM a_expr TO a_expr + { + ForPortionOfClause *n = makeNode(ForPortionOfClause); + n->range_name = $4; + n->location = @4; + n->target_start = $6; + n->target_end = $8; + n->target_location = @5; + $$ = (Node *) n; + } + ; + /* * TABLESAMPLE decoration in a FROM item */ @@ -14944,16 +15814,25 @@ opt_timezone: | /*EMPTY*/ { $$ = false; } ; +/* + * We need to handle this shift/reduce conflict: + * FOR PORTION OF valid_at FROM t + INTERVAL '1' YEAR TO MONTH. + * We don't see far enough ahead to know if there is another TO coming. + * We prefer to interpret this as FROM (t + INTERVAL '1' YEAR TO MONTH), + * i.e. to shift. + * That gives the user the option of adding parentheses to get the other meaning. + * If we reduced, intervals could never have a TO. + */ opt_interval: - YEAR_P + YEAR_P %prec IS { $$ = list_make1(makeIntConst(INTERVAL_MASK(YEAR), @1)); } | MONTH_P { $$ = list_make1(makeIntConst(INTERVAL_MASK(MONTH), @1)); } - | DAY_P + | DAY_P %prec IS { $$ = list_make1(makeIntConst(INTERVAL_MASK(DAY), @1)); } - | HOUR_P + | HOUR_P %prec IS { $$ = list_make1(makeIntConst(INTERVAL_MASK(HOUR), @1)); } - | MINUTE_P + | MINUTE_P %prec IS { $$ = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), @1)); } | interval_second { $$ = $1; } @@ -15114,6 +15993,10 @@ a_expr: c_expr { $$ = $1; } { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $3, @2); } | a_expr NOT_EQUALS a_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, $3, @2); } + | a_expr RIGHT_ARROW a_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "->", $1, $3, @2); } + | a_expr '|' a_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", $1, $3, @2); } | a_expr qual_Op a_expr %prec Op { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); } @@ -15505,7 +16388,7 @@ a_expr: c_expr { $$ = $1; } { JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1); - $$ = makeJsonIsPredicate($1, format, $3, $4, @1); + $$ = makeJsonIsPredicate($1, format, $3, $4, InvalidOid, @1); } /* * Required by SQL/JSON, but there are conflicts @@ -15514,7 +16397,7 @@ a_expr: c_expr { $$ = $1; } IS json_predicate_type_constraint json_key_uniqueness_constraint_opt %prec IS { - $$ = makeJsonIsPredicate($1, $2, $4, $5, @1); + $$ = makeJsonIsPredicate($1, $2, $4, $5, InvalidOid, @1); } */ | a_expr IS NOT @@ -15523,7 +16406,7 @@ a_expr: c_expr { $$ = $1; } { JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1); - $$ = makeNotExpr(makeJsonIsPredicate($1, format, $4, $5, @1), @1); + $$ = makeNotExpr(makeJsonIsPredicate($1, format, $4, $5, InvalidOid, @1), @1); } /* * Required by SQL/JSON, but there are conflicts @@ -15533,7 +16416,7 @@ a_expr: c_expr { $$ = $1; } json_predicate_type_constraint json_key_uniqueness_constraint_opt %prec IS { - $$ = makeNotExpr(makeJsonIsPredicate($1, $2, $5, $6, @1), @1); + $$ = makeNotExpr(makeJsonIsPredicate($1, $2, $5, $6, InvalidOid, @1), @1); } */ | DEFAULT @@ -15594,6 +16477,10 @@ b_expr: c_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $3, @2); } | b_expr NOT_EQUALS b_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, $3, @2); } + | b_expr RIGHT_ARROW b_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "->", $1, $3, @2); } + | b_expr '|' b_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", $1, $3, @2); } | b_expr qual_Op b_expr %prec Op { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); } | qual_Op b_expr %prec Op @@ -15853,7 +16740,7 @@ func_application: func_name '(' ')' * (Note that many of the special SQL functions wouldn't actually make any * sense as functional index entries, but we ignore that consideration here.) */ -func_expr: func_application within_group_clause filter_clause over_clause +func_expr: func_application within_group_clause filter_clause null_treatment over_clause { FuncCall *n = (FuncCall *) $1; @@ -15886,7 +16773,8 @@ func_expr: func_application within_group_clause filter_clause over_clause n->agg_within_group = true; } n->agg_filter = $3; - n->over = $4; + n->ignore_nulls = $4; + n->over = $5; $$ = (Node *) n; } | json_aggregate_func filter_clause over_clause @@ -16175,7 +17063,7 @@ func_expr_common_subexpr: COERCE_SQL_SYNTAX, @1); } - | XMLFOREST '(' xml_attribute_list ')' + | XMLFOREST '(' labeled_expr_list ')' { $$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NIL, @1); } @@ -16400,14 +17288,14 @@ opt_xml_root_standalone: ',' STANDALONE_P YES_P { $$ = makeIntConst(XML_STANDALONE_OMITTED, -1); } ; -xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; } +xml_attributes: XMLATTRIBUTES '(' labeled_expr_list ')' { $$ = $3; } ; -xml_attribute_list: xml_attribute_el { $$ = list_make1($1); } - | xml_attribute_list ',' xml_attribute_el { $$ = lappend($1, $3); } +labeled_expr_list: labeled_expr { $$ = list_make1($1); } + | labeled_expr_list ',' labeled_expr { $$ = lappend($1, $3); } ; -xml_attribute_el: a_expr AS ColLabel +labeled_expr: a_expr AS ColLabel { $$ = makeNode(ResTarget); $$->name = $3; @@ -16464,6 +17352,26 @@ xml_passing_mech: | BY VALUE_P ; +/***************************************************************************** + * + * WAIT FOR LSN + * + *****************************************************************************/ + +WaitStmt: + WAIT FOR LSN_P Sconst opt_wait_with_clause + { + WaitStmt *n = makeNode(WaitStmt); + n->lsn_literal = $4; + n->options = $5; + $$ = (Node *) n; + } + ; + +opt_wait_with_clause: + WITH '(' utility_option_list ')' { $$ = $3; } + | /*EMPTY*/ { $$ = NIL; } + ; /* * Aggregate decoration clauses @@ -16482,6 +17390,12 @@ filter_clause: /* * Window Definitions */ +null_treatment: + IGNORE_P NULLS_P { $$ = PARSER_IGNORE_NULLS; } + | RESPECT_P NULLS_P { $$ = PARSER_RESPECT_NULLS; } + | /*EMPTY*/ { $$ = NO_NULLTREATMENT; } + ; + window_clause: WINDOW window_definition_list { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } @@ -16762,6 +17676,8 @@ MathOp: '+' { $$ = "+"; } | LESS_EQUALS { $$ = "<="; } | GREATER_EQUALS { $$ = ">="; } | NOT_EQUALS { $$ = "<>"; } + | RIGHT_ARROW { $$ = "->"; } + | '|' { $$ = "|"; } ; qual_Op: Op @@ -17342,6 +18258,214 @@ json_array_aggregate_order_by_clause_opt: | /* EMPTY */ { $$ = NIL; } ; + +/***************************************************************************** + * + * graph patterns + * + *****************************************************************************/ + +graph_pattern: + path_pattern_list where_clause + { + GraphPattern *gp = makeNode(GraphPattern); + + gp->path_pattern_list = $1; + gp->whereClause = $2; + $$ = (Node *) gp; + } + ; + +path_pattern_list: + path_pattern { $$ = list_make1($1); } + | path_pattern_list ',' path_pattern { $$ = lappend($1, $3); } + ; + +path_pattern: + path_pattern_expression { $$ = $1; } + ; + +/* + * path pattern expression + */ + +path_pattern_expression: + path_term { $$ = $1; } + /* | path_multiset_alternation */ + /* | path_pattern_union */ + ; + +path_term: + path_factor { $$ = list_make1($1); } + | path_term path_factor { $$ = lappend($1, $2); } + ; + +path_factor: + path_primary opt_graph_pattern_quantifier + { + GraphElementPattern *gep = (GraphElementPattern *) $1; + + gep->quantifier = $2; + + $$ = (Node *) gep; + } + ; + +path_primary: + '(' opt_colid opt_is_label_expression where_clause ')' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = VERTEX_PATTERN; + gep->variable = $2; + gep->labelexpr = $3; + gep->whereClause = $4; + gep->location = @1; + + $$ = (Node *) gep; + } + /* full edge pointing left: <-[ xxx ]- */ + | '<' '-' '[' opt_colid opt_is_label_expression where_clause ']' '-' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_LEFT; + gep->variable = $4; + gep->labelexpr = $5; + gep->whereClause = $6; + gep->location = @1; + + $$ = (Node *) gep; + } + /* full edge pointing right: -[ xxx ]-> */ + | '-' '[' opt_colid opt_is_label_expression where_clause ']' '-' '>' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_RIGHT; + gep->variable = $3; + gep->labelexpr = $4; + gep->whereClause = $5; + gep->location = @1; + + $$ = (Node *) gep; + } + | '-' '[' opt_colid opt_is_label_expression where_clause ']' RIGHT_ARROW + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_RIGHT; + gep->variable = $3; + gep->labelexpr = $4; + gep->whereClause = $5; + gep->location = @1; + + $$ = (Node *) gep; + } + /* full edge any direction: -[ xxx ]- */ + | '-' '[' opt_colid opt_is_label_expression where_clause ']' '-' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_ANY; + gep->variable = $3; + gep->labelexpr = $4; + gep->whereClause = $5; + gep->location = @1; + + $$ = (Node *) gep; + } + /* abbreviated edge patterns */ + | '<' '-' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_LEFT; + gep->location = @1; + + $$ = (Node *) gep; + } + | '-' '>' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_RIGHT; + gep->location = @1; + + $$ = (Node *) gep; + } + | RIGHT_ARROW + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_RIGHT; + gep->location = @1; + + $$ = (Node *) gep; + } + | '-' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_ANY; + gep->location = @1; + + $$ = (Node *) gep; + } + | '(' path_pattern_expression where_clause ')' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = PAREN_EXPR; + gep->subexpr = $2; + gep->whereClause = $3; + gep->location = @1; + + $$ = (Node *) gep; + } + ; + +opt_colid: + ColId { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; + +opt_is_label_expression: + IS label_expression { $$ = $2; } + | /*EMPTY*/ { $$ = NULL; } + ; + +/* + * graph pattern quantifier + */ + +opt_graph_pattern_quantifier: + '{' Iconst '}' { $$ = list_make2_int($2, $2); } + | '{' ',' Iconst '}' { $$ = list_make2_int(0, $3); } + | '{' Iconst ',' Iconst '}' { $$ = list_make2_int($2, $4); } + | /*EMPTY*/ { $$ = NULL; } + ; + +/* + * label expression + */ + +label_expression: + label_term + | label_disjunction + ; + +label_disjunction: + label_expression '|' label_term + { $$ = makeOrExpr($1, $3, @2); } + ; + +label_term: + name + { $$ = makeColumnRef($1, NIL, @1, yyscanner); } + ; + + /***************************************************************************** * * target list for SELECT @@ -17862,6 +18986,7 @@ unreserved_keyword: | DELIMITERS | DEPENDS | DEPTH + | DESTINATION | DETACH | DICTIONARY | DISABLE_P @@ -17871,6 +18996,7 @@ unreserved_keyword: | DOUBLE_P | DROP | EACH + | EDGE | EMPTY_P | ENABLE_P | ENCODING @@ -17901,6 +19027,7 @@ unreserved_keyword: | GENERATED | GLOBAL | GRANTED + | GRAPH | GROUPS | HANDLER | HEADER_P @@ -17908,6 +19035,7 @@ unreserved_keyword: | HOUR_P | IDENTITY_P | IF_P + | IGNORE_P | IMMEDIATE | IMMUTABLE | IMPLICIT_P @@ -17943,6 +19071,7 @@ unreserved_keyword: | LOCK_P | LOCKED | LOGGED + | LSN_P | MAPPING | MATCH | MATCHED @@ -17965,6 +19094,7 @@ unreserved_keyword: | NFKC | NFKD | NO + | NODE | NORMALIZED | NOTHING | NOTIFY @@ -17991,6 +19121,7 @@ unreserved_keyword: | PARSER | PARTIAL | PARTITION + | PARTITIONS | PASSING | PASSWORD | PATH @@ -17998,6 +19129,7 @@ unreserved_keyword: | PLAN | PLANS | POLICY + | PORTION | PRECEDING | PREPARE | PREPARED @@ -18008,6 +19140,8 @@ unreserved_keyword: | PROCEDURE | PROCEDURES | PROGRAM + | PROPERTIES + | PROPERTY | PUBLICATION | QUOTE | QUOTES @@ -18019,13 +19153,16 @@ unreserved_keyword: | REFERENCING | REFRESH | REINDEX + | RELATIONSHIP | RELATIVE_P | RELEASE | RENAME + | REPACK | REPEATABLE | REPLACE | REPLICA | RESET + | RESPECT_P | RESTART | RESTRICT | RETURN @@ -18059,6 +19196,7 @@ unreserved_keyword: | SKIP | SNAPSHOT | SOURCE + | SPLIT | SQL_P | STABLE | STANDALONE_P @@ -18108,10 +19246,12 @@ unreserved_keyword: | VALUE_P | VARYING | VERSION_P + | VERTEX | VIEW | VIEWS | VIRTUAL | VOLATILE + | WAIT | WHITESPACE_P | WITHIN | WITHOUT @@ -18147,6 +19287,7 @@ col_name_keyword: | EXISTS | EXTRACT | FLOAT_P + | GRAPH_TABLE | GREATEST | GROUPING | INOUT @@ -18438,6 +19579,7 @@ bare_label_keyword: | DEPENDS | DEPTH | DESC + | DESTINATION | DETACH | DICTIONARY | DISABLE_P @@ -18449,6 +19591,7 @@ bare_label_keyword: | DOUBLE_P | DROP | EACH + | EDGE | ELSE | EMPTY_P | ENABLE_P @@ -18487,6 +19630,8 @@ bare_label_keyword: | GENERATED | GLOBAL | GRANTED + | GRAPH + | GRAPH_TABLE | GREATEST | GROUPING | GROUPS @@ -18558,6 +19703,7 @@ bare_label_keyword: | LOCK_P | LOCKED | LOGGED + | LSN_P | MAPPING | MATCH | MATCHED @@ -18582,6 +19728,7 @@ bare_label_keyword: | NFKC | NFKD | NO + | NODE | NONE | NORMALIZE | NORMALIZED @@ -18618,6 +19765,7 @@ bare_label_keyword: | PARSER | PARTIAL | PARTITION + | PARTITIONS | PASSING | PASSWORD | PATH @@ -18626,6 +19774,7 @@ bare_label_keyword: | PLAN | PLANS | POLICY + | PORTION | POSITION | PRECEDING | PREPARE @@ -18638,6 +19787,8 @@ bare_label_keyword: | PROCEDURE | PROCEDURES | PROGRAM + | PROPERTIES + | PROPERTY | PUBLICATION | QUOTE | QUOTES @@ -18651,9 +19802,11 @@ bare_label_keyword: | REFERENCING | REFRESH | REINDEX + | RELATIONSHIP | RELATIVE_P | RELEASE | RENAME + | REPACK | REPEATABLE | REPLACE | REPLICA @@ -18698,6 +19851,7 @@ bare_label_keyword: | SNAPSHOT | SOME | SOURCE + | SPLIT | SQL_P | STABLE | STANDALONE_P @@ -18765,10 +19919,12 @@ bare_label_keyword: | VARIADIC | VERBOSE | VERSION_P + | VERTEX | VIEW | VIEWS | VIRTUAL | VOLATILE + | WAIT | WHEN | WHITESPACE_P | WORK @@ -19625,6 +20781,49 @@ parsePartitionStrategy(char *strategy, int location, core_yyscan_t yyscanner) } +/* + * Process all_objects_list to set all_tables and/or all_sequences. + * Also, checks if the pub_object_type has been specified more than once. + */ +static void +preprocess_pub_all_objtype_list(List *all_objects_list, List **pubobjects, + bool *all_tables, bool *all_sequences, + core_yyscan_t yyscanner) +{ + if (!all_objects_list) + return; + + *all_tables = false; + *all_sequences = false; + + foreach_ptr(PublicationAllObjSpec, obj, all_objects_list) + { + if (obj->pubobjtype == PUBLICATION_ALL_TABLES) + { + if (*all_tables) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid publication object list"), + errdetail("ALL TABLES can be specified only once."), + parser_errposition(obj->location)); + + *all_tables = true; + *pubobjects = list_concat(*pubobjects, obj->except_tables); + } + else if (obj->pubobjtype == PUBLICATION_ALL_SEQUENCES) + { + if (*all_sequences) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid publication object list"), + errdetail("ALL SEQUENCES can be specified only once."), + parser_errposition(obj->location)); + + *all_sequences = true; + } + } +} + /* * Process pubobjspec_list to check for errors in any of the objects and * convert PUBLICATIONOBJ_CONTINUATION into appropriate PublicationObjSpecType. diff --git a/src/parser/gram_template.y b/src/parser/gram_template.y index 4ade68365..bd23b978b 100644 --- a/src/parser/gram_template.y +++ b/src/parser/gram_template.y @@ -6,8 +6,8 @@ * gram.y * POSTGRESQL BISON rules/actions * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -226,7 +226,7 @@ static void doNegateFloat(Float *v); static Node *makeAndExpr(Node *lexpr, Node *rexpr, int location); static Node *makeOrExpr(Node *lexpr, Node *rexpr, int location); static Node *makeNotExpr(Node *expr, int location); -static Node *makeAArrayExpr(List *elements, int location, int end_location); +static Node *makeAArrayExpr(List *elements, int location, int location_end); static Node *makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod, int location); static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, @@ -244,6 +244,11 @@ static void processCASbits(int cas_bits, int location, const char *constrType, bool *not_valid, bool *no_inherit, core_yyscan_t yyscanner); static PartitionStrategy parsePartitionStrategy(char *strategy, int location, core_yyscan_t yyscanner); +static void preprocess_pub_all_objtype_list(List *all_objects_list, + List **pubobjects, + bool *all_tables, + bool *all_sequences, + core_yyscan_t yyscanner); static void preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner); static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); @@ -304,8 +309,10 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); PartitionElem *partelem; PartitionSpec *partspec; PartitionBoundSpec *partboundspec; + SinglePartitionSpec *singlepartspec; RoleSpec *rolespec; PublicationObjSpec *publicationobjectspec; + PublicationAllObjSpec *publicationallobjectspec; struct SelectLimit *selectlimit; SetQuantifier setquantifier; struct GroupClause *groupclause; @@ -327,13 +334,14 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); AlterCompositeTypeStmt AlterUserMappingStmt AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt AlterStatsStmt AlterDefaultPrivilegesStmt DefACLAction - AnalyzeStmt CallStmt ClosePortalStmt ClusterStmt CommentStmt + AnalyzeStmt CallStmt ClosePortalStmt CommentStmt ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt CreateDomainStmt CreateExtensionStmt CreateGroupStmt CreateOpClassStmt CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt CreateSchemaStmt CreateSeqStmt CreateStmt CreateStatsStmt CreateTableSpaceStmt CreateFdwStmt CreateForeignServerStmt CreateForeignTableStmt CreateAssertionStmt CreateTransformStmt CreateTrigStmt CreateEventTrigStmt + CreatePropGraphStmt AlterPropGraphStmt CreateUserStmt CreateUserMappingStmt CreateRoleStmt CreatePolicyStmt CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt DoStmt DropOpClassStmt DropOpFamilyStmt DropStmt @@ -347,7 +355,7 @@ InsertStmtShort #endif ListenStmt LoadStmt LockStmt MergeStmt NotifyStmt ExplainableStmt PreparableStmt CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt - RemoveFuncStmt RemoveOperStmt RenameStmt ReturnStmt RevokeStmt RevokeRoleStmt + RemoveFuncStmt RemoveOperStmt RenameStmt RepackStmt ReturnStmt RevokeStmt RevokeRoleStmt RuleActionStmt RuleActionStmtOrEmpty RuleStmt SecLabelStmt SelectStmt TransactionStmt TransactionStmtLegacy TruncateStmt UnlistenStmt UpdateStmt @@ -356,7 +364,7 @@ UpdateStmtShort #endif VacuumStmt VariableResetStmt VariableSetStmt VariableShowStmt - ViewStmt CheckPointStmt CreateConversionStmt + ViewStmt WaitStmt CheckPointStmt CreateConversionStmt DeallocateStmt PrepareStmt ExecuteStmt DropOwnedStmt ReassignOwnedStmt AlterTSConfigurationStmt AlterTSDictionaryStmt @@ -370,8 +378,14 @@ UpdateStmtShort %type opt_single_name %type opt_qualified_name -%type opt_concurrently +%type opt_concurrently opt_usingindex %type opt_drop_behavior +%type opt_utility_option_list +%type opt_wait_with_clause +%type utility_option_list +%type utility_option_elem +%type utility_option_name +%type utility_option_arg %type alter_column_default opclass_item opclass_drop alter_using %type add_drop opt_asc_desc opt_nulls_order @@ -392,10 +406,6 @@ UpdateStmtShort create_extension_opt_item alter_extension_opt_item %type opt_lock lock_type cast_context -%type utility_option_name -%type utility_option_elem -%type utility_option_list -%type utility_option_arg %type drop_option %type opt_or_replace opt_no opt_grant_grant_option @@ -499,7 +509,8 @@ UpdateStmtShort transform_element_list transform_type_list TriggerTransitions TriggerReferencing vacuum_relation_list opt_vacuum_relation_list - drop_option_list pub_obj_list + drop_option_list pub_obj_list pub_all_obj_type_list + pub_except_obj_list opt_pub_except_clause %type returning_clause %type returning_option @@ -526,7 +537,7 @@ UpdateStmtShort %type OptNoLog %type OnCommitOption -%type for_locking_strength +%type for_locking_strength opt_for_locking_strength %type for_locking_item %type for_locking_clause opt_for_locking_clause for_locking_items %type locked_rels_list @@ -601,6 +612,8 @@ UpdateStmtShort %type relation_expr %type extended_relation_expr %type relation_expr_opt_alias +%type for_portion_of_opt_alias +%type for_portion_of_clause %type tablesample_clause opt_repeatable_clause %type target_el set_target insert_column_item @@ -610,7 +623,6 @@ UpdateStmtShort %type generic_option_list alter_generic_option_list %type reindex_target_relation reindex_target_all -%type opt_reindex_option_list %type copy_generic_opt_arg copy_generic_opt_arg_list_item %type copy_generic_opt_elem @@ -638,6 +650,8 @@ UpdateStmtShort %type var_value zone_value %type auth_ident RoleSpec opt_granted_by %type PublicationObjSpec +%type PublicationExceptObjSpec +%type PublicationAllObjSpec %type unreserved_keyword type_func_name_keyword %type col_name_keyword reserved_keyword @@ -662,8 +676,8 @@ UpdateStmtShort %type opt_provider security_label -%type xml_attribute_el -%type xml_attribute_list xml_attributes +%type labeled_expr +%type labeled_expr_list xml_attributes %type xml_root_version opt_xml_root_standalone %type xmlexists_argument %type document_or_content @@ -685,7 +699,7 @@ UpdateStmtShort %type window_clause window_definition_list opt_partition_clause %type window_definition over_clause window_specification opt_frame_clause frame_extent frame_bound -%type opt_window_exclusion_clause +%type null_treatment opt_window_exclusion_clause %type opt_existing_window_name %type opt_if_not_exists %type opt_unique_null_treatment @@ -694,6 +708,8 @@ UpdateStmtShort %type part_elem %type part_params %type PartitionBoundSpec +%type SinglePartitionSpec +%type partitions_list %type hash_partbound %type hash_partbound_elem @@ -725,6 +741,35 @@ UpdateStmtShort json_object_constructor_null_clause_opt json_array_constructor_null_clause_opt +%type vertex_tables_clause edge_tables_clause + opt_vertex_tables_clause opt_edge_tables_clause + vertex_table_list + opt_graph_table_key_clause + edge_table_list + source_vertex_table destination_vertex_table + opt_element_table_label_and_properties + label_and_properties_list + add_label_list +%type vertex_table_definition edge_table_definition +%type opt_propgraph_table_alias +%type element_table_label_clause +%type label_and_properties element_table_properties + add_label +%type vertex_or_edge + +%type opt_graph_pattern_quantifier + path_pattern_list + path_pattern + path_pattern_expression + path_term +%type graph_pattern + path_factor + path_primary + opt_is_label_expression + label_expression + label_disjunction + label_term +%type opt_colid /* * Non-keyword token types. These are hard-wired into the "flex" lexer. @@ -768,22 +813,22 @@ UpdateStmtShort CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS - DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC + DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC DESTINATION DETACH DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP - EACH ELSE EMPTY_P ENABLE_P ENCODING ENCRYPTED END_P ENFORCED ENUM_P ERROR_P - ESCAPE EVENT EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN - EXPRESSION EXTENSION EXTERNAL EXTRACT + EACH EDGE ELSE EMPTY_P ENABLE_P ENCODING ENCRYPTED END_P ENFORCED ENUM_P + ERROR_P ESCAPE EVENT EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS + EXPLAIN EXPRESSION EXTENSION EXTERNAL EXTRACT FALSE_P FAMILY FETCH FILTER FINALIZE FIRST_P FLOAT_P FOLLOWING FOR FORCE FOREIGN FORMAT FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS - GENERATED GLOBAL GRANT GRANTED GREATEST GROUP_P GROUPING GROUPS + GENERATED GLOBAL GRANT GRANTED GRAPH GRAPH_TABLE GREATEST GROUP_P GROUPING GROUPS HANDLER HAVING HEADER_P HOLD HOUR_P - IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE + IDENTITY_P IF_P IGNORE_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE INCLUDING INCREMENT INDENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION @@ -795,12 +840,12 @@ UpdateStmtShort LABEL LANGUAGE LARGE_P LAST_P LATERAL_P LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL - LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOGGED + LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOGGED LSN_P MAPPING MATCH MATCHED MATERIALIZED MAXVALUE MERGE MERGE_ACTION METHOD MINUTE_P MINVALUE MODE MONTH_P MOVE - NAME_P NAMES NATIONAL NATURAL NCHAR NESTED NEW NEXT NFC NFD NFKC NFKD NO + NAME_P NAMES NATIONAL NATURAL NCHAR NESTED NEW NEXT NFC NFD NFKC NFKD NO NODE NONE NORMALIZE NORMALIZED NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NULLS_P NUMERIC @@ -809,22 +854,22 @@ UpdateStmtShort ORDER ORDINALITY OTHERS OUT_P OUTER_P OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER - PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD PATH PGPOOL - PERIOD PLACING PLAN PLANS POLICY + PARALLEL PARAMETER PARSER PARTIAL PARTITION PARTITIONS PASSING PASSWORD PATH PGPOOL + PERIOD PLACING PLAN PLANS POLICY PORTION POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY - PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION + PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PROPERTIES PROPERTY PUBLICATION QUOTE QUOTES RANGE READ REAL REASSIGN RECURSIVE REF_P REFERENCES REFERENCING - REFRESH REINDEX RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA - RESET RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP + REFRESH REINDEX RELATIONSHIP RELATIVE_P RELEASE RENAME REPACK REPEATABLE REPLACE REPLICA + RESET RESPECT_P RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP ROUTINE ROUTINES ROW ROWS RULE SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW - SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SOURCE SQL_P STABLE STANDALONE_P + SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SPLIT SOURCE SQL_P STABLE STANDALONE_P START STATEMENT STATISTICS STDIN STDOUT STORAGE STORED STRICT_P STRING_P STRIP_P SUBSCRIPTION SUBSTRING SUPPORT SYMMETRIC SYSID SYSTEM_P SYSTEM_USER @@ -837,9 +882,9 @@ UpdateStmtShort UNLISTEN UNLOGGED UNTIL UPDATE USER USING VACUUM VALID VALIDATE VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING - VERBOSE VERSION_P VIEW VIEWS VIRTUAL VOLATILE + VERBOSE VERSION_P VERTEX VIEW VIEWS VIRTUAL VOLATILE - WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE + WAIT WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE @@ -929,13 +974,16 @@ UpdateStmtShort * json_predicate_type_constraint and json_key_uniqueness_constraint_opt * productions (see comments there). * + * TO is assigned the same precedence as IDENT, to support the opt_interval + * production (see comment there). + * * Like the UNBOUNDED PRECEDING/FOLLOWING case, NESTED is assigned a lower * precedence than PATH to fix ambiguity in the json_table production. */ %nonassoc UNBOUNDED NESTED /* ideally would have same precedence as IDENT */ %nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP - SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT PATH -%left Op OPERATOR /* multi-character ops and user-defined operators */ + SET KEYS OBJECT_P SCALAR TO USING VALUE_P WITH WITHOUT PATH +%left Op OPERATOR RIGHT_ARROW '|' /* multi-character ops and user-defined operators */ %left '+' '-' %left '*' '/' '%' %left '^' @@ -1062,6 +1110,7 @@ stmt: | AlterOperatorStmt | AlterTypeStmt | AlterPolicyStmt + | AlterPropGraphStmt | AlterSeqStmt | AlterSystemStmt | AlterTableStmt @@ -1079,7 +1128,6 @@ stmt: | CallStmt | CheckPointStmt | ClosePortalStmt - | ClusterStmt | CommentStmt | ConstraintsSetStmt | CopyStmt @@ -1102,6 +1150,7 @@ stmt: | AlterOpFamilyStmt | CreatePolicyStmt | CreatePLangStmt + | CreatePropGraphStmt | CreateSchemaStmt | CreateSeqStmt | CreateStmt @@ -1157,6 +1206,7 @@ stmt: | RemoveFuncStmt | RemoveOperStmt | RenameStmt + | RepackStmt | RevokeStmt | RevokeRoleStmt | RuleStmt @@ -1175,6 +1225,7 @@ stmt: | VariableSetStmt | VariableShowStmt | ViewStmt + | WaitStmt | /*EMPTY*/ { $$ = NULL; } ; @@ -1197,12 +1248,52 @@ opt_concurrently: | /*EMPTY*/ { $$ = false; } ; +opt_usingindex: + USING INDEX { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; + opt_drop_behavior: CASCADE { $$ = DROP_CASCADE; } | RESTRICT { $$ = DROP_RESTRICT; } | /* EMPTY */ { $$ = DROP_RESTRICT; /* default */ } ; +opt_utility_option_list: + '(' utility_option_list ')' { $$ = $2; } + | /* EMPTY */ { $$ = NULL; } + ; + +utility_option_list: + utility_option_elem + { + $$ = list_make1($1); + } + | utility_option_list ',' utility_option_elem + { + $$ = lappend($1, $3); + } + ; + +utility_option_elem: + utility_option_name utility_option_arg + { + $$ = makeDefElem($1, $2, @1); + } + ; + +utility_option_name: + NonReservedWord { $$ = $1; } + | analyze_keyword { $$ = "analyze"; } + | FORMAT_LA { $$ = "format"; } + ; + +utility_option_arg: + opt_boolean_or_string { $$ = (Node *) makeString($1); } + | NumericOnly { $$ = (Node *) $1; } + | /* EMPTY */ { $$ = NULL; } + ; + /***************************************************************************** * * CALL statement @@ -1649,8 +1740,11 @@ OptSchemaEltList: schema_stmt: CreateStmt | IndexStmt + | CreateDomainStmt + | CreateFunctionStmt | CreateSeqStmt | CreateTrigStmt + | DefineStmt | GrantStmt | ViewStmt ; @@ -1750,6 +1844,26 @@ generic_set: n->location = @3; $$ = n; } + | var_name TO NULL_P + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = $1; + n->args = list_make1(makeNullAConst(@3)); + n->location = @3; + $$ = n; + } + | var_name '=' NULL_P + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = $1; + n->args = list_make1(makeNullAConst(@3)); + n->location = @3; + $$ = n; + } | var_name TO DEFAULT { VariableSetStmt *n = makeNode(VariableSetStmt); @@ -2130,11 +2244,12 @@ constraints_set_mode: * Checkpoint statement */ CheckPointStmt: - CHECKPOINT + CHECKPOINT opt_utility_option_list { CheckPointStmt *n = makeNode(CheckPointStmt); $$ = (Node *) n; + n->options = $2; } ; @@ -2423,6 +2538,23 @@ alter_table_cmds: | alter_table_cmds ',' alter_table_cmd { $$ = lappend($1, $3); } ; +partitions_list: + SinglePartitionSpec { $$ = list_make1($1); } + | partitions_list ',' SinglePartitionSpec { $$ = lappend($1, $3); } + ; + +SinglePartitionSpec: + PARTITION qualified_name PartitionBoundSpec + { + SinglePartitionSpec *n = makeNode(SinglePartitionSpec); + + n->name = $2; + n->bound = $3; + + $$ = n; + } + ; + partition_cmd: /* ALTER TABLE ATTACH PARTITION FOR VALUES */ ATTACH PARTITION qualified_name PartitionBoundSpec @@ -2433,6 +2565,7 @@ partition_cmd: n->subtype = AT_AttachPartition; cmd->name = $3; cmd->bound = $4; + cmd->partlist = NIL; cmd->concurrent = false; n->def = (Node *) cmd; @@ -2447,6 +2580,7 @@ partition_cmd: n->subtype = AT_DetachPartition; cmd->name = $3; cmd->bound = NULL; + cmd->partlist = NIL; cmd->concurrent = $4; n->def = (Node *) cmd; @@ -2460,6 +2594,35 @@ partition_cmd: n->subtype = AT_DetachPartitionFinalize; cmd->name = $3; cmd->bound = NULL; + cmd->partlist = NIL; + cmd->concurrent = false; + n->def = (Node *) cmd; + $$ = (Node *) n; + } + /* ALTER TABLE SPLIT PARTITION INTO () */ + | SPLIT PARTITION qualified_name INTO '(' partitions_list ')' + { + AlterTableCmd *n = makeNode(AlterTableCmd); + PartitionCmd *cmd = makeNode(PartitionCmd); + + n->subtype = AT_SplitPartition; + cmd->name = $3; + cmd->bound = NULL; + cmd->partlist = $6; + cmd->concurrent = false; + n->def = (Node *) cmd; + $$ = (Node *) n; + } + /* ALTER TABLE MERGE PARTITIONS () INTO */ + | MERGE PARTITIONS '(' qualified_name_list ')' INTO qualified_name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + PartitionCmd *cmd = makeNode(PartitionCmd); + + n->subtype = AT_MergePartitions; + cmd->name = $7; + cmd->bound = NULL; + cmd->partlist = $4; cmd->concurrent = false; n->def = (Node *) cmd; $$ = (Node *) n; @@ -2476,6 +2639,7 @@ index_partition_cmd: n->subtype = AT_AttachPartition; cmd->name = $3; cmd->bound = NULL; + cmd->partlist = NIL; cmd->concurrent = false; n->def = (Node *) cmd; @@ -3466,7 +3630,7 @@ ClosePortalStmt: * COPY ( query ) TO file [WITH] [(options)] * * where 'query' can be one of: - * { SELECT | UPDATE | INSERT | DELETE } + * { SELECT | UPDATE | INSERT | DELETE | MERGE } * * and 'file' can be one of: * { PROGRAM 'command' | STDIN | STDOUT | 'filename' } @@ -3507,6 +3671,7 @@ CopyStmt: COPY opt_binary qualified_name opt_column_list ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("WHERE clause not allowed with COPY TO"), + errhint("Try the COPY (SELECT ... WHERE ...) TO variant."), parser_errposition(@11))); n->options = NIL; @@ -3593,6 +3758,10 @@ copy_opt_item: { $$ = makeDefElem("format", (Node *) makeString("csv"), @1); } + | JSON + { + $$ = makeDefElem("format", (Node *) makeString("json"), @1); + } | HEADER_P { $$ = makeDefElem("header", (Node *) makeBoolean(true), @1); @@ -3675,6 +3844,10 @@ copy_generic_opt_elem: { $$ = makeDefElem($1, $2, @1); } + | FORMAT_LA copy_generic_opt_arg + { + $$ = makeDefElem("format", $2, @1); + } ; copy_generic_opt_arg: @@ -4593,19 +4766,19 @@ OptWhereClause: key_actions: key_update { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); n->updateAction = $1; - n->deleteAction = palloc(sizeof(KeyAction)); + n->deleteAction = palloc_object(KeyAction); n->deleteAction->action = FKCONSTR_ACTION_NOACTION; n->deleteAction->cols = NIL; $$ = n; } | key_delete { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); - n->updateAction = palloc(sizeof(KeyAction)); + n->updateAction = palloc_object(KeyAction); n->updateAction->action = FKCONSTR_ACTION_NOACTION; n->updateAction->cols = NIL; n->deleteAction = $1; @@ -4613,7 +4786,7 @@ key_actions: } | key_update key_delete { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); n->updateAction = $1; n->deleteAction = $2; @@ -4621,7 +4794,7 @@ key_actions: } | key_delete key_update { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); n->updateAction = $2; n->deleteAction = $1; @@ -4629,12 +4802,12 @@ key_actions: } | /*EMPTY*/ { - KeyActions *n = palloc(sizeof(KeyActions)); + KeyActions *n = palloc_object(KeyActions); - n->updateAction = palloc(sizeof(KeyAction)); + n->updateAction = palloc_object(KeyAction); n->updateAction->action = FKCONSTR_ACTION_NOACTION; n->updateAction->cols = NIL; - n->deleteAction = palloc(sizeof(KeyAction)); + n->deleteAction = palloc_object(KeyAction); n->deleteAction->action = FKCONSTR_ACTION_NOACTION; n->deleteAction->cols = NIL; $$ = n; @@ -4662,7 +4835,7 @@ key_delete: ON DELETE_P key_action key_action: NO ACTION { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_NOACTION; n->cols = NIL; @@ -4670,7 +4843,7 @@ key_action: } | RESTRICT { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_RESTRICT; n->cols = NIL; @@ -4678,7 +4851,7 @@ key_action: } | CASCADE { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_CASCADE; n->cols = NIL; @@ -4686,7 +4859,7 @@ key_action: } | SET NULL_P opt_column_list { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_SETNULL; n->cols = $3; @@ -4694,7 +4867,7 @@ key_action: } | SET DEFAULT opt_column_list { - KeyAction *n = palloc(sizeof(KeyAction)); + KeyAction *n = palloc_object(KeyAction); n->action = FKCONSTR_ACTION_SETDEFAULT; n->cols = $3; @@ -5566,6 +5739,8 @@ fdw_option: | NO HANDLER { $$ = makeDefElem("handler", NULL, @1); } | VALIDATOR handler_name { $$ = makeDefElem("validator", (Node *) $2, @1); } | NO VALIDATOR { $$ = makeDefElem("validator", NULL, @1); } + | CONNECTION handler_name { $$ = makeDefElem("connection", (Node *) $2, @1); } + | NO CONNECTION { $$ = makeDefElem("connection", NULL, @1); } ; fdw_options: @@ -5891,7 +6066,7 @@ import_qualification_type: import_qualification: import_qualification_type '(' relation_expr_list ')' { - ImportQual *n = (ImportQual *) palloc(sizeof(ImportQual)); + ImportQual *n = palloc_object(ImportQual); n->type = $1; n->table_names = $3; @@ -5899,7 +6074,7 @@ import_qualification: } | /*EMPTY*/ { - ImportQual *n = (ImportQual *) palloc(sizeof(ImportQual)); + ImportQual *n = palloc_object(ImportQual); n->type = FDW_IMPORT_SCHEMA_ALL; n->table_names = NIL; $$ = n; @@ -6144,6 +6319,26 @@ CreateTrigStmt: EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')' { CreateTrigStmt *n = makeNode(CreateTrigStmt); + bool dummy; + + if (($11 & CAS_NOT_VALID) != 0) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constraint triggers cannot be marked %s", + "NOT VALID"), + parser_errposition(@11)); + if (($11 & CAS_NO_INHERIT) != 0) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constraint triggers cannot be marked %s", + "NO INHERIT"), + parser_errposition(@11)); + if (($11 & CAS_NOT_ENFORCED) != 0) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constraint triggers cannot be marked %s", + "NOT ENFORCED"), + parser_errposition(@11)); n->replace = $2; if (n->replace) /* not supported, see CreateTrigger */ @@ -6163,7 +6358,7 @@ CreateTrigStmt: n->whenClause = $15; n->transitionRels = NIL; processCASbits($11, @11, "TRIGGER", - &n->deferrable, &n->initdeferred, NULL, + &n->deferrable, &n->initdeferred, &dummy, NULL, NULL, yyscanner); n->constrrel = $10; $$ = (Node *) n; @@ -7158,6 +7353,7 @@ object_type_any_name: | MATERIALIZED VIEW { $$ = OBJECT_MATVIEW; } | INDEX { $$ = OBJECT_INDEX; } | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; } + | PROPERTY GRAPH { $$ = OBJECT_PROPGRAPH; } | COLLATION { $$ = OBJECT_COLLATION; } | CONVERSION_P { $$ = OBJECT_CONVERSION; } | STATISTICS { $$ = OBJECT_STATISTIC_EXT; } @@ -7586,6 +7782,8 @@ fetch_args: cursor_name n->portalname = $1; n->direction = FETCH_FORWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_NONE; $$ = (Node *) n; } | from_in cursor_name @@ -7595,6 +7793,19 @@ fetch_args: cursor_name n->portalname = $2; n->direction = FETCH_FORWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_NONE; + $$ = (Node *) n; + } + | SignedIconst opt_from_in cursor_name + { + FetchStmt *n = makeNode(FetchStmt); + + n->portalname = $3; + n->direction = FETCH_FORWARD; + n->howMany = $1; + n->location = @1; + n->direction_keyword = FETCH_KEYWORD_NONE; $$ = (Node *) n; } | NEXT opt_from_in cursor_name @@ -7604,6 +7815,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_NEXT; $$ = (Node *) n; } | PRIOR opt_from_in cursor_name @@ -7613,6 +7826,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_BACKWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_PRIOR; $$ = (Node *) n; } | FIRST_P opt_from_in cursor_name @@ -7622,6 +7837,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_ABSOLUTE; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_FIRST; $$ = (Node *) n; } | LAST_P opt_from_in cursor_name @@ -7631,6 +7848,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_ABSOLUTE; n->howMany = -1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_LAST; $$ = (Node *) n; } | ABSOLUTE_P SignedIconst opt_from_in cursor_name @@ -7640,6 +7859,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_ABSOLUTE; n->howMany = $2; + n->location = @2; + n->direction_keyword = FETCH_KEYWORD_ABSOLUTE; $$ = (Node *) n; } | RELATIVE_P SignedIconst opt_from_in cursor_name @@ -7649,15 +7870,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_RELATIVE; n->howMany = $2; - $$ = (Node *) n; - } - | SignedIconst opt_from_in cursor_name - { - FetchStmt *n = makeNode(FetchStmt); - - n->portalname = $3; - n->direction = FETCH_FORWARD; - n->howMany = $1; + n->location = @2; + n->direction_keyword = FETCH_KEYWORD_RELATIVE; $$ = (Node *) n; } | ALL opt_from_in cursor_name @@ -7667,6 +7881,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = FETCH_ALL; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_ALL; $$ = (Node *) n; } | FORWARD opt_from_in cursor_name @@ -7676,6 +7892,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_FORWARD; $$ = (Node *) n; } | FORWARD SignedIconst opt_from_in cursor_name @@ -7685,6 +7903,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_FORWARD; n->howMany = $2; + n->location = @2; + n->direction_keyword = FETCH_KEYWORD_FORWARD; $$ = (Node *) n; } | FORWARD ALL opt_from_in cursor_name @@ -7694,6 +7914,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_FORWARD; n->howMany = FETCH_ALL; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_FORWARD_ALL; $$ = (Node *) n; } | BACKWARD opt_from_in cursor_name @@ -7703,6 +7925,8 @@ fetch_args: cursor_name n->portalname = $3; n->direction = FETCH_BACKWARD; n->howMany = 1; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_BACKWARD; $$ = (Node *) n; } | BACKWARD SignedIconst opt_from_in cursor_name @@ -7712,6 +7936,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_BACKWARD; n->howMany = $2; + n->location = @2; + n->direction_keyword = FETCH_KEYWORD_BACKWARD; $$ = (Node *) n; } | BACKWARD ALL opt_from_in cursor_name @@ -7721,6 +7947,8 @@ fetch_args: cursor_name n->portalname = $4; n->direction = FETCH_BACKWARD; n->howMany = FETCH_ALL; + n->location = -1; + n->direction_keyword = FETCH_KEYWORD_BACKWARD_ALL; $$ = (Node *) n; } ; @@ -7900,7 +8128,7 @@ parameter_name: privilege_target: qualified_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TABLE; @@ -7909,7 +8137,7 @@ privilege_target: } | TABLE qualified_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TABLE; @@ -7918,7 +8146,7 @@ privilege_target: } | SEQUENCE qualified_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_SEQUENCE; @@ -7927,7 +8155,7 @@ privilege_target: } | FOREIGN DATA_P WRAPPER name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_FDW; @@ -7936,7 +8164,7 @@ privilege_target: } | FOREIGN SERVER name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_FOREIGN_SERVER; @@ -7945,7 +8173,7 @@ privilege_target: } | FUNCTION function_with_argtypes_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_FUNCTION; @@ -7954,7 +8182,7 @@ privilege_target: } | PROCEDURE function_with_argtypes_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_PROCEDURE; @@ -7963,7 +8191,7 @@ privilege_target: } | ROUTINE function_with_argtypes_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_ROUTINE; @@ -7972,7 +8200,7 @@ privilege_target: } | DATABASE name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_DATABASE; @@ -7981,7 +8209,7 @@ privilege_target: } | DOMAIN_P any_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_DOMAIN; @@ -7990,7 +8218,7 @@ privilege_target: } | LANGUAGE name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_LANGUAGE; @@ -7999,7 +8227,7 @@ privilege_target: } | LARGE_P OBJECT_P NumericOnly_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_LARGEOBJECT; @@ -8008,15 +8236,24 @@ privilege_target: } | PARAMETER parameter_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_PARAMETER_ACL; n->objs = $2; $$ = n; } + | PROPERTY GRAPH qualified_name_list + { + PrivTarget *n = palloc_object(PrivTarget); + + n->targtype = ACL_TARGET_OBJECT; + n->objtype = OBJECT_PROPGRAPH; + n->objs = $3; + $$ = n; + } | SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_SCHEMA; @@ -8025,7 +8262,7 @@ privilege_target: } | TABLESPACE name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TABLESPACE; @@ -8034,7 +8271,7 @@ privilege_target: } | TYPE_P any_name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TYPE; @@ -8043,7 +8280,7 @@ privilege_target: } | ALL TABLES IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_TABLE; @@ -8052,7 +8289,7 @@ privilege_target: } | ALL SEQUENCES IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_SEQUENCE; @@ -8061,7 +8298,7 @@ privilege_target: } | ALL FUNCTIONS IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_FUNCTION; @@ -8070,7 +8307,7 @@ privilege_target: } | ALL PROCEDURES IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_PROCEDURE; @@ -8079,7 +8316,7 @@ privilege_target: } | ALL ROUTINES IN_P SCHEMA name_list { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + PrivTarget *n = palloc_object(PrivTarget); n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_ROUTINE; @@ -8388,6 +8625,7 @@ index_elem_options: $$->opclassopts = NIL; $$->ordering = $3; $$->nulls_ordering = $4; + /* location will be filled in index_elem production */ } | opt_collate any_name reloptions opt_asc_desc opt_nulls_order { @@ -8400,6 +8638,7 @@ index_elem_options: $$->opclassopts = $3; $$->ordering = $4; $$->nulls_ordering = $5; + /* location will be filled in index_elem production */ } ; @@ -8412,16 +8651,19 @@ index_elem: ColId index_elem_options { $$ = $2; $$->name = $1; + $$->location = @1; } | func_expr_windowless index_elem_options { $$ = $2; $$->expr = $1; + $$->location = @1; } | '(' a_expr ')' index_elem_options { $$ = $4; $$->expr = $2; + $$->location = @1; } ; @@ -9338,6 +9580,370 @@ opt_if_exists: IF_P EXISTS { $$ = true; } ; +/***************************************************************************** + * + * CREATE PROPERTY GRAPH + * ALTER PROPERTY GRAPH + * + *****************************************************************************/ + +CreatePropGraphStmt: CREATE OptTemp PROPERTY GRAPH qualified_name opt_vertex_tables_clause opt_edge_tables_clause + { + CreatePropGraphStmt *n = makeNode(CreatePropGraphStmt); + + n->pgname = $5; + n->pgname->relpersistence = $2; + n->vertex_tables = $6; + n->edge_tables = $7; + + $$ = (Node *)n; + } + ; + +opt_vertex_tables_clause: + vertex_tables_clause { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +vertex_tables_clause: + vertex_synonym TABLES '(' vertex_table_list ')' { $$ = $4; } + ; + +vertex_synonym: NODE | VERTEX + ; + +vertex_table_list: vertex_table_definition { $$ = list_make1($1); } + | vertex_table_list ',' vertex_table_definition { $$ = lappend($1, $3); } + ; + +vertex_table_definition: qualified_name opt_propgraph_table_alias opt_graph_table_key_clause + opt_element_table_label_and_properties + { + PropGraphVertex *n = makeNode(PropGraphVertex); + + $1->alias = $2; + n->vtable = $1; + n->vkey = $3; + n->labels = $4; + n->location = @1; + + $$ = (Node *) n; + } + ; + +opt_propgraph_table_alias: + AS name + { + $$ = makeNode(Alias); + $$->aliasname = $2; + } + | /*EMPTY*/ { $$ = NULL; } + ; + +opt_graph_table_key_clause: + KEY '(' columnList ')' { $$ = $3; } + | /*EMPTY*/ { $$ = NIL; } + ; + +opt_edge_tables_clause: + edge_tables_clause { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +edge_tables_clause: + edge_synonym TABLES '(' edge_table_list ')' { $$ = $4; } + ; + +edge_synonym: EDGE | RELATIONSHIP + ; + +edge_table_list: edge_table_definition { $$ = list_make1($1); } + | edge_table_list ',' edge_table_definition { $$ = lappend($1, $3); } + ; + +edge_table_definition: qualified_name opt_propgraph_table_alias opt_graph_table_key_clause + source_vertex_table destination_vertex_table opt_element_table_label_and_properties + { + PropGraphEdge *n = makeNode(PropGraphEdge); + + $1->alias = $2; + n->etable = $1; + n->ekey = $3; + n->esrckey = linitial($4); + n->esrcvertex = lsecond($4); + n->esrcvertexcols = lthird($4); + n->edestkey = linitial($5); + n->edestvertex = lsecond($5); + n->edestvertexcols = lthird($5); + n->labels = $6; + n->location = @1; + + $$ = (Node *) n; + } + ; + +source_vertex_table: SOURCE name + { + $$ = list_make3(NULL, $2, NULL); + } + | SOURCE KEY '(' columnList ')' REFERENCES name '(' columnList ')' + { + $$ = list_make3($4, $7, $9); + } + ; + +destination_vertex_table: DESTINATION name + { + $$ = list_make3(NULL, $2, NULL); + } + | DESTINATION KEY '(' columnList ')' REFERENCES name '(' columnList ')' + { + $$ = list_make3($4, $7, $9); + } + ; + +opt_element_table_label_and_properties: + element_table_properties + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + + lp->properties = (PropGraphProperties *) $1; + lp->location = @1; + + $$ = list_make1(lp); + } + | label_and_properties_list + { + $$ = $1; + } + | /*EMPTY*/ + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->all = true; + pr->location = -1; + lp->properties = pr; + lp->location = -1; + + $$ = list_make1(lp); + } + ; + +element_table_properties: + NO PROPERTIES + { + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->properties = NIL; + pr->location = @1; + + $$ = (Node *) pr; + } + | PROPERTIES ALL COLUMNS + /* + * SQL standard also allows "PROPERTIES ARE ALL COLUMNS", but that + * would require making ARE a keyword, which seems a bit much for + * such a marginal use. Could be added later if needed. + */ + { + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->all = true; + pr->location = @1; + + $$ = (Node *) pr; + } + | PROPERTIES '(' labeled_expr_list ')' + { + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->properties = $3; + pr->location = @1; + + $$ = (Node *) pr; + } + ; + +label_and_properties_list: + label_and_properties + { + $$ = list_make1($1); + } + | label_and_properties_list label_and_properties + { + $$ = lappend($1, $2); + } + ; + +label_and_properties: + element_table_label_clause + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->all = true; + pr->location = -1; + + lp->label = $1; + lp->properties = pr; + lp->location = @1; + + $$ = (Node *) lp; + } + | element_table_label_clause element_table_properties + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + + lp->label = $1; + lp->properties = (PropGraphProperties *) $2; + lp->location = @1; + + $$ = (Node *) lp; + } + ; + +element_table_label_clause: + LABEL name + { + $$ = $2; + } + | DEFAULT LABEL + { + $$ = NULL; + } + ; + +AlterPropGraphStmt: + ALTER PROPERTY GRAPH qualified_name ADD_P vertex_tables_clause + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->add_vertex_tables = $6; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ADD_P vertex_tables_clause ADD_P edge_tables_clause + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->add_vertex_tables = $6; + n->add_edge_tables = $8; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ADD_P edge_tables_clause + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->add_edge_tables = $6; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name DROP vertex_synonym TABLES '(' name_list ')' opt_drop_behavior + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->drop_vertex_tables = $9; + n->drop_behavior = $11; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name DROP edge_synonym TABLES '(' name_list ')' opt_drop_behavior + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->drop_edge_tables = $9; + n->drop_behavior = $11; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ALTER vertex_or_edge TABLE name + add_label_list + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->element_kind = $6; + n->element_alias = $8; + n->add_labels = $9; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ALTER vertex_or_edge TABLE name + DROP LABEL name opt_drop_behavior + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->element_kind = $6; + n->element_alias = $8; + n->drop_label = $11; + n->drop_behavior = $12; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ALTER vertex_or_edge TABLE name + ALTER LABEL name ADD_P PROPERTIES '(' labeled_expr_list ')' + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + PropGraphProperties *pr = makeNode(PropGraphProperties); + + n->pgname = $4; + n->element_kind = $6; + n->element_alias = $8; + n->alter_label = $11; + + pr->properties = $15; + pr->location = @13; + n->add_properties = pr; + + $$ = (Node *) n; + } + | ALTER PROPERTY GRAPH qualified_name ALTER vertex_or_edge TABLE name + ALTER LABEL name DROP PROPERTIES '(' name_list ')' opt_drop_behavior + { + AlterPropGraphStmt *n = makeNode(AlterPropGraphStmt); + + n->pgname = $4; + n->element_kind = $6; + n->element_alias = $8; + n->alter_label = $11; + n->drop_properties = $15; + n->drop_behavior = $17; + + $$ = (Node *) n; + } + ; + +vertex_or_edge: + vertex_synonym { $$ = PROPGRAPH_ELEMENT_KIND_VERTEX; } + | edge_synonym { $$ = PROPGRAPH_ELEMENT_KIND_EDGE; } + ; + +add_label_list: + add_label { $$ = list_make1($1); } + | add_label_list add_label { $$ = lappend($1, $2); } + ; + +add_label: ADD_P LABEL name element_table_properties + { + PropGraphLabelAndProperties *lp = makeNode(PropGraphLabelAndProperties); + + lp->label = $3; + lp->properties = (PropGraphProperties *) $4; + lp->location = @1; + + $$ = (Node *) lp; + } + ; + + /***************************************************************************** * * CREATE TRANSFORM / DROP TRANSFORM @@ -9398,7 +10004,7 @@ DropTransformStmt: DROP TRANSFORM opt_if_exists FOR Typename LANGUAGE name opt_d *****************************************************************************/ ReindexStmt: - REINDEX opt_reindex_option_list reindex_target_relation opt_concurrently qualified_name + REINDEX opt_utility_option_list reindex_target_relation opt_concurrently qualified_name { ReindexStmt *n = makeNode(ReindexStmt); @@ -9411,7 +10017,7 @@ ReindexStmt: makeDefElem("concurrently", NULL, @4)); $$ = (Node *) n; } - | REINDEX opt_reindex_option_list SCHEMA opt_concurrently name + | REINDEX opt_utility_option_list SCHEMA opt_concurrently name { ReindexStmt *n = makeNode(ReindexStmt); @@ -9424,7 +10030,7 @@ ReindexStmt: makeDefElem("concurrently", NULL, @4)); $$ = (Node *) n; } - | REINDEX opt_reindex_option_list reindex_target_all opt_concurrently opt_single_name + | REINDEX opt_utility_option_list reindex_target_all opt_concurrently opt_single_name { ReindexStmt *n = makeNode(ReindexStmt); @@ -9446,10 +10052,6 @@ reindex_target_all: SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; } | DATABASE { $$ = REINDEX_OBJECT_DATABASE; } ; -opt_reindex_option_list: - '(' utility_option_list ')' { $$ = $2; } - | /* EMPTY */ { $$ = NULL; } - ; /***************************************************************************** * @@ -9638,6 +10240,16 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name n->missing_ok = false; $$ = (Node *) n; } + | ALTER PROPERTY GRAPH qualified_name RENAME TO name + { + RenameStmt *n = makeNode(RenameStmt); + + n->renameType = OBJECT_PROPGRAPH; + n->relation = $4; + n->newname = $7; + n->missing_ok = false; + $$ = (Node *)n; + } | ALTER PUBLICATION name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); @@ -10263,6 +10875,26 @@ AlterObjectSchemaStmt: n->missing_ok = false; $$ = (Node *) n; } + | ALTER PROPERTY GRAPH qualified_name SET SCHEMA name + { + AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + + n->objectType = OBJECT_PROPGRAPH; + n->relation = $4; + n->newschema = $7; + n->missing_ok = false; + $$ = (Node *)n; + } + | ALTER PROPERTY GRAPH IF_P EXISTS qualified_name SET SCHEMA name + { + AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + + n->objectType = OBJECT_PROPGRAPH; + n->relation = $6; + n->newschema = $9; + n->missing_ok = true; + $$ = (Node *)n; + } | ALTER ROUTINE function_with_argtypes SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); @@ -10606,6 +11238,15 @@ AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec n->newowner = $6; $$ = (Node *) n; } + | ALTER PROPERTY GRAPH qualified_name OWNER TO RoleSpec + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + + n->objectType = OBJECT_PROPGRAPH; + n->relation = $4; + n->newowner = $7; + $$ = (Node *) n; + } | ALTER ROUTINE function_with_argtypes OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); @@ -10721,7 +11362,12 @@ AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec * * CREATE PUBLICATION name [WITH options] * - * CREATE PUBLICATION FOR ALL TABLES [WITH options] + * CREATE PUBLICATION FOR ALL pub_all_obj_type [, ...] [WITH options] + * + * pub_all_obj_type is one of: + * + * TABLES [EXCEPT (TABLE table [, ...] )] + * SEQUENCES * * CREATE PUBLICATION FOR pub_obj [, ...] [WITH options] * @@ -10741,13 +11387,16 @@ CreatePublicationStmt: n->options = $4; $$ = (Node *) n; } - | CREATE PUBLICATION name FOR ALL TABLES opt_definition + | CREATE PUBLICATION name FOR pub_all_obj_type_list opt_definition { CreatePublicationStmt *n = makeNode(CreatePublicationStmt); n->pubname = $3; - n->options = $7; - n->for_all_tables = true; + preprocess_pub_all_objtype_list($5, &n->pubobjects, + &n->for_all_tables, + &n->for_all_sequences, + yyscanner); + n->options = $6; $$ = (Node *) n; } | CREATE PUBLICATION name FOR pub_obj_list opt_definition @@ -10859,6 +11508,51 @@ pub_obj_list: PublicationObjSpec { $$ = lappend($1, $3); } ; +opt_pub_except_clause: + EXCEPT '(' TABLE pub_except_obj_list ')' { $$ = $4; } + | /*EMPTY*/ { $$ = NIL; } + ; + +PublicationAllObjSpec: + ALL TABLES opt_pub_except_clause + { + $$ = makeNode(PublicationAllObjSpec); + $$->pubobjtype = PUBLICATION_ALL_TABLES; + $$->except_tables = $3; + $$->location = @1; + } + | ALL SEQUENCES + { + $$ = makeNode(PublicationAllObjSpec); + $$->pubobjtype = PUBLICATION_ALL_SEQUENCES; + $$->location = @1; + } + ; + +pub_all_obj_type_list: PublicationAllObjSpec + { $$ = list_make1($1); } + | pub_all_obj_type_list ',' PublicationAllObjSpec + { $$ = lappend($1, $3); } + ; + +PublicationExceptObjSpec: + relation_expr + { + $$ = makeNode(PublicationObjSpec); + $$->pubobjtype = PUBLICATIONOBJ_EXCEPT_TABLE; + $$->pubtable = makeNode(PublicationTable); + $$->pubtable->except = true; + $$->pubtable->relation = $1; + $$->location = @1; + } + ; + +pub_except_obj_list: PublicationExceptObjSpec + { $$ = list_make1($1); } + | pub_except_obj_list ',' opt_table PublicationExceptObjSpec + { $$ = lappend($1, $4); } + ; + /***************************************************************************** * * ALTER PUBLICATION name SET ( options ) @@ -10869,11 +11563,18 @@ pub_obj_list: PublicationObjSpec * * ALTER PUBLICATION name SET pub_obj [, ...] * + * ALTER PUBLICATION name SET pub_all_obj_type [, ...] + * * pub_obj is one of: * * TABLE table_name [, ...] * TABLES IN SCHEMA schema_name [, ...] * + * pub_all_obj_type is one of: + * + * ALL TABLES [ EXCEPT ( TABLE table_name [, ...] ) ] + * ALL SEQUENCES + * *****************************************************************************/ AlterPublicationStmt: @@ -10883,6 +11584,7 @@ AlterPublicationStmt: n->pubname = $3; n->options = $5; + n->for_all_tables = false; $$ = (Node *) n; } | ALTER PUBLICATION name ADD_P pub_obj_list @@ -10893,6 +11595,7 @@ AlterPublicationStmt: n->pubobjects = $5; preprocess_pubobj_list(n->pubobjects, yyscanner); n->action = AP_AddObjects; + n->for_all_tables = false; $$ = (Node *) n; } | ALTER PUBLICATION name SET pub_obj_list @@ -10903,6 +11606,19 @@ AlterPublicationStmt: n->pubobjects = $5; preprocess_pubobj_list(n->pubobjects, yyscanner); n->action = AP_SetObjects; + n->for_all_tables = false; + $$ = (Node *) n; + } + | ALTER PUBLICATION name SET pub_all_obj_type_list + { + AlterPublicationStmt *n = makeNode(AlterPublicationStmt); + + n->pubname = $3; + n->action = AP_SetObjects; + preprocess_pub_all_objtype_list($5, &n->pubobjects, + &n->for_all_tables, + &n->for_all_sequences, + yyscanner); $$ = (Node *) n; } | ALTER PUBLICATION name DROP pub_obj_list @@ -10913,6 +11629,7 @@ AlterPublicationStmt: n->pubobjects = $5; preprocess_pubobj_list(n->pubobjects, yyscanner); n->action = AP_DropObjects; + n->for_all_tables = false; $$ = (Node *) n; } ; @@ -10934,6 +11651,16 @@ CreateSubscriptionStmt: n->options = $8; $$ = (Node *) n; } + | CREATE SUBSCRIPTION name SERVER name PUBLICATION name_list opt_definition + { + CreateSubscriptionStmt *n = + makeNode(CreateSubscriptionStmt); + n->subname = $3; + n->servername = $5; + n->publication = $7; + n->options = $8; + $$ = (Node *) n; + } ; /***************************************************************************** @@ -10950,27 +11677,46 @@ AlterSubscriptionStmt: n->kind = ALTER_SUBSCRIPTION_OPTIONS; n->subname = $3; - n->options = $5; + n->options = $5; + $$ = (Node *) n; + } + | ALTER SUBSCRIPTION name CONNECTION Sconst + { + AlterSubscriptionStmt *n = + makeNode(AlterSubscriptionStmt); + + n->kind = ALTER_SUBSCRIPTION_CONNECTION; + n->subname = $3; + n->conninfo = $5; + $$ = (Node *) n; + } + | ALTER SUBSCRIPTION name SERVER name + { + AlterSubscriptionStmt *n = + makeNode(AlterSubscriptionStmt); + + n->kind = ALTER_SUBSCRIPTION_SERVER; + n->subname = $3; + n->servername = $5; $$ = (Node *) n; } - | ALTER SUBSCRIPTION name CONNECTION Sconst + | ALTER SUBSCRIPTION name REFRESH PUBLICATION opt_definition { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_CONNECTION; + n->kind = ALTER_SUBSCRIPTION_REFRESH_PUBLICATION; n->subname = $3; - n->conninfo = $5; + n->options = $6; $$ = (Node *) n; } - | ALTER SUBSCRIPTION name REFRESH PUBLICATION opt_definition + | ALTER SUBSCRIPTION name REFRESH SEQUENCES { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_REFRESH; + n->kind = ALTER_SUBSCRIPTION_REFRESH_SEQUENCES; n->subname = $3; - n->options = $6; $$ = (Node *) n; } | ALTER SUBSCRIPTION name ADD_P PUBLICATION name_list opt_definition @@ -11736,7 +12482,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'T'; + n->subtype = AD_AlterDefault; n->typeName = $3; n->def = $4; $$ = (Node *) n; @@ -11746,7 +12492,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'N'; + n->subtype = AD_DropNotNull; n->typeName = $3; $$ = (Node *) n; } @@ -11755,7 +12501,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'O'; + n->subtype = AD_SetNotNull; n->typeName = $3; $$ = (Node *) n; } @@ -11764,7 +12510,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'C'; + n->subtype = AD_AddConstraint; n->typeName = $3; n->def = $5; $$ = (Node *) n; @@ -11774,7 +12520,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'X'; + n->subtype = AD_DropConstraint; n->typeName = $3; n->name = $6; n->behavior = $7; @@ -11786,7 +12532,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'X'; + n->subtype = AD_DropConstraint; n->typeName = $3; n->name = $8; n->behavior = $9; @@ -11798,7 +12544,7 @@ AlterDomainStmt: { AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'V'; + n->subtype = AD_ValidateConstraint; n->typeName = $3; n->name = $6; $$ = (Node *) n; @@ -11931,65 +12677,110 @@ CreateConversionStmt: /***************************************************************************** * * QUERY: + * REPACK [ (options) ] [ [ ] [ USING INDEX ] ] + * + * obsolete variants: * CLUSTER (options) [ [ USING ] ] * CLUSTER [VERBOSE] [ [ USING ] ] * CLUSTER [VERBOSE] ON (for pre-8.3) * *****************************************************************************/ -ClusterStmt: - CLUSTER '(' utility_option_list ')' qualified_name cluster_index_specification +RepackStmt: + REPACK opt_utility_option_list vacuum_relation USING INDEX name { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); - n->relation = $5; + n->command = REPACK_COMMAND_REPACK; + n->relation = (VacuumRelation *) $3; n->indexname = $6; - n->params = $3; + n->usingindex = true; + n->params = $2; + $$ = (Node *) n; + } + | REPACK opt_utility_option_list vacuum_relation opt_usingindex + { + RepackStmt *n = makeNode(RepackStmt); + + n->command = REPACK_COMMAND_REPACK; + n->relation = (VacuumRelation *) $3; + n->indexname = NULL; + n->usingindex = $4; + n->params = $2; $$ = (Node *) n; } - | CLUSTER '(' utility_option_list ')' + | REPACK opt_utility_option_list opt_usingindex { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); + n->command = REPACK_COMMAND_REPACK; n->relation = NULL; n->indexname = NULL; + n->usingindex = $3; + n->params = $2; + $$ = (Node *) n; + } + | CLUSTER '(' utility_option_list ')' qualified_name cluster_index_specification + { + RepackStmt *n = makeNode(RepackStmt); + + n->command = REPACK_COMMAND_CLUSTER; + n->relation = makeNode(VacuumRelation); + n->relation->relation = $5; + n->indexname = $6; + n->usingindex = true; n->params = $3; $$ = (Node *) n; } + | CLUSTER opt_utility_option_list + { + RepackStmt *n = makeNode(RepackStmt); + + n->command = REPACK_COMMAND_CLUSTER; + n->relation = NULL; + n->indexname = NULL; + n->usingindex = true; + n->params = $2; + $$ = (Node *) n; + } /* unparenthesized VERBOSE kept for pre-14 compatibility */ | CLUSTER opt_verbose qualified_name cluster_index_specification { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); - n->relation = $3; + n->command = REPACK_COMMAND_CLUSTER; + n->relation = makeNode(VacuumRelation); + n->relation->relation = $3; n->indexname = $4; - n->params = NIL; + n->usingindex = true; if ($2) - n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + n->params = list_make1(makeDefElem("verbose", NULL, @2)); $$ = (Node *) n; } /* unparenthesized VERBOSE kept for pre-17 compatibility */ - | CLUSTER opt_verbose + | CLUSTER VERBOSE { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); + n->command = REPACK_COMMAND_CLUSTER; n->relation = NULL; n->indexname = NULL; - n->params = NIL; - if ($2) - n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + n->usingindex = true; + n->params = list_make1(makeDefElem("verbose", NULL, @2)); $$ = (Node *) n; } /* kept for pre-8.3 compatibility */ | CLUSTER opt_verbose name ON qualified_name { - ClusterStmt *n = makeNode(ClusterStmt); + RepackStmt *n = makeNode(RepackStmt); - n->relation = $5; + n->command = REPACK_COMMAND_CLUSTER; + n->relation = makeNode(VacuumRelation); + n->relation->relation = $5; n->indexname = $3; - n->params = NIL; + n->usingindex = true; if ($2) - n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + n->params = list_make1(makeDefElem("verbose", NULL, @2)); $$ = (Node *) n; } ; @@ -12040,64 +12831,31 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose opt_analyze opt_vacuum_relati } ; -AnalyzeStmt: analyze_keyword opt_verbose opt_vacuum_relation_list +AnalyzeStmt: analyze_keyword opt_utility_option_list opt_vacuum_relation_list { VacuumStmt *n = makeNode(VacuumStmt); - n->options = NIL; - if ($2) - n->options = lappend(n->options, - makeDefElem("verbose", NULL, @2)); + n->options = $2; n->rels = $3; n->is_vacuumcmd = false; $$ = (Node *) n; } - | analyze_keyword '(' utility_option_list ')' opt_vacuum_relation_list + | analyze_keyword VERBOSE opt_vacuum_relation_list { VacuumStmt *n = makeNode(VacuumStmt); - n->options = $3; - n->rels = $5; + n->options = list_make1(makeDefElem("verbose", NULL, @2)); + n->rels = $3; n->is_vacuumcmd = false; $$ = (Node *) n; } ; -utility_option_list: - utility_option_elem - { - $$ = list_make1($1); - } - | utility_option_list ',' utility_option_elem - { - $$ = lappend($1, $3); - } - ; - analyze_keyword: ANALYZE | ANALYSE /* British */ ; -utility_option_elem: - utility_option_name utility_option_arg - { - $$ = makeDefElem($1, $2, @1); - } - ; - -utility_option_name: - NonReservedWord { $$ = $1; } - | analyze_keyword { $$ = "analyze"; } - | FORMAT_LA { $$ = "format"; } - ; - -utility_option_arg: - opt_boolean_or_string { $$ = (Node *) makeString($1); } - | NumericOnly { $$ = (Node *) $1; } - | /* EMPTY */ { $$ = NULL; } - ; - opt_analyze: analyze_keyword { $$ = true; } | /*EMPTY*/ { $$ = false; } @@ -12444,12 +13202,24 @@ insert_column_item: ; opt_on_conflict: + ON CONFLICT opt_conf_expr DO SELECT opt_for_locking_strength where_clause + { + $$ = makeNode(OnConflictClause); + $$->action = ONCONFLICT_SELECT; + $$->infer = $3; + $$->targetList = NIL; + $$->lockStrength = $6; + $$->whereClause = $7; + $$->location = @1; + } + | ON CONFLICT opt_conf_expr DO UPDATE SET set_clause_list where_clause { $$ = makeNode(OnConflictClause); $$->action = ONCONFLICT_UPDATE; $$->infer = $3; $$->targetList = $7; + $$->lockStrength = LCS_NONE; $$->whereClause = $8; $$->location = @1; } @@ -12460,6 +13230,7 @@ opt_on_conflict: $$->action = ONCONFLICT_NOTHING; $$->infer = $3; $$->targetList = NIL; + $$->lockStrength = LCS_NONE; $$->whereClause = NULL; $$->location = @1; } @@ -12555,6 +13326,21 @@ DeleteStmt: opt_with_clause DELETE_P FROM relation_expr_opt_alias n->withClause = $1; $$ = (Node *) n; } + | opt_with_clause DELETE_P FROM relation_expr + for_portion_of_clause for_portion_of_opt_alias + using_clause where_or_current_clause returning_clause + { + DeleteStmt *n = makeNode(DeleteStmt); + + n->relation = $4; + n->forPortionOf = (ForPortionOfClause *) $5; + n->relation->alias = $6; + n->usingClause = $7; + n->whereClause = $8; + n->returningClause = $9; + n->withClause = $1; + $$ = (Node *) n; + } ; using_clause: @@ -12579,6 +13365,25 @@ LockStmt: LOCK_P opt_table relation_expr_list opt_lock opt_nowait n->nowait = $5; $$ = (Node *) n; } + | opt_with_clause UPDATE relation_expr + for_portion_of_clause for_portion_of_opt_alias + SET set_clause_list + from_clause + where_or_current_clause + returning_clause + { + UpdateStmt *n = makeNode(UpdateStmt); + + n->relation = $3; + n->forPortionOf = (ForPortionOfClause *) $4; + n->relation->alias = $5; + n->targetList = $7; + n->fromClause = $8; + n->whereClause = $9; + n->returningClause = $10; + n->withClause = $1; + $$ = (Node *) n; + } ; opt_lock: IN_P lock_type MODE { $$ = $2; } @@ -13411,7 +14216,7 @@ select_limit: } | offset_clause { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = $1; n->limitCount = NULL; @@ -13431,7 +14236,7 @@ opt_select_limit: limit_clause: LIMIT select_limit_value { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = $2; @@ -13459,7 +14264,7 @@ limit_clause: */ | FETCH first_or_next select_fetch_first_value row_or_rows ONLY { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = $3; @@ -13471,7 +14276,7 @@ limit_clause: } | FETCH first_or_next select_fetch_first_value row_or_rows WITH TIES { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = $3; @@ -13483,7 +14288,7 @@ limit_clause: } | FETCH first_or_next row_or_rows ONLY { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = makeIntConst(1, -1); @@ -13495,7 +14300,7 @@ limit_clause: } | FETCH first_or_next row_or_rows WITH TIES { - SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + SelectLimit *n = palloc_object(SelectLimit); n->limitOffset = NULL; n->limitCount = makeIntConst(1, -1); @@ -13590,7 +14395,7 @@ first_or_next: FIRST_P { $$ = 0; } group_clause: GROUP_P BY set_quantifier group_by_list { - GroupClause *n = (GroupClause *) palloc(sizeof(GroupClause)); + GroupClause *n = palloc_object(GroupClause); n->distinct = $3 == SET_QUANTIFIER_DISTINCT; n->list = $4; @@ -13598,7 +14403,7 @@ group_clause: } | /*EMPTY*/ { - GroupClause *n = (GroupClause *) palloc(sizeof(GroupClause)); + GroupClause *n = palloc_object(GroupClause); n->distinct = false; n->list = NIL; @@ -13692,6 +14497,11 @@ for_locking_strength: | FOR KEY SHARE { $$ = LCS_FORKEYSHARE; } ; +opt_for_locking_strength: + for_locking_strength { $$ = $1; } + | /* EMPTY */ { $$ = LCS_NONE; } + ; + locked_rels_list: OF qualified_name_list { $$ = $2; } | /* EMPTY */ { $$ = NIL; } @@ -13788,6 +14598,17 @@ table_ref: relation_expr opt_alias_clause n->alias = $3; $$ = (Node *) n; } + | GRAPH_TABLE '(' qualified_name MATCH graph_pattern COLUMNS '(' labeled_expr_list ')' ')' opt_alias_clause + { + RangeGraphTable *n = makeNode(RangeGraphTable); + + n->graph_name = $3; + n->graph_pattern = castNode(GraphPattern, $5); + n->columns = $8; + n->alias = $11; + n->location = @1; + $$ = (Node *) n; + } | select_with_parens opt_alias_clause { RangeSubselect *n = makeNode(RangeSubselect); @@ -14129,6 +14950,55 @@ relation_expr_opt_alias: relation_expr %prec UMINUS } ; +/* + * If an UPDATE/DELETE has FOR PORTION OF, then the relation_expr is separated + * from its potential alias by the for_portion_of_clause. So this production + * handles the potential alias in those cases. We need to solve the same + * problems as relation_expr_opt_alias, in particular resolving a shift/reduce + * conflict where "set set" could be an alias plus the SET keyword, or the SET + * keyword then a column name. As above, we force the latter interpretation by + * giving the non-alias choice a higher precedence. + */ +for_portion_of_opt_alias: + AS ColId + { + Alias *alias = makeNode(Alias); + + alias->aliasname = $2; + $$ = alias; + } + | BareColLabel + { + Alias *alias = makeNode(Alias); + + alias->aliasname = $1; + $$ = alias; + } + | /* empty */ %prec UMINUS { $$ = NULL; } + ; + +for_portion_of_clause: + FOR PORTION OF ColId '(' a_expr ')' + { + ForPortionOfClause *n = makeNode(ForPortionOfClause); + n->range_name = $4; + n->location = @4; + n->target = $6; + n->target_location = @6; + $$ = (Node *) n; + } + | FOR PORTION OF ColId FROM a_expr TO a_expr + { + ForPortionOfClause *n = makeNode(ForPortionOfClause); + n->range_name = $4; + n->location = @4; + n->target_start = $6; + n->target_end = $8; + n->target_location = @5; + $$ = (Node *) n; + } + ; + /* * TABLESAMPLE decoration in a FROM item */ @@ -14969,16 +15839,25 @@ opt_timezone: | /*EMPTY*/ { $$ = false; } ; +/* + * We need to handle this shift/reduce conflict: + * FOR PORTION OF valid_at FROM t + INTERVAL '1' YEAR TO MONTH. + * We don't see far enough ahead to know if there is another TO coming. + * We prefer to interpret this as FROM (t + INTERVAL '1' YEAR TO MONTH), + * i.e. to shift. + * That gives the user the option of adding parentheses to get the other meaning. + * If we reduced, intervals could never have a TO. + */ opt_interval: - YEAR_P + YEAR_P %prec IS { $$ = list_make1(makeIntConst(INTERVAL_MASK(YEAR), @1)); } | MONTH_P { $$ = list_make1(makeIntConst(INTERVAL_MASK(MONTH), @1)); } - | DAY_P + | DAY_P %prec IS { $$ = list_make1(makeIntConst(INTERVAL_MASK(DAY), @1)); } - | HOUR_P + | HOUR_P %prec IS { $$ = list_make1(makeIntConst(INTERVAL_MASK(HOUR), @1)); } - | MINUTE_P + | MINUTE_P %prec IS { $$ = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), @1)); } | interval_second { $$ = $1; } @@ -15139,6 +16018,10 @@ a_expr: c_expr { $$ = $1; } { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $3, @2); } | a_expr NOT_EQUALS a_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, $3, @2); } + | a_expr RIGHT_ARROW a_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "->", $1, $3, @2); } + | a_expr '|' a_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", $1, $3, @2); } | a_expr qual_Op a_expr %prec Op { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); } @@ -15530,7 +16413,7 @@ a_expr: c_expr { $$ = $1; } { JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1); - $$ = makeJsonIsPredicate($1, format, $3, $4, @1); + $$ = makeJsonIsPredicate($1, format, $3, $4, InvalidOid, @1); } /* * Required by SQL/JSON, but there are conflicts @@ -15539,7 +16422,7 @@ a_expr: c_expr { $$ = $1; } IS json_predicate_type_constraint json_key_uniqueness_constraint_opt %prec IS { - $$ = makeJsonIsPredicate($1, $2, $4, $5, @1); + $$ = makeJsonIsPredicate($1, $2, $4, $5, InvalidOid, @1); } */ | a_expr IS NOT @@ -15548,7 +16431,7 @@ a_expr: c_expr { $$ = $1; } { JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1); - $$ = makeNotExpr(makeJsonIsPredicate($1, format, $4, $5, @1), @1); + $$ = makeNotExpr(makeJsonIsPredicate($1, format, $4, $5, InvalidOid, @1), @1); } /* * Required by SQL/JSON, but there are conflicts @@ -15558,7 +16441,7 @@ a_expr: c_expr { $$ = $1; } json_predicate_type_constraint json_key_uniqueness_constraint_opt %prec IS { - $$ = makeNotExpr(makeJsonIsPredicate($1, $2, $5, $6, @1), @1); + $$ = makeNotExpr(makeJsonIsPredicate($1, $2, $5, $6, InvalidOid, @1), @1); } */ | DEFAULT @@ -15619,6 +16502,10 @@ b_expr: c_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $3, @2); } | b_expr NOT_EQUALS b_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, $3, @2); } + | b_expr RIGHT_ARROW b_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "->", $1, $3, @2); } + | b_expr '|' b_expr + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", $1, $3, @2); } | b_expr qual_Op b_expr %prec Op { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); } | qual_Op b_expr %prec Op @@ -15878,7 +16765,7 @@ func_application: func_name '(' ')' * (Note that many of the special SQL functions wouldn't actually make any * sense as functional index entries, but we ignore that consideration here.) */ -func_expr: func_application within_group_clause filter_clause over_clause +func_expr: func_application within_group_clause filter_clause null_treatment over_clause { FuncCall *n = (FuncCall *) $1; @@ -15911,7 +16798,8 @@ func_expr: func_application within_group_clause filter_clause over_clause n->agg_within_group = true; } n->agg_filter = $3; - n->over = $4; + n->ignore_nulls = $4; + n->over = $5; $$ = (Node *) n; } | json_aggregate_func filter_clause over_clause @@ -16200,7 +17088,7 @@ func_expr_common_subexpr: COERCE_SQL_SYNTAX, @1); } - | XMLFOREST '(' xml_attribute_list ')' + | XMLFOREST '(' labeled_expr_list ')' { $$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NIL, @1); } @@ -16425,14 +17313,14 @@ opt_xml_root_standalone: ',' STANDALONE_P YES_P { $$ = makeIntConst(XML_STANDALONE_OMITTED, -1); } ; -xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; } +xml_attributes: XMLATTRIBUTES '(' labeled_expr_list ')' { $$ = $3; } ; -xml_attribute_list: xml_attribute_el { $$ = list_make1($1); } - | xml_attribute_list ',' xml_attribute_el { $$ = lappend($1, $3); } +labeled_expr_list: labeled_expr { $$ = list_make1($1); } + | labeled_expr_list ',' labeled_expr { $$ = lappend($1, $3); } ; -xml_attribute_el: a_expr AS ColLabel +labeled_expr: a_expr AS ColLabel { $$ = makeNode(ResTarget); $$->name = $3; @@ -16489,6 +17377,26 @@ xml_passing_mech: | BY VALUE_P ; +/***************************************************************************** + * + * WAIT FOR LSN + * + *****************************************************************************/ + +WaitStmt: + WAIT FOR LSN_P Sconst opt_wait_with_clause + { + WaitStmt *n = makeNode(WaitStmt); + n->lsn_literal = $4; + n->options = $5; + $$ = (Node *) n; + } + ; + +opt_wait_with_clause: + WITH '(' utility_option_list ')' { $$ = $3; } + | /*EMPTY*/ { $$ = NIL; } + ; /* * Aggregate decoration clauses @@ -16507,6 +17415,12 @@ filter_clause: /* * Window Definitions */ +null_treatment: + IGNORE_P NULLS_P { $$ = PARSER_IGNORE_NULLS; } + | RESPECT_P NULLS_P { $$ = PARSER_RESPECT_NULLS; } + | /*EMPTY*/ { $$ = NO_NULLTREATMENT; } + ; + window_clause: WINDOW window_definition_list { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } @@ -16787,6 +17701,8 @@ MathOp: '+' { $$ = "+"; } | LESS_EQUALS { $$ = "<="; } | GREATER_EQUALS { $$ = ">="; } | NOT_EQUALS { $$ = "<>"; } + | RIGHT_ARROW { $$ = "->"; } + | '|' { $$ = "|"; } ; qual_Op: Op @@ -17367,6 +18283,214 @@ json_array_aggregate_order_by_clause_opt: | /* EMPTY */ { $$ = NIL; } ; + +/***************************************************************************** + * + * graph patterns + * + *****************************************************************************/ + +graph_pattern: + path_pattern_list where_clause + { + GraphPattern *gp = makeNode(GraphPattern); + + gp->path_pattern_list = $1; + gp->whereClause = $2; + $$ = (Node *) gp; + } + ; + +path_pattern_list: + path_pattern { $$ = list_make1($1); } + | path_pattern_list ',' path_pattern { $$ = lappend($1, $3); } + ; + +path_pattern: + path_pattern_expression { $$ = $1; } + ; + +/* + * path pattern expression + */ + +path_pattern_expression: + path_term { $$ = $1; } + /* | path_multiset_alternation */ + /* | path_pattern_union */ + ; + +path_term: + path_factor { $$ = list_make1($1); } + | path_term path_factor { $$ = lappend($1, $2); } + ; + +path_factor: + path_primary opt_graph_pattern_quantifier + { + GraphElementPattern *gep = (GraphElementPattern *) $1; + + gep->quantifier = $2; + + $$ = (Node *) gep; + } + ; + +path_primary: + '(' opt_colid opt_is_label_expression where_clause ')' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = VERTEX_PATTERN; + gep->variable = $2; + gep->labelexpr = $3; + gep->whereClause = $4; + gep->location = @1; + + $$ = (Node *) gep; + } + /* full edge pointing left: <-[ xxx ]- */ + | '<' '-' '[' opt_colid opt_is_label_expression where_clause ']' '-' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_LEFT; + gep->variable = $4; + gep->labelexpr = $5; + gep->whereClause = $6; + gep->location = @1; + + $$ = (Node *) gep; + } + /* full edge pointing right: -[ xxx ]-> */ + | '-' '[' opt_colid opt_is_label_expression where_clause ']' '-' '>' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_RIGHT; + gep->variable = $3; + gep->labelexpr = $4; + gep->whereClause = $5; + gep->location = @1; + + $$ = (Node *) gep; + } + | '-' '[' opt_colid opt_is_label_expression where_clause ']' RIGHT_ARROW + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_RIGHT; + gep->variable = $3; + gep->labelexpr = $4; + gep->whereClause = $5; + gep->location = @1; + + $$ = (Node *) gep; + } + /* full edge any direction: -[ xxx ]- */ + | '-' '[' opt_colid opt_is_label_expression where_clause ']' '-' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_ANY; + gep->variable = $3; + gep->labelexpr = $4; + gep->whereClause = $5; + gep->location = @1; + + $$ = (Node *) gep; + } + /* abbreviated edge patterns */ + | '<' '-' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_LEFT; + gep->location = @1; + + $$ = (Node *) gep; + } + | '-' '>' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_RIGHT; + gep->location = @1; + + $$ = (Node *) gep; + } + | RIGHT_ARROW + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_RIGHT; + gep->location = @1; + + $$ = (Node *) gep; + } + | '-' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = EDGE_PATTERN_ANY; + gep->location = @1; + + $$ = (Node *) gep; + } + | '(' path_pattern_expression where_clause ')' + { + GraphElementPattern *gep = makeNode(GraphElementPattern); + + gep->kind = PAREN_EXPR; + gep->subexpr = $2; + gep->whereClause = $3; + gep->location = @1; + + $$ = (Node *) gep; + } + ; + +opt_colid: + ColId { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; + +opt_is_label_expression: + IS label_expression { $$ = $2; } + | /*EMPTY*/ { $$ = NULL; } + ; + +/* + * graph pattern quantifier + */ + +opt_graph_pattern_quantifier: + '{' Iconst '}' { $$ = list_make2_int($2, $2); } + | '{' ',' Iconst '}' { $$ = list_make2_int(0, $3); } + | '{' Iconst ',' Iconst '}' { $$ = list_make2_int($2, $4); } + | /*EMPTY*/ { $$ = NULL; } + ; + +/* + * label expression + */ + +label_expression: + label_term + | label_disjunction + ; + +label_disjunction: + label_expression '|' label_term + { $$ = makeOrExpr($1, $3, @2); } + ; + +label_term: + name + { $$ = makeColumnRef($1, NIL, @1, yyscanner); } + ; + + /***************************************************************************** * * target list for SELECT @@ -17887,6 +19011,7 @@ unreserved_keyword: | DELIMITERS | DEPENDS | DEPTH + | DESTINATION | DETACH | DICTIONARY | DISABLE_P @@ -17896,6 +19021,7 @@ unreserved_keyword: | DOUBLE_P | DROP | EACH + | EDGE | EMPTY_P | ENABLE_P | ENCODING @@ -17926,6 +19052,7 @@ unreserved_keyword: | GENERATED | GLOBAL | GRANTED + | GRAPH | GROUPS | HANDLER | HEADER_P @@ -17933,6 +19060,7 @@ unreserved_keyword: | HOUR_P | IDENTITY_P | IF_P + | IGNORE_P | IMMEDIATE | IMMUTABLE | IMPLICIT_P @@ -17968,6 +19096,7 @@ unreserved_keyword: | LOCK_P | LOCKED | LOGGED + | LSN_P | MAPPING | MATCH | MATCHED @@ -17990,6 +19119,7 @@ unreserved_keyword: | NFKC | NFKD | NO + | NODE | NORMALIZED | NOTHING | NOTIFY @@ -18016,6 +19146,7 @@ unreserved_keyword: | PARSER | PARTIAL | PARTITION + | PARTITIONS | PASSING | PASSWORD | PATH @@ -18023,6 +19154,7 @@ unreserved_keyword: | PLAN | PLANS | POLICY + | PORTION | PRECEDING | PREPARE | PREPARED @@ -18033,6 +19165,8 @@ unreserved_keyword: | PROCEDURE | PROCEDURES | PROGRAM + | PROPERTIES + | PROPERTY | PUBLICATION | QUOTE | QUOTES @@ -18044,13 +19178,16 @@ unreserved_keyword: | REFERENCING | REFRESH | REINDEX + | RELATIONSHIP | RELATIVE_P | RELEASE | RENAME + | REPACK | REPEATABLE | REPLACE | REPLICA | RESET + | RESPECT_P | RESTART | RESTRICT | RETURN @@ -18084,6 +19221,7 @@ unreserved_keyword: | SKIP | SNAPSHOT | SOURCE + | SPLIT | SQL_P | STABLE | STANDALONE_P @@ -18133,10 +19271,12 @@ unreserved_keyword: | VALUE_P | VARYING | VERSION_P + | VERTEX | VIEW | VIEWS | VIRTUAL | VOLATILE + | WAIT | WHITESPACE_P | WITHIN | WITHOUT @@ -18172,6 +19312,7 @@ col_name_keyword: | EXISTS | EXTRACT | FLOAT_P + | GRAPH_TABLE | GREATEST | GROUPING | INOUT @@ -18463,6 +19604,7 @@ bare_label_keyword: | DEPENDS | DEPTH | DESC + | DESTINATION | DETACH | DICTIONARY | DISABLE_P @@ -18474,6 +19616,7 @@ bare_label_keyword: | DOUBLE_P | DROP | EACH + | EDGE | ELSE | EMPTY_P | ENABLE_P @@ -18512,6 +19655,8 @@ bare_label_keyword: | GENERATED | GLOBAL | GRANTED + | GRAPH + | GRAPH_TABLE | GREATEST | GROUPING | GROUPS @@ -18583,6 +19728,7 @@ bare_label_keyword: | LOCK_P | LOCKED | LOGGED + | LSN_P | MAPPING | MATCH | MATCHED @@ -18607,6 +19753,7 @@ bare_label_keyword: | NFKC | NFKD | NO + | NODE | NONE | NORMALIZE | NORMALIZED @@ -18643,6 +19790,7 @@ bare_label_keyword: | PARSER | PARTIAL | PARTITION + | PARTITIONS | PASSING | PASSWORD | PATH @@ -18651,6 +19799,7 @@ bare_label_keyword: | PLAN | PLANS | POLICY + | PORTION | POSITION | PRECEDING | PREPARE @@ -18663,6 +19812,8 @@ bare_label_keyword: | PROCEDURE | PROCEDURES | PROGRAM + | PROPERTIES + | PROPERTY | PUBLICATION | QUOTE | QUOTES @@ -18676,9 +19827,11 @@ bare_label_keyword: | REFERENCING | REFRESH | REINDEX + | RELATIONSHIP | RELATIVE_P | RELEASE | RENAME + | REPACK | REPEATABLE | REPLACE | REPLICA @@ -18723,6 +19876,7 @@ bare_label_keyword: | SNAPSHOT | SOME | SOURCE + | SPLIT | SQL_P | STABLE | STANDALONE_P @@ -18790,10 +19944,12 @@ bare_label_keyword: | VARIADIC | VERBOSE | VERSION_P + | VERTEX | VIEW | VIEWS | VIRTUAL | VOLATILE + | WAIT | WHEN | WHITESPACE_P | WORK @@ -19710,6 +20866,49 @@ parsePartitionStrategy(char *strategy, int location, core_yyscan_t yyscanner) } +/* + * Process all_objects_list to set all_tables and/or all_sequences. + * Also, checks if the pub_object_type has been specified more than once. + */ +static void +preprocess_pub_all_objtype_list(List *all_objects_list, List **pubobjects, + bool *all_tables, bool *all_sequences, + core_yyscan_t yyscanner) +{ + if (!all_objects_list) + return; + + *all_tables = false; + *all_sequences = false; + + foreach_ptr(PublicationAllObjSpec, obj, all_objects_list) + { + if (obj->pubobjtype == PUBLICATION_ALL_TABLES) + { + if (*all_tables) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid publication object list"), + errdetail("ALL TABLES can be specified only once."), + parser_errposition(obj->location)); + + *all_tables = true; + *pubobjects = list_concat(*pubobjects, obj->except_tables); + } + else if (obj->pubobjtype == PUBLICATION_ALL_SEQUENCES) + { + if (*all_sequences) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid publication object list"), + errdetail("ALL SEQUENCES can be specified only once."), + parser_errposition(obj->location)); + + *all_sequences = true; + } + } +} + /* * Process pubobjspec_list to check for errors in any of the objects and * convert PUBLICATIONOBJ_CONTINUATION into appropriate PublicationObjSpecType. diff --git a/src/parser/keywords.c b/src/parser/keywords.c index 835ddfeb5..afc60828e 100644 --- a/src/parser/keywords.c +++ b/src/parser/keywords.c @@ -4,8 +4,8 @@ * PostgreSQL's list of SQL keywords * * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/parser/kwlookup.c b/src/parser/kwlookup.c index ff2498cf8..b7cd5a682 100644 --- a/src/parser/kwlookup.c +++ b/src/parser/kwlookup.c @@ -4,8 +4,8 @@ * Key word lookup for PostgreSQL * * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/parser/list.c b/src/parser/list.c index 17f394fb0..5e9903a26 100644 --- a/src/parser/list.c +++ b/src/parser/list.c @@ -5,8 +5,8 @@ * * See comments in pg_list.h * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/parser/makefuncs.c b/src/parser/makefuncs.c index be807d982..065e728f3 100644 --- a/src/parser/makefuncs.c +++ b/src/parser/makefuncs.c @@ -4,8 +4,8 @@ * creator functions for various nodes. The functions here are for the * most frequently created nodes. * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -792,14 +792,17 @@ makeJsonKeyValue(Node *key, Node *value) * */ Node * makeJsonIsPredicate(Node *expr, JsonFormat *format, JsonValueType item_type, - bool unique_keys, int location) + bool unique_keys, Oid exprBaseType, int location) { JsonIsPredicate *n = makeNode(JsonIsPredicate); + Assert(expr != NULL); + n->expr = expr; n->format = format; n->item_type = item_type; n->unique_keys = unique_keys; + n->exprBaseType = exprBaseType; n->location = location; return (Node *) n; diff --git a/src/parser/outfuncs.c b/src/parser/outfuncs.c index 529ac347c..b72393cb7 100644 --- a/src/parser/outfuncs.c +++ b/src/parser/outfuncs.c @@ -127,7 +127,7 @@ static void _outTransactionStmt(StringInfo str, TransactionStmt *node); static void _outTruncateStmt(StringInfo str, TruncateStmt *node); static void _outVacuumStmt(StringInfo str, VacuumStmt *node); static void _outExplainStmt(StringInfo str, ExplainStmt *node); -static void _outClusterStmt(StringInfo str, ClusterStmt *node); +static void _outRepackStmt(StringInfo str, RepackStmt *node); static void _outCheckPointStmt(StringInfo str, CheckPointStmt *node); static void _outClosePortalStmt(StringInfo str, ClosePortalStmt *node); static void _outListenStmt(StringInfo str, ListenStmt *node); @@ -200,7 +200,7 @@ static void _outRangeFunction(StringInfo str, RangeFunction *node); static void _outRangeTableSample(StringInfo str, RangeTableSample *node); static void _outWithDefinition(StringInfo str, List *def_list); static void _outOnConflictClause(StringInfo str, OnConflictClause *node); - +static void _outForPortionOfClause(StringInfo str, ForPortionOfClause *node); /* * Borrowed from backend/catalog/namespace.c @@ -260,11 +260,6 @@ escape_string(char *str) { es[j++] = '\''; } - else if (str[i] == '\\') - { - if (!standard_conforming_strings) - es[j++] = '\\'; - } es[j] = str[i]; } @@ -2788,6 +2783,9 @@ _outSetClause(StringInfo str, List *node) static void _outUpdateStmt(StringInfo str, UpdateStmt *node) { + ereport(LOG, + (errmsg("_outUpdateStmt: forPortionOf=%p", + node->forPortionOf))); if (node->withClause) _outWithClause(str, node->withClause); @@ -2795,6 +2793,12 @@ _outUpdateStmt(StringInfo str, UpdateStmt *node) _outNode(str, node->relation); + if (node->forPortionOf) + { + appendStringInfoString(str, " FOR PORTION OF "); + _outNode(str, node->forPortionOf); + } + _outSetClause(str, node->targetList); if (node->fromClause) @@ -2826,6 +2830,12 @@ _outDeleteStmt(StringInfo str, DeleteStmt *node) _outNode(str, node->relation); + if (node->forPortionOf) + { + appendStringInfoString(str, " FOR PORTION OF "); + _outNode(str, node->forPortionOf); + } + if (node->usingClause) { appendStringInfoString(str, " USING "); @@ -3030,7 +3040,7 @@ _outExplainStmt(StringInfo str, ExplainStmt *node) } static void -_outClusterStmt(StringInfo str, ClusterStmt *node) +_outRepackStmt(StringInfo str, RepackStmt *node) { appendStringInfoString(str, "CLUSTER "); @@ -4806,6 +4816,7 @@ _outGrantStmt(StringInfo str, GrantStmt *node) case OBJECT_OPERATOR: case OBJECT_OPFAMILY: case OBJECT_PARAMETER_ACL: + case OBJECT_PROPGRAPH: case OBJECT_POLICY: case OBJECT_PROCEDURE: case OBJECT_PUBLICATION: @@ -5471,6 +5482,11 @@ _outAlterDomainStmt(StringInfo str, AlterDomainStmt *node) if (node->behavior == DROP_CASCADE) appendStringInfoString(str, " CASCADE"); break; + case 'V': + appendStringInfoString(str, " VALIDATE CONSTRAINT \""); + appendStringInfoString(str, node->name); + appendStringInfoString(str, "\""); + break; } } @@ -6143,6 +6159,10 @@ _outOnConflictClause(StringInfo str, OnConflictClause *node) appendStringInfoString(str, " DO NOTHING "); break; + case ONCONFLICT_SELECT: + appendStringInfoString(str, " DO SELECT "); + break; + default: break; } @@ -6159,6 +6179,26 @@ _outOnConflictClause(StringInfo str, OnConflictClause *node) } } +static void +_outForPortionOfClause(StringInfo str, ForPortionOfClause *node) +{ + appendStringInfoString(str, node->range_name); + + if (node->target) + { + appendStringInfoString(str, " "); + _outNode(str, node->target); + } + else + { + appendStringInfoString(str, " FROM "); + _outNode(str, node->target_start); + + appendStringInfoString(str, " TO "); + _outNode(str, node->target_end); + } +} + static void _outPartitionElem(StringInfo str, PartitionElem *node) { @@ -6686,8 +6726,8 @@ _outNode(StringInfo str, void *obj) _outExplainStmt(str, obj); break; - case T_ClusterStmt: - _outClusterStmt(str, obj); + case T_RepackStmt: + _outRepackStmt(str, obj); break; case T_CheckPointStmt: @@ -6941,6 +6981,9 @@ _outNode(StringInfo str, void *obj) case T_OnConflictClause: _outOnConflictClause(str, obj); break; + case T_ForPortionOfClause: + _outForPortionOfClause(str, obj); + break; default: break; diff --git a/src/parser/parser.c b/src/parser/parser.c index 997c175fb..d25c60333 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -10,8 +10,8 @@ * analyze.c and related files. * * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -36,7 +36,6 @@ #include "scansup.h" int server_version_num = 0; static pg_enc server_encoding = PG_SQL_ASCII; - static int parse_version(const char *versionString); static bool check_uescapechar(unsigned char escape); @@ -479,7 +478,7 @@ hexval(unsigned char c) /* is Unicode code point acceptable? */ static void -check_unicode_value(pg_wchar c) +check_unicode_value(char32_t c) { if (!is_valid_unicode_codepoint(c)) ereport(ERROR, @@ -516,7 +515,7 @@ str_udeescape(const char *str, char escape, char *new, *out; size_t new_len; - pg_wchar pair_first = 0; + char16_t pair_first = 0; ScannerCallbackState scbstate; /* @@ -560,7 +559,7 @@ str_udeescape(const char *str, char escape, isxdigit((unsigned char) in[3]) && isxdigit((unsigned char) in[4])) { - pg_wchar unicode; + char32_t unicode; unicode = (hexval(in[1]) << 12) + (hexval(in[2]) << 8) + @@ -597,7 +596,7 @@ str_udeescape(const char *str, char escape, isxdigit((unsigned char) in[6]) && isxdigit((unsigned char) in[7])) { - pg_wchar unicode; + char32_t unicode; unicode = (hexval(in[2]) << 20) + (hexval(in[3]) << 16) + @@ -709,13 +708,6 @@ parser_set_param(const char *name, const char *value) else server_encoding = PG_SQL_ASCII; } - else if (strcmp(name, "standard_conforming_strings") == 0) - { - if (strcmp(value, "on") == 0) - standard_conforming_strings = true; - else - standard_conforming_strings = false; - } } int diff --git a/src/parser/scan.l b/src/parser/scan.l index 011728cc8..282328e45 100644 --- a/src/parser/scan.l +++ b/src/parser/scan.l @@ -65,17 +65,16 @@ fprintf_to_ereport(const char *fmt, const char *msg) } /* - * GUC variables. This is a DIRECT violation of the warning given at the + * GUC variable. This is a DIRECT violation of the warning given at the * head of gram.y, ie flex/bison code must not depend on any GUC variables; - * as such, changing their values can induce very unintuitive behavior. - * But we shall have to live with it until we can remove these variables. + * as such, changing its value can induce very unintuitive behavior. + * In practice, backslash_quote is not too awful since it only controls + * whether to throw an error: it cannot change non-error results. * * standard_conforming_strings is overridden by parser_set_param() * while connecting to backend by receiving parameter status message. */ int backslash_quote = BACKSLASH_QUOTE_SAFE_ENCODING; -bool escape_string_warning = true; -bool standard_conforming_strings = true; /* * Constant data exported from this file. This array maps from the @@ -129,15 +128,12 @@ static void addlitchar(unsigned char ychar, core_yyscan_t yyscanner); static char *litbufdup(core_yyscan_t yyscanner); static unsigned char unescape_single_char(unsigned char c, core_yyscan_t yyscanner); static int process_integer_literal(const char *token, YYSTYPE *lval, int base); -static void addunicode(pg_wchar c, yyscan_t yyscanner); +static void addunicode(char32_t c, yyscan_t yyscanner); #define yyerror(msg) scanner_yyerror(msg, yyscanner) #define lexer_errposition() scanner_errposition(*(yylloc), yyscanner) -static void check_string_escape_warning(unsigned char ychar, core_yyscan_t yyscanner); -static void check_escape_warning(core_yyscan_t yyscanner); - %} %option reentrant @@ -360,6 +356,8 @@ less_equals "<=" greater_equals ">=" less_greater "<>" not_equals "!=" +/* Note there is no need for left_arrow, since "<-" is not a single operator. */ +right_arrow "->" /* * "self" is the set of chars that should be returned as single-character @@ -371,7 +369,7 @@ not_equals "!=" * If you change either set, adjust the character lists appearing in the * rule for "operator"! */ -self [,()\[\].;\:\+\-\*\/\%\^\<\>\=] +self [,()\[\].;\:\|\+\-\*\/\%\^\<\>\=] op_chars [\~\!\@\#\^\&\|\`\?\+\-\*\/\%\<\>\=] operator {op_chars}+ @@ -551,17 +549,12 @@ other . } {xqstart} { - yyextra->warn_on_first_escape = true; yyextra->saw_non_ascii = false; SET_YYLLOC(); - if (yyextra->standard_conforming_strings) - BEGIN(xq); - else - BEGIN(xe); + BEGIN(xq); startlit(); } {xestart} { - yyextra->warn_on_first_escape = false; yyextra->saw_non_ascii = false; SET_YYLLOC(); BEGIN(xe); @@ -569,12 +562,6 @@ other . } {xusstart} { SET_YYLLOC(); - if (!yyextra->standard_conforming_strings) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("unsafe use of string constant with Unicode escapes"), - errdetail("String constants with Unicode escapes cannot be used when \"standard_conforming_strings\" is off."), - lexer_errposition())); BEGIN(xus); startlit(); } @@ -648,14 +635,7 @@ other . addlit(yytext, yyleng, yyscanner); } {xeunicode} { - pg_wchar c = strtoul(yytext + 2, NULL, 16); - - /* - * For consistency with other productions, issue any - * escape warning with cursor pointing to start of string. - * We might want to change that, someday. - */ - check_escape_warning(yyscanner); + char32_t c = strtoul(yytext + 2, NULL, 16); /* Remember start of overall string token ... */ PUSH_YYLLOC(); @@ -676,7 +656,7 @@ other . POP_YYLLOC(); } {xeunicode} { - pg_wchar c = strtoul(yytext + 2, NULL, 16); + char32_t c = strtoul(yytext + 2, NULL, 16); /* Remember start of overall string token ... */ PUSH_YYLLOC(); @@ -725,14 +705,12 @@ other . lexer_errposition())); } #endif - check_string_escape_warning(yytext[1], yyscanner); addlitchar(unescape_single_char(yytext[1], yyscanner), yyscanner); } {xeoctesc} { unsigned char c = strtoul(yytext + 1, NULL, 8); - check_escape_warning(yyscanner); addlitchar(c, yyscanner); if (c == '\0' || IS_HIGHBIT_SET(c)) yyextra->saw_non_ascii = true; @@ -740,7 +718,6 @@ other . {xehexesc} { unsigned char c = strtoul(yytext + 2, NULL, 16); - check_escape_warning(yyscanner); addlitchar(c, yyscanner); if (c == '\0' || IS_HIGHBIT_SET(c)) yyextra->saw_non_ascii = true; @@ -888,6 +865,11 @@ other . return NOT_EQUALS; } +{right_arrow} { + SET_YYLLOC(); + return RIGHT_ARROW; + } + {self} { SET_YYLLOC(); return yytext[0]; @@ -965,7 +947,7 @@ other . * that the "self" rule would have. */ if (nchars == 1 && - strchr(",()[].;:+-*/%^<>=", yytext[0])) + strchr(",()[].;:|+-*/%^<>=", yytext[0])) return yytext[0]; /* * Likewise, if what we have left is two chars, and @@ -985,6 +967,8 @@ other . return NOT_EQUALS; if (yytext[0] == '!' && yytext[1] == '=') return NOT_EQUALS; + if (yytext[0] == '-' && yytext[1] == '>') + return RIGHT_ARROW; } } @@ -1272,8 +1256,6 @@ scanner_init(const char *str, yyext->keyword_tokens = keyword_tokens; yyext->backslash_quote = backslash_quote; - yyext->escape_string_warning = escape_string_warning; - yyext->standard_conforming_strings = standard_conforming_strings; /* * Make a scan buffer with special termination needed by flex. @@ -1397,7 +1379,7 @@ process_integer_literal(const char *token, YYSTYPE *lval, int base) } static void -addunicode(pg_wchar c, core_yyscan_t yyscanner) +addunicode(char32_t c, core_yyscan_t yyscanner) { ScannerCallbackState scbstate; char buf[MAX_UNICODE_EQUIVALENT_STRING + 1]; @@ -1441,51 +1423,6 @@ unescape_single_char(unsigned char c, core_yyscan_t yyscanner) } } -static void -check_string_escape_warning(unsigned char ychar, core_yyscan_t yyscanner) -{ - if (ychar == '\'') - { - if (yyextra->warn_on_first_escape && yyextra->escape_string_warning) -#ifdef NOT_USED - ereport(WARNING, - (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER), - errmsg("nonstandard use of \\' in a string literal"), - errhint("Use '' to write quotes in strings, or use the escape string syntax (E'...')."), - lexer_errposition())); -#endif - yyextra->warn_on_first_escape = false; /* warn only once per string */ - } - else if (ychar == '\\') - { - if (yyextra->warn_on_first_escape && yyextra->escape_string_warning) -#ifdef NOT_USED - ereport(WARNING, - (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER), - errmsg("nonstandard use of \\\\ in a string literal"), - errhint("Use the escape string syntax for backslashes, e.g., E'\\\\'."), - lexer_errposition())); -#endif - yyextra->warn_on_first_escape = false; /* warn only once per string */ - } - else - check_escape_warning(yyscanner); -} - -static void -check_escape_warning(core_yyscan_t yyscanner) -{ - if (yyextra->warn_on_first_escape && yyextra->escape_string_warning) -#ifdef NOT_USED - ereport(WARNING, - (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER), - errmsg("nonstandard use of escape in a string literal"), - errhint("Use the escape string syntax for escapes, e.g., E'\\r\\n'."), - lexer_errposition())); -#endif - yyextra->warn_on_first_escape = false; /* warn only once per string */ -} - /* * Interface functions to make flex use palloc() instead of malloc(). * It'd be better to make these static, but flex insists otherwise. diff --git a/src/parser/scansup.c b/src/parser/scansup.c index 943fb358b..b5251dd96 100644 --- a/src/parser/scansup.c +++ b/src/parser/scansup.c @@ -3,8 +3,8 @@ * scansup.c * scanner support routines used by the core lexer * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/parser/snprintf.c b/src/parser/snprintf.c index e82832f24..de60cc470 100644 --- a/src/parser/snprintf.c +++ b/src/parser/snprintf.c @@ -3,7 +3,7 @@ * Copyright (c) 1983, 1995, 1996 Eric P. Allman * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -254,7 +254,7 @@ pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args) #if 0 int -pg_snprintf(char *str, size_t count, const char *fmt,...) +pg_snprintf(char *str, size_t count, const char *fmt, ...) { int len; va_list args; @@ -282,7 +282,7 @@ pg_vsprintf(char *str, const char *fmt, va_list args) } int -pg_sprintf(char *str, const char *fmt,...) +pg_sprintf(char *str, const char *fmt, ...) { int len; va_list args; @@ -316,7 +316,7 @@ pg_vfprintf(FILE *stream, const char *fmt, va_list args) } int -pg_fprintf(FILE *stream, const char *fmt,...) +pg_fprintf(FILE *stream, const char *fmt, ...) { int len; va_list args; @@ -334,7 +334,7 @@ pg_vprintf(const char *fmt, va_list args) } int -pg_printf(const char *fmt,...) +pg_printf(const char *fmt, ...) { int len; va_list args; @@ -518,7 +518,7 @@ nextch2: /* set zero padding if no nonzero digits yet */ if (accum == 0 && !pointflag) zpad = '0'; - /* FALL THRU */ + pg_fallthrough; case '1': case '2': case '3': @@ -613,34 +613,21 @@ nextch2: fmtpos = accum; accum = 0; goto nextch2; -#ifdef WIN32 - case 'I': - /* Windows PRI*{32,64,PTR} size */ - if (format[0] == '3' && format[1] == '2') - format += 2; - else if (format[0] == '6' && format[1] == '4') - { - format += 2; - longlongflag = 1; - } - else - { -#if SIZEOF_VOID_P == SIZEOF_LONG - longflag = 1; -#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG - longlongflag = 1; -#else -#error "cannot find integer type of the same size as intptr_t" -#endif - } - goto nextch2; -#endif case 'l': if (longflag) longlongflag = 1; else longflag = 1; goto nextch2; + case 'j': +#if SIZEOF_INTMAX_T == SIZEOF_LONG + longflag = 1; +#elif SIZEOF_INTMAX_T == SIZEOF_LONG_LONG + longlongflag = 1; +#else +#error "cannot find integer type of the same size as intmax_t" +#endif + goto nextch2; case 'z': #if SIZEOF_SIZE_T == SIZEOF_LONG longflag = 1; @@ -898,34 +885,21 @@ nextch1: fmtpos = accum; accum = 0; goto nextch1; -#ifdef WIN32 - case 'I': - /* Windows PRI*{32,64,PTR} size */ - if (format[0] == '3' && format[1] == '2') - format += 2; - else if (format[0] == '6' && format[1] == '4') - { - format += 2; - longlongflag = 1; - } - else - { -#if SIZEOF_VOID_P == SIZEOF_LONG - longflag = 1; -#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG - longlongflag = 1; -#else -#error "cannot find integer type of the same size as intptr_t" -#endif - } - goto nextch1; -#endif case 'l': if (longflag) longlongflag = 1; else longflag = 1; goto nextch1; + case 'j': +#if SIZEOF_INTMAX_T == SIZEOF_LONG + longflag = 1; +#elif SIZEOF_INTMAX_T == SIZEOF_LONG_LONG + longlongflag = 1; +#else +#error "cannot find integer type of the same size as intmax_t" +#endif + goto nextch1; case 'z': #if SIZEOF_SIZE_T == SIZEOF_LONG longflag = 1; @@ -1305,22 +1279,6 @@ fmtfloat(double value, char type, int forcesign, int leftjust, } if (vallen < 0) goto fail; - - /* - * Windows, alone among our supported platforms, likes to emit - * three-digit exponent fields even when two digits would do. Hack - * such results to look like the way everyone else does it. - */ -#ifdef WIN32 - if (vallen >= 6 && - convert[vallen - 5] == 'e' && - convert[vallen - 3] == '0') - { - convert[vallen - 3] = convert[vallen - 2]; - convert[vallen - 2] = convert[vallen - 1]; - vallen--; - } -#endif } padlen = compute_padlen(minlen, vallen + zeropadlen, leftjust); @@ -1436,17 +1394,6 @@ pg_strfromd(char *str, size_t count, int precision, double value) target.failed = true; goto fail; } - -#ifdef WIN32 - if (vallen >= 6 && - convert[vallen - 5] == 'e' && - convert[vallen - 3] == '0') - { - convert[vallen - 3] = convert[vallen - 2]; - convert[vallen - 2] = convert[vallen - 1]; - vallen--; - } -#endif } } diff --git a/src/parser/stringinfo.c b/src/parser/stringinfo.c index 9429dac46..52db50ad9 100644 --- a/src/parser/stringinfo.c +++ b/src/parser/stringinfo.c @@ -6,8 +6,8 @@ * It can be used to buffer either ordinary C strings (null-terminated text) * or arbitrary binary data. All storage is allocated with palloc(). * - * Portions Copyright (c) 2003-2025, PgPool Global Development Group - * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2026, PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/common/stringinfo.c @@ -49,7 +49,7 @@ initStringInfoInternal(StringInfo str, int initsize) static inline StringInfo makeStringInfoInternal(int initsize) { - StringInfo res = (StringInfo) palloc(sizeof(StringInfoData)); + StringInfo res = palloc_object(StringInfoData); initStringInfoInternal(res, initsize); return res; @@ -134,7 +134,7 @@ resetStringInfo(StringInfo str) * strcat. */ void -appendStringInfo(StringInfo str, const char *fmt,...) +appendStringInfo(StringInfo str, const char *fmt, ...) { int save_errno = errno; diff --git a/src/parser/value.c b/src/parser/value.c index f99883c5b..92465217d 100644 --- a/src/parser/value.c +++ b/src/parser/value.c @@ -4,8 +4,8 @@ * implementation of value nodes * * - * Copyright (c) 2003-2025, PgPool Global Development Group - * Copyright (c) 2003-2025, PostgreSQL Global Development Group + * Copyright (c) 2003-2026, PgPool Global Development Group + * Copyright (c) 2003-2026, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/parser/wchar.c b/src/parser/wchar.c index 27c972fc0..1d1afac04 100644 --- a/src/parser/wchar.c +++ b/src/parser/wchar.c @@ -12,6 +12,10 @@ #include #include "pg_wchar.h" +#ifndef pg_fallthrough +#define pg_fallthrough __attribute__((fallthrough)) +#endif + #ifndef WIN32 #define DEF_ENC2NAME(name, codepage) { #name, PG_##name } #else @@ -27,7 +31,6 @@ const pg_enc2name pg_enc2name_tbl[] = [PG_EUC_TW] = DEF_ENC2NAME(EUC_TW, 0), [PG_EUC_JIS_2004] = DEF_ENC2NAME(EUC_JIS_2004, 20932), [PG_UTF8] = DEF_ENC2NAME(UTF8, 65001), - [PG_MULE_INTERNAL] = DEF_ENC2NAME(MULE_INTERNAL, 0), [PG_LATIN1] = DEF_ENC2NAME(LATIN1, 28591), [PG_LATIN2] = DEF_ENC2NAME(LATIN2, 28592), [PG_LATIN3] = DEF_ENC2NAME(LATIN3, 28593), @@ -74,7 +77,6 @@ const char *pg_enc2gettext_tbl[] = { [PG_SQL_ASCII] = "US-ASCII", [PG_UTF8] = "UTF-8", - [PG_MULE_INTERNAL] = NULL, [PG_LATIN1] = "LATIN1", [PG_LATIN2] = "LATIN2", [PG_LATIN3] = "LATIN3", @@ -124,9 +126,9 @@ const char *pg_enc2gettext_tbl[] = * this pair specifically. Byte pair range constraints, in encoding * originator documentation, always excluded this pair. No core conversion * could translate it. However, longstanding verifychar implementations - * accepted any non-NUL byte. big5_to_euc_tw and big5_to_mic even translate - * pairs not valid per encoding originator documentation. To avoid tightening - * core or non-core conversions in a security patch, we sought this one pair. + * accepted any non-NUL byte. big5_to_euc_tw even translates pairs not + * valid per encoding originator documentation. To avoid tightening core + * or non-core conversions in a security patch, we sought this one pair. * * PQescapeString() historically used spaces for BYTE1; many other values * could suffice for BYTE1. @@ -161,6 +163,9 @@ const char *pg_enc2gettext_tbl[] = * subset to the ASCII routines to ensure consistency. */ +/* No error-reporting facility. Ignore incomplete trailing byte sequence. */ +#define MB2CHAR_NEED_AT_LEAST(len, need) if ((len) < (need)) break + /* * SQL/ASCII */ @@ -206,22 +211,24 @@ pg_euc2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) while (len > 0 && *from) { - if (*from == SS2 && len >= 2) /* JIS X 0201 (so called "1 byte - * KANA") */ + if (*from == SS2) /* JIS X 0201 (so called "1 byte KANA") */ { + MB2CHAR_NEED_AT_LEAST(len, 2); from++; *to = (SS2 << 8) | *from++; len -= 2; } - else if (*from == SS3 && len >= 3) /* JIS X 0212 KANJI */ + else if (*from == SS3) /* JIS X 0212 KANJI */ { + MB2CHAR_NEED_AT_LEAST(len, 3); from++; *to = (SS3 << 16) | (*from++ << 8); *to |= *from++; len -= 3; } - else if (IS_HIGHBIT_SET(*from) && len >= 2) /* JIS X 0208 KANJI */ + else if (IS_HIGHBIT_SET(*from)) /* JIS X 0208 KANJI */ { + MB2CHAR_NEED_AT_LEAST(len, 2); *to = *from++ << 8; *to |= *from++; len -= 2; @@ -333,22 +340,25 @@ pg_euccn2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) while (len > 0 && *from) { - if (*from == SS2 && len >= 3) /* code set 2 (unused?) */ + if (*from == SS2) /* code set 2 (unused?) */ { + MB2CHAR_NEED_AT_LEAST(len, 3); from++; *to = (SS2 << 16) | (*from++ << 8); *to |= *from++; len -= 3; } - else if (*from == SS3 && len >= 3) /* code set 3 (unused ?) */ + else if (*from == SS3) /* code set 3 (unused ?) */ { + MB2CHAR_NEED_AT_LEAST(len, 3); from++; *to = (SS3 << 16) | (*from++ << 8); *to |= *from++; len -= 3; } - else if (IS_HIGHBIT_SET(*from) && len >= 2) /* code set 1 */ + else if (IS_HIGHBIT_SET(*from)) /* code set 1 */ { + MB2CHAR_NEED_AT_LEAST(len, 2); *to = *from++ << 8; *to |= *from++; len -= 2; @@ -365,12 +375,22 @@ pg_euccn2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) return cnt; } +/* + * mbverifychar does not accept SS2 or SS3 (CS2 and CS3 are not defined for + * EUC_CN), but mb2wchar_with_len does. Tell a coherent story for code that + * relies on agreement between mb2wchar_with_len and mblen. Invalid text + * datums (e.g. from shared catalogs) reach this. + */ static int pg_euccn_mblen(const unsigned char *s) { int len; - if (IS_HIGHBIT_SET(*s)) + if (*s == SS2) + len = 3; + else if (*s == SS3) + len = 3; + else if (IS_HIGHBIT_SET(*s)) len = 2; else len = 1; @@ -400,23 +420,26 @@ pg_euctw2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) while (len > 0 && *from) { - if (*from == SS2 && len >= 4) /* code set 2 */ + if (*from == SS2) /* code set 2 */ { + MB2CHAR_NEED_AT_LEAST(len, 4); from++; *to = (((uint32) SS2) << 24) | (*from++ << 16); *to |= *from++ << 8; *to |= *from++; len -= 4; } - else if (*from == SS3 && len >= 3) /* code set 3 (unused?) */ + else if (*from == SS3) /* code set 3 (unused?) */ { + MB2CHAR_NEED_AT_LEAST(len, 3); from++; *to = (SS3 << 16) | (*from++ << 8); *to |= *from++; len -= 3; } - else if (IS_HIGHBIT_SET(*from) && len >= 2) /* code set 2 */ + else if (IS_HIGHBIT_SET(*from)) /* code set 2 */ { + MB2CHAR_NEED_AT_LEAST(len, 2); *to = *from++ << 8; *to |= *from++; len -= 2; @@ -553,8 +576,7 @@ pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) } else if ((*from & 0xe0) == 0xc0) { - if (len < 2) - break; /* drop trailing incomplete char */ + MB2CHAR_NEED_AT_LEAST(len, 2); c1 = *from++ & 0x1f; c2 = *from++ & 0x3f; *to = (c1 << 6) | c2; @@ -562,8 +584,7 @@ pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) } else if ((*from & 0xf0) == 0xe0) { - if (len < 3) - break; /* drop trailing incomplete char */ + MB2CHAR_NEED_AT_LEAST(len, 3); c1 = *from++ & 0x0f; c2 = *from++ & 0x3f; c3 = *from++ & 0x3f; @@ -572,8 +593,7 @@ pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) } else if ((*from & 0xf8) == 0xf0) { - if (len < 4) - break; /* drop trailing incomplete char */ + MB2CHAR_NEED_AT_LEAST(len, 4); c1 = *from++ & 0x07; c2 = *from++ & 0x3f; c3 = *from++ & 0x3f; @@ -698,7 +718,8 @@ mbbisearch(pg_wchar ucs, const struct mbinterval *table, int max) } -/* The following functions define the column width of an ISO 10646 +/* + * The following functions define the column width of an ISO 10646 * character as follows: * * - The null character (U+0000) has a column width of 0. @@ -762,173 +783,6 @@ pg_utf_dsplen(const unsigned char *s) return ucs_wcwidth(utf8_to_unicode(s)); } -/* - * convert mule internal code to pg_wchar - * caller should allocate enough space for "to" - * len: length of from. - * "from" not necessarily null terminated. - */ -static int -pg_mule2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) -{ - int cnt = 0; - - while (len > 0 && *from) - { - if (IS_LC1(*from) && len >= 2) - { - *to = *from++ << 16; - *to |= *from++; - len -= 2; - } - else if (IS_LCPRV1(*from) && len >= 3) - { - from++; - *to = *from++ << 16; - *to |= *from++; - len -= 3; - } - else if (IS_LC2(*from) && len >= 3) - { - *to = *from++ << 16; - *to |= *from++ << 8; - *to |= *from++; - len -= 3; - } - else if (IS_LCPRV2(*from) && len >= 4) - { - from++; - *to = *from++ << 16; - *to |= *from++ << 8; - *to |= *from++; - len -= 4; - } - else - { /* assume ASCII */ - *to = (unsigned char) *from++; - len--; - } - to++; - cnt++; - } - *to = 0; - return cnt; -} - -/* - * convert pg_wchar to mule internal code - * caller should allocate enough space for "to" - * len: length of from. - * "from" not necessarily null terminated. - */ -static int -pg_wchar2mule_with_len(const pg_wchar *from, unsigned char *to, int len) -{ - int cnt = 0; - - while (len > 0 && *from) - { - unsigned char lb; - - lb = (*from >> 16) & 0xff; - if (IS_LC1(lb)) - { - *to++ = lb; - *to++ = *from & 0xff; - cnt += 2; - } - else if (IS_LC2(lb)) - { - *to++ = lb; - *to++ = (*from >> 8) & 0xff; - *to++ = *from & 0xff; - cnt += 3; - } - else if (IS_LCPRV1_A_RANGE(lb)) - { - *to++ = LCPRV1_A; - *to++ = lb; - *to++ = *from & 0xff; - cnt += 3; - } - else if (IS_LCPRV1_B_RANGE(lb)) - { - *to++ = LCPRV1_B; - *to++ = lb; - *to++ = *from & 0xff; - cnt += 3; - } - else if (IS_LCPRV2_A_RANGE(lb)) - { - *to++ = LCPRV2_A; - *to++ = lb; - *to++ = (*from >> 8) & 0xff; - *to++ = *from & 0xff; - cnt += 4; - } - else if (IS_LCPRV2_B_RANGE(lb)) - { - *to++ = LCPRV2_B; - *to++ = lb; - *to++ = (*from >> 8) & 0xff; - *to++ = *from & 0xff; - cnt += 4; - } - else - { - *to++ = *from & 0xff; - cnt += 1; - } - from++; - len--; - } - *to = 0; - return cnt; -} - -int -pg_mule_mblen(const unsigned char *s) -{ - int len; - - if (IS_LC1(*s)) - len = 2; - else if (IS_LCPRV1(*s)) - len = 3; - else if (IS_LC2(*s)) - len = 3; - else if (IS_LCPRV2(*s)) - len = 4; - else - len = 1; /* assume ASCII */ - return len; -} - -static int -pg_mule_dsplen(const unsigned char *s) -{ - int len; - - /* - * Note: it's not really appropriate to assume that all multibyte charsets - * are double-wide on screen. But this seems an okay approximation for - * the MULE charsets we currently support. - */ - - if (IS_LC1(*s)) - len = 1; - else if (IS_LCPRV1(*s)) - len = 1; - else if (IS_LC2(*s)) - len = 2; - else if (IS_LCPRV2(*s)) - len = 2; - else - len = 1; /* assume ASCII */ - - return len; -} - /* * ISO8859-1 */ @@ -1453,56 +1307,6 @@ pg_johab_verifystr(const unsigned char *s, int len) return s - start; } -static int -pg_mule_verifychar(const unsigned char *s, int len) -{ - int l, - mbl; - unsigned char c; - - l = mbl = pg_mule_mblen(s); - - if (len < l) - return -1; - - while (--l > 0) - { - c = *++s; - if (!IS_HIGHBIT_SET(c)) - return -1; - } - return mbl; -} - -static int -pg_mule_verifystr(const unsigned char *s, int len) -{ - const unsigned char *start = s; - - while (len > 0) - { - int l; - - /* fast path for ASCII-subset characters */ - if (!IS_HIGHBIT_SET(*s)) - { - if (*s == '\0') - break; - l = 1; - } - else - { - l = pg_mule_verifychar(s, len); - if (l == -1) - break; - } - s += l; - len -= l; - } - - return s - start; -} - static int pg_latin1_verifychar(const unsigned char *s, int len) { @@ -1966,12 +1770,12 @@ pg_utf8_islegal(const unsigned char *source, int length) a = source[3]; if (a < 0x80 || a > 0xBF) return false; - /* FALL THRU */ + pg_fallthrough; case 3: a = source[2]; if (a < 0x80 || a > 0xBF) return false; - /* FALL THRU */ + pg_fallthrough; case 2: a = source[1]; switch (*source) @@ -1997,7 +1801,7 @@ pg_utf8_islegal(const unsigned char *source, int length) return false; break; } - /* FALL THRU */ + pg_fallthrough; case 1: a = *source; if (a >= 0x80 && a < 0xC2) @@ -2239,12 +2043,11 @@ pg_encoding_set_invalid(int encoding, char *dst) const pg_wchar_tbl pg_wchar_table[] = { [PG_SQL_ASCII] = {pg_ascii2wchar_with_len, pg_wchar2single_with_len, pg_ascii_mblen, pg_ascii_dsplen, pg_ascii_verifychar, pg_ascii_verifystr, 1}, [PG_EUC_JP] = {pg_eucjp2wchar_with_len, pg_wchar2euc_with_len, pg_eucjp_mblen, pg_eucjp_dsplen, pg_eucjp_verifychar, pg_eucjp_verifystr, 3}, - [PG_EUC_CN] = {pg_euccn2wchar_with_len, pg_wchar2euc_with_len, pg_euccn_mblen, pg_euccn_dsplen, pg_euccn_verifychar, pg_euccn_verifystr, 2}, + [PG_EUC_CN] = {pg_euccn2wchar_with_len, pg_wchar2euc_with_len, pg_euccn_mblen, pg_euccn_dsplen, pg_euccn_verifychar, pg_euccn_verifystr, 3}, [PG_EUC_KR] = {pg_euckr2wchar_with_len, pg_wchar2euc_with_len, pg_euckr_mblen, pg_euckr_dsplen, pg_euckr_verifychar, pg_euckr_verifystr, 3}, [PG_EUC_TW] = {pg_euctw2wchar_with_len, pg_wchar2euc_with_len, pg_euctw_mblen, pg_euctw_dsplen, pg_euctw_verifychar, pg_euctw_verifystr, 4}, [PG_EUC_JIS_2004] = {pg_eucjp2wchar_with_len, pg_wchar2euc_with_len, pg_eucjp_mblen, pg_eucjp_dsplen, pg_eucjp_verifychar, pg_eucjp_verifystr, 3}, [PG_UTF8] = {pg_utf2wchar_with_len, pg_wchar2utf_with_len, pg_utf_mblen, pg_utf_dsplen, pg_utf8_verifychar, pg_utf8_verifystr, 4}, - [PG_MULE_INTERNAL] = {pg_mule2wchar_with_len, pg_wchar2mule_with_len, pg_mule_mblen, pg_mule_dsplen, pg_mule_verifychar, pg_mule_verifystr, 4}, [PG_LATIN1] = {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, [PG_LATIN2] = {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, [PG_LATIN3] = {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, diff --git a/src/protocol/pool_process_query.c b/src/protocol/pool_process_query.c index ca01d1ea5..b01c9b403 100644 --- a/src/protocol/pool_process_query.c +++ b/src/protocol/pool_process_query.c @@ -4042,7 +4042,7 @@ is_internal_transaction_needed(Node *node) * T_AlterDefaultPrivilegesStmt, Our parser does not support yet */ T_ClosePortalStmt, - T_ClusterStmt, + T_RepackStmt, T_CopyStmt, T_CreateStmt, /* CREATE TABLE */ T_DefineStmt, /* CREATE AGGREGATE, OPERATOR, TYPE */ @@ -4133,9 +4133,9 @@ is_internal_transaction_needed(Node *node) /* * Check CLUSTER with no option. If so, do not start transaction */ - else if (IsA(node, ClusterStmt)) + else if (IsA(node, RepackStmt)) { - if (((ClusterStmt *) node)->relation == NULL) + if (((RepackStmt *) node)->relation == NULL) return false; } diff --git a/src/rewrite/pool_timestamp.c b/src/rewrite/pool_timestamp.c index 050a0210c..c12844d8b 100644 --- a/src/rewrite/pool_timestamp.c +++ b/src/rewrite/pool_timestamp.c @@ -729,7 +729,9 @@ rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext *ctx) raw_expression_tree_walker( (Node *) u_stmt->targetList, rewrite_timestamp_walker, (void *) ctx); - + raw_expression_tree_walker( + (Node *) u_stmt->forPortionOf, + rewrite_timestamp_walker, (void *) ctx); raw_expression_tree_walker( (Node *) u_stmt->whereClause, rewrite_timestamp_walker, (void *) ctx); @@ -875,7 +877,9 @@ rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, raw_expression_tree_walker( (Node *) d_stmt->usingClause, rewrite_timestamp_walker, (void *) &ctx); - + raw_expression_tree_walker( + (Node *) d_stmt->forPortionOf, + rewrite_timestamp_walker, (void *) &ctx); raw_expression_tree_walker( (Node *) d_stmt->whereClause, rewrite_timestamp_walker, (void *) &ctx); @@ -1585,6 +1589,8 @@ raw_expression_tree_walker(Node *node, return true; if (WALK(stmt->usingClause, context)) return true; + if (WALK(stmt->forPortionOf, context)) + return true; if (WALK(stmt->whereClause, context)) return true; if (WALK(stmt->returningClause, context)) @@ -1601,6 +1607,8 @@ raw_expression_tree_walker(Node *node, return true; if (WALK(stmt->targetList, context)) return true; + if (WALK(stmt->forPortionOf, context)) + return true; if (WALK(stmt->whereClause, context)) return true; if (WALK(stmt->fromClause, context)) @@ -1849,6 +1857,18 @@ raw_expression_tree_walker(Node *node, break; case T_CommonTableExpr: return WALK(((CommonTableExpr *) node)->ctequery, context); + case T_ForPortionOfClause: + { + ForPortionOfClause *fpo = (ForPortionOfClause *) node; + + if (WALK(fpo->target, context)) + return true; + if (WALK(fpo->target_start, context)) + return true; + if (WALK(fpo->target_end, context)) + return true; + } + break; default: /* diff --git a/src/sql/pgpool-regclass/pgpool-regclass.c b/src/sql/pgpool-regclass/pgpool-regclass.c index 9317d8aa1..e0858762b 100644 --- a/src/sql/pgpool-regclass/pgpool-regclass.c +++ b/src/sql/pgpool-regclass/pgpool-regclass.c @@ -35,6 +35,7 @@ #include "utils/elog.h" #include "utils/syscache.h" #include "utils/varlena.h" +#include "utils/lsyscache.h" #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC; -- 2.52.0