From d8aa3cc65bfbafc6753ba3c7dc74251b68b178df Mon Sep 17 00:00:00 2001 From: Lukas Fittl Date: Wed, 2 Nov 2022 16:23:46 -0700 Subject: [PATCH] Update Postgres to 13.8 and backport bc7a40b4 to fix new Xcode build See https://postgr.es/m/1803927.1665938411@sss.pgh.pa.us for discussion of the Xcode build issue. Fixed in bc7a40b4, which is on REL_13_STABLE but not yet in an official Postgres release. In passing this also fixes a extract source issue with newer clang versions. --- Makefile | 4 +- README.md | 4 +- ..._parser_additional_param_ref_support.patch | 4 +- ...r_support_question_mark_as_param_ref.patch | 6 +- patches/03_lexer_track_yyllocend.patch | 6 +- patches/04_lexer_comments_as_tokens.patch | 8 +- .../05_limit_option_enum_value_default.patch | 2 +- patches/06_alloc_set_delete_free_list.patch | 2 +- patches/07_plpgsql_start_finish_datums.patch | 10 +- ...length_delimiter_in_regression_tests.patch | 2 +- patches/09_backport_gram_ref_p_fix.patch | 71 ++ pg_query.h | 4 +- protobuf/pg_query.pb-c.c | 23 +- protobuf/pg_query.pb-c.h | 7 +- protobuf/pg_query.proto | 3 +- scripts/extract_source.rb | 18 +- src/pg_query_fingerprint_defs.c | 5 + src/pg_query_outfuncs_defs.c | 1 + src/pg_query_readfuncs_defs.c | 1 + src/postgres/include/access/twophase.h | 2 + src/postgres/include/access/xact.h | 6 + src/postgres/include/access/xlog_internal.h | 11 +- src/postgres/include/access/xlogreader.h | 10 + src/postgres/include/catalog/dependency.h | 2 + src/postgres/include/catalog/pg_class.h | 2 +- src/postgres/include/catalog/pg_class_d.h | 2 +- src/postgres/include/catalog/pg_control.h | 2 + src/postgres/include/catalog/pg_operator.h | 4 +- src/postgres/include/catalog/pg_publication.h | 3 + src/postgres/include/catalog/pg_type.h | 1 + src/postgres/include/commands/async.h | 2 +- src/postgres/include/commands/tablespace.h | 2 + src/postgres/include/commands/trigger.h | 8 + src/postgres/include/lib/simplehash.h | 26 +- src/postgres/include/libpq/libpq.h | 1 + src/postgres/include/mb/pg_wchar.h | 1 + src/postgres/include/miscadmin.h | 35 +- src/postgres/include/nodes/execnodes.h | 4 +- src/postgres/include/nodes/parsenodes.h | 9 +- src/postgres/include/nodes/pathnodes.h | 3 +- src/postgres/include/nodes/pg_list.h | 1 + src/postgres/include/nodes/plannodes.h | 21 +- src/postgres/include/optimizer/optimizer.h | 5 - src/postgres/include/parser/gram.h | 4 +- src/postgres/include/parser/kwlist.h | 2 +- src/postgres/include/parser/parse_coerce.h | 1 + src/postgres/include/pg_config.h | 29 +- src/postgres/include/pgstat.h | 3 +- src/postgres/include/plpgsql.h | 4 +- src/postgres/include/port.h | 4 + src/postgres/include/port/pg_bitutils.h | 50 +- .../include/replication/reorderbuffer.h | 11 +- src/postgres/include/replication/slot.h | 2 +- src/postgres/include/storage/block.h | 2 +- src/postgres/include/storage/lock.h | 11 +- src/postgres/include/storage/lwlock.h | 1 + src/postgres/include/storage/proc.h | 14 + src/postgres/include/storage/s_lock.h | 24 + src/postgres/include/tcop/pquery.h | 6 + src/postgres/include/utils/builtins.h | 1 + src/postgres/include/utils/inval.h | 1 + src/postgres/include/utils/portal.h | 13 + src/postgres/include/utils/rel.h | 1 - src/postgres/include/utils/relcache.h | 3 +- src/postgres/include/utils/snapmgr.h | 1 + src/postgres/src_backend_catalog_namespace.c | 1 + src/postgres/src_backend_libpq_pqcomm.c | 8 + src/postgres/src_backend_nodes_copyfuncs.c | 56 +- src/postgres/src_backend_nodes_equalfuncs.c | 1 + src/postgres/src_backend_nodes_list.c | 12 + src/postgres/src_backend_parser_gram.c | 21 +- src/postgres/src_backend_parser_scan.c | 743 ++++++++++++------ src/postgres/src_backend_tcop_postgres.c | 12 +- .../src_backend_utils_adt_ruleutils.c | 48 +- src/postgres/src_backend_utils_misc_guc.c | 1 + src/postgres/src_common_wchar.c | 11 + src/postgres/src_pl_plpgsql_src_pl_comp.c | 6 +- src/postgres/src_pl_plpgsql_src_pl_gram.c | 2 +- src/postgres/src_port_pg_bitutils.c | 23 +- src/postgres/src_port_snprintf.c | 16 +- srcdata/enum_defs.json | 4 +- srcdata/struct_defs.json | 7 +- test/parse_tests.c | 54 +- test/sql/postgres_regress/aggregates.sql | 11 + test/sql/postgres_regress/alter_table.sql | 78 +- test/sql/postgres_regress/arrays.sql | 2 + test/sql/postgres_regress/btree_index.sql | 11 + test/sql/postgres_regress/cluster.sql | 6 + test/sql/postgres_regress/create_index.sql | 26 +- test/sql/postgres_regress/create_view.sql | 11 +- test/sql/postgres_regress/dbsize.sql | 16 + test/sql/postgres_regress/domain.sql | 26 + test/sql/postgres_regress/errors.sql | 4 + test/sql/postgres_regress/event_trigger.sql | 32 +- test/sql/postgres_regress/expressions.sql | 52 ++ test/sql/postgres_regress/fast_default.sql | 14 + test/sql/postgres_regress/foreign_data.sql | 1 + test/sql/postgres_regress/generated.sql | 8 +- test/sql/postgres_regress/gist.sql | 27 + test/sql/postgres_regress/groupingsets.sql | 32 + test/sql/postgres_regress/hash_func.sql | 9 + .../sql/postgres_regress/incremental_sort.sql | 2 - test/sql/postgres_regress/int2.sql | 4 + test/sql/postgres_regress/join.sql | 28 + test/sql/postgres_regress/limit.sql | 5 + test/sql/postgres_regress/matview.sql | 10 +- test/sql/postgres_regress/numeric.sql | 36 + test/sql/postgres_regress/portals.sql | 20 + test/sql/postgres_regress/prepared_xacts.sql | 6 + test/sql/postgres_regress/privileges.sql | 73 +- test/sql/postgres_regress/publication.sql | 42 +- test/sql/postgres_regress/rangefuncs.sql | 15 + test/sql/postgres_regress/regex.sql | 9 + test/sql/postgres_regress/reloptions.sql | 6 +- .../sql/postgres_regress/replica_identity.sql | 4 + test/sql/postgres_regress/rowsecurity.sql | 10 + test/sql/postgres_regress/rowtypes.sql | 6 +- test/sql/postgres_regress/rules.sql | 14 + test/sql/postgres_regress/select.sql | 5 + test/sql/postgres_regress/select_parallel.sql | 10 + test/sql/postgres_regress/stats_ext.sql | 55 +- test/sql/postgres_regress/subscription.sql | 3 + test/sql/postgres_regress/sysviews.sql | 3 + test/sql/postgres_regress/timestamp.sql | 14 + test/sql/postgres_regress/timestamptz.sql | 14 + test/sql/postgres_regress/triggers.sql | 57 +- test/sql/postgres_regress/type_sanity.sql | 95 +++ test/sql/postgres_regress/unicode.sql | 4 +- test/sql/postgres_regress/vacuum.sql | 6 +- test/sql/postgres_regress/with.sql | 92 ++- test/sql/postgres_regress/xml.sql | 3 + test/sql/postgres_regress/xmlmap.sql | 10 +- 132 files changed, 2063 insertions(+), 522 deletions(-) create mode 100644 patches/09_backport_gram_ref_p_fix.patch diff --git a/Makefile b/Makefile index a4cae119..1f9a130c 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ ARLIB = lib$(TARGET).a PGDIR = $(root_dir)/tmp/postgres PGDIRBZ2 = $(root_dir)/tmp/postgres.tar.bz2 -PG_VERSION = 13.3 +PG_VERSION = 13.8 PG_VERSION_MAJOR = $(call word-dot,$(PG_VERSION),1) PROTOC_VERSION = 3.14.0 @@ -120,6 +120,7 @@ $(PGDIR): cd $(PGDIR); patch -p1 < $(root_dir)/patches/06_alloc_set_delete_free_list.patch cd $(PGDIR); patch -p1 < $(root_dir)/patches/07_plpgsql_start_finish_datums.patch cd $(PGDIR); patch -p1 < $(root_dir)/patches/08_avoid_zero_length_delimiter_in_regression_tests.patch + cd $(PGDIR); patch -p1 < $(root_dir)/patches/09_backport_gram_ref_p_fix.patch cd $(PGDIR); ./configure $(PG_CONFIGURE_FLAGS) cd $(PGDIR); rm src/pl/plpgsql/src/pl_gram.h cd $(PGDIR); make -C src/pl/plpgsql/src pl_gram.h @@ -133,6 +134,7 @@ extract_source: $(PGDIR) mkdir ./src/postgres/include LIBCLANG=/Library/Developer/CommandLineTools/usr/lib/libclang.dylib ruby ./scripts/extract_source.rb $(PGDIR)/ ./src/postgres/ cp $(PGDIR)/src/include/storage/dsm_impl.h ./src/postgres/include/storage + cp $(PGDIR)/src/include/port/atomics/arch-x86.h ./src/postgres/include/port/atomics cp $(PGDIR)/src/include/port/atomics/arch-arm.h ./src/postgres/include/port/atomics cp $(PGDIR)/src/include/port/atomics/arch-ppc.h ./src/postgres/include/port/atomics touch ./src/postgres/guc-file.c diff --git a/README.md b/README.md index 96d86d95..90346cd1 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ This will output the parse tree (whitespace adjusted here for better readability ```json { - "version": 130003, + "version": 130008, "stmts": [ { "stmt": { @@ -124,7 +124,7 @@ int main() { This will output the following: ``` - version: 130003, tokens: 7, size: 77 + version: 130008, tokens: 7, size: 77 "SELECT" = [ 0, 6, SELECT, RESERVED_KEYWORD ] "update" = [ 7, 13, UPDATE, UNRESERVED_KEYWORD ] "AS" = [ 14, 16, AS, RESERVED_KEYWORD ] diff --git a/patches/01_parser_additional_param_ref_support.patch b/patches/01_parser_additional_param_ref_support.patch index 01282844..3d1939b8 100644 --- a/patches/01_parser_additional_param_ref_support.patch +++ b/patches/01_parser_additional_param_ref_support.patch @@ -1,4 +1,4 @@ -commit 2be7057a595bdf4794dd4f9397de19a0fcd0dc23 +commit 708fe3468d0f373c2208ae927d0de52247f2fda8 Author: Lukas Fittl Date: Sun Jan 3 15:06:25 2021 -0800 @@ -23,7 +23,7 @@ Date: Sun Jan 3 15:06:25 2021 -0800 SELECT INTERVAL (6) $1; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y -index 3adc087e3f..cf2b521c23 100644 +index 74339aa4db..4529fea74e 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -162,6 +162,8 @@ static Node *makeBitStringConst(char *str, int location); diff --git a/patches/02_parser_support_question_mark_as_param_ref.patch b/patches/02_parser_support_question_mark_as_param_ref.patch index 44b37a71..9d23e254 100644 --- a/patches/02_parser_support_question_mark_as_param_ref.patch +++ b/patches/02_parser_support_question_mark_as_param_ref.patch @@ -1,4 +1,4 @@ -commit 911e2c633fc9f75ea587f9763470ee6140cea0f1 +commit c813b6930bd68577f7db381ff9178a807c989942 Author: Lukas Fittl Date: Sun Jan 3 15:56:21 2021 -0800 @@ -14,7 +14,7 @@ Date: Sun Jan 3 15:56:21 2021 -0800 should be considered deprecated. diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y -index cf2b521c23..ad796b87e1 100644 +index 4529fea74e..8beb6fef5e 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -164,6 +164,7 @@ static Node *makeAConst(Value *v, int location); @@ -250,7 +250,7 @@ index cf2b521c23..ad796b87e1 100644 * Create a RoleSpec with the given type */ diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l -index b1ea0cb538..9ba31f418c 100644 +index b1ea0cb538..a0dfcf3b99 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -277,6 +277,9 @@ xehexesc [\\]x[0-9A-Fa-f]{1,2} diff --git a/patches/03_lexer_track_yyllocend.patch b/patches/03_lexer_track_yyllocend.patch index 2098124c..2a919c92 100644 --- a/patches/03_lexer_track_yyllocend.patch +++ b/patches/03_lexer_track_yyllocend.patch @@ -1,4 +1,4 @@ -commit 70279ba982378d70ba19e312bf5acd627109acce +commit 386cf95ca17d28ae4bc7db92a784ab8f6dde9f8b Author: Lukas Fittl Date: Sun Jan 3 15:59:40 2021 -0800 @@ -8,7 +8,7 @@ Date: Sun Jan 3 15:59:40 2021 -0800 as this is made available by pg_query for uses such as syntax highlighting. diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l -index 9ba31f418c..5caa03e395 100644 +index a0dfcf3b99..768170bb30 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -517,6 +517,7 @@ other . @@ -75,7 +75,7 @@ index 9ba31f418c..5caa03e395 100644 return IDENT; } -@@ -1065,6 +1074,7 @@ other . +@@ -1068,6 +1077,7 @@ other . */ ident = downcase_truncate_identifier(yytext, yyleng, true); yylval->str = ident; diff --git a/patches/04_lexer_comments_as_tokens.patch b/patches/04_lexer_comments_as_tokens.patch index fd290771..b748990c 100644 --- a/patches/04_lexer_comments_as_tokens.patch +++ b/patches/04_lexer_comments_as_tokens.patch @@ -1,4 +1,4 @@ -commit 2e6aded5d64f6825e8e4e100d2234b3e89b62cd6 +commit 17aa7e51f4a3bf12d4662720ef39f6f60336dc83 Author: Lukas Fittl Date: Sun Jan 3 16:01:44 2021 -0800 @@ -12,7 +12,7 @@ Date: Sun Jan 3 16:01:44 2021 -0800 this change, the lexer returns them as SQL_COMMENT/C_COMMENT tokens. diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y -index bcdda00a3a..9a581cbde6 100644 +index 8beb6fef5e..f2c963e801 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -620,6 +620,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); @@ -38,7 +38,7 @@ index be86eb37fe..07b8fd486f 100644 return cur_token; } diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l -index 5caa03e395..6d7e2f0f12 100644 +index 768170bb30..24fd149497 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -223,7 +223,7 @@ non_newline [^\n\r] @@ -100,7 +100,7 @@ index a2eeeba217..cbfb92384a 100644 return cur_token; } diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y -index 3e84162487..d1e6e714ab 100644 +index fc6cedb7a4..1cf9405d81 100644 --- a/src/pl/plpgsql/src/pl_gram.y +++ b/src/pl/plpgsql/src/pl_gram.y @@ -236,6 +236,7 @@ static void check_raise_parameters(PLpgSQL_stmt_raise *stmt); diff --git a/patches/05_limit_option_enum_value_default.patch b/patches/05_limit_option_enum_value_default.patch index 7249ca73..cba76a69 100644 --- a/patches/05_limit_option_enum_value_default.patch +++ b/patches/05_limit_option_enum_value_default.patch @@ -1,4 +1,4 @@ -commit d72ada28933f0e04fe2b4481f7886997050ec403 +commit e855d8c81a0cd73aa1913825e7b4395961e6f2c9 Author: Lukas Fittl Date: Sun Jan 3 15:57:25 2021 -0800 diff --git a/patches/06_alloc_set_delete_free_list.patch b/patches/06_alloc_set_delete_free_list.patch index 593def61..f9f9b4b9 100644 --- a/patches/06_alloc_set_delete_free_list.patch +++ b/patches/06_alloc_set_delete_free_list.patch @@ -1,4 +1,4 @@ -commit bac06c62ccb4d4d5bfa7ae30e3ebef64f37d2254 +commit f716536100e86bb410341daf3f84cf23f4e3adc2 Author: Lukas Fittl Date: Sat Jan 9 23:42:42 2021 -0800 diff --git a/patches/07_plpgsql_start_finish_datums.patch b/patches/07_plpgsql_start_finish_datums.patch index 950d459c..996848ea 100644 --- a/patches/07_plpgsql_start_finish_datums.patch +++ b/patches/07_plpgsql_start_finish_datums.patch @@ -1,4 +1,4 @@ -commit 80cb7dcdd721b21fd1e56e915482fd4345a80b17 +commit 4850baf8039f2714d01c45a64af7ccbd12bbbd64 Author: Lukas Fittl Date: Sun Jan 10 00:28:33 2021 -0800 @@ -8,7 +8,7 @@ Date: Sun Jan 10 00:28:33 2021 -0800 the already exported plpgsql_adddatum. diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c -index 828ff5a288..4670fcafa2 100644 +index cb0ce3900b..fbd0ad8bd0 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -105,8 +105,6 @@ static Node *make_datum_param(PLpgSQL_expr *expr, int dno, int location); @@ -20,7 +20,7 @@ index 828ff5a288..4670fcafa2 100644 static void compute_function_hashkey(FunctionCallInfo fcinfo, Form_pg_proc procStruct, PLpgSQL_func_hashkey *hashkey, -@@ -2270,7 +2268,7 @@ plpgsql_parse_err_condition(char *condname) +@@ -2272,7 +2270,7 @@ plpgsql_parse_err_condition(char *condname) * plpgsql_start_datums Initialize datum list at compile startup. * ---------- */ @@ -29,7 +29,7 @@ index 828ff5a288..4670fcafa2 100644 plpgsql_start_datums(void) { datums_alloc = 128; -@@ -2304,7 +2302,7 @@ plpgsql_adddatum(PLpgSQL_datum *newdatum) +@@ -2306,7 +2304,7 @@ plpgsql_adddatum(PLpgSQL_datum *newdatum) * plpgsql_finish_datums Copy completed datum info into function struct. * ---------- */ @@ -39,7 +39,7 @@ index 828ff5a288..4670fcafa2 100644 { Size copiable_size = 0; diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h -index 0c3d30fb13..25fdd20bbf 100644 +index bc6eefb60b..53864ca881 100644 --- a/src/pl/plpgsql/src/plpgsql.h +++ b/src/pl/plpgsql/src/plpgsql.h @@ -1263,6 +1263,8 @@ extern PLpgSQL_recfield *plpgsql_build_recfield(PLpgSQL_rec *rec, diff --git a/patches/08_avoid_zero_length_delimiter_in_regression_tests.patch b/patches/08_avoid_zero_length_delimiter_in_regression_tests.patch index 764570ac..947a9fc6 100644 --- a/patches/08_avoid_zero_length_delimiter_in_regression_tests.patch +++ b/patches/08_avoid_zero_length_delimiter_in_regression_tests.patch @@ -1,4 +1,4 @@ -commit da83e9064fad6128f1968df975b3ad56377a4476 +commit 48cc023e889e02f8f172c5130a6f958c92da3ddf Author: Lukas Fittl Date: Sat Feb 20 04:38:04 2021 -0800 diff --git a/patches/09_backport_gram_ref_p_fix.patch b/patches/09_backport_gram_ref_p_fix.patch new file mode 100644 index 00000000..fcdc3de7 --- /dev/null +++ b/patches/09_backport_gram_ref_p_fix.patch @@ -0,0 +1,71 @@ +commit c3506d3dd7ca1fd2ad88a038bce507f104b1e53f +Author: Tom Lane +Date: Sun Oct 16 15:27:04 2022 -0400 + + Rename parser token REF to REF_P to avoid a symbol conflict. + + In the latest version of Apple's macOS SDK, + fails to compile if "REF" is #define'd as something. + Apple may or may not agree that this is a bug, and even if + they do accept the bug report I filed, they probably won't + fix it very quickly. In the meantime, our back branches will all + fail to compile gram.y. v15 and HEAD currently escape the problem + thanks to the refactoring done in 98e93a1fc, but that's purely + accidental. Moreover, since that patch removed a widely-visible + inclusion of , back-patching it seems too likely to break + third-party code. + + Instead, change the token's code name to REF_P, following our usual + convention for naming parser tokens that are likely to have symbol + conflicts. The effects of that should be localized to the grammar + and immediately surrounding files, so it seems like a safer answer. + + Per project policy that we want to keep recently-out-of-support + branches buildable on modern systems, back-patch all the way to 9.2. + + Discussion: https://postgr.es/m/1803927.1665938411@sss.pgh.pa.us + +diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y +index f2c963e801..fc1de59430 100644 +--- a/src/backend/parser/gram.y ++++ b/src/backend/parser/gram.y +@@ -692,7 +692,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); + + QUOTE + +- RANGE READ REAL REASSIGN RECHECK RECURSIVE REF REFERENCES REFERENCING ++ RANGE READ REAL REASSIGN RECHECK RECURSIVE REF_P REFERENCES REFERENCING + REFRESH REINDEX RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA + RESET RESTART RESTRICT RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP + ROUTINE ROUTINES ROW ROWS RULE +@@ -14369,7 +14369,7 @@ xmlexists_argument: + ; + + xml_passing_mech: +- BY REF ++ BY REF_P + | BY VALUE_P + ; + +@@ -15660,7 +15660,7 @@ unreserved_keyword: + | REASSIGN + | RECHECK + | RECURSIVE +- | REF ++ | REF_P + | REFERENCING + | REFRESH + | REINDEX +diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h +index 08f22ce211..4121a53ba0 100644 +--- a/src/include/parser/kwlist.h ++++ b/src/include/parser/kwlist.h +@@ -330,7 +330,7 @@ PG_KEYWORD("real", REAL, COL_NAME_KEYWORD) + PG_KEYWORD("reassign", REASSIGN, UNRESERVED_KEYWORD) + PG_KEYWORD("recheck", RECHECK, UNRESERVED_KEYWORD) + PG_KEYWORD("recursive", RECURSIVE, UNRESERVED_KEYWORD) +-PG_KEYWORD("ref", REF, UNRESERVED_KEYWORD) ++PG_KEYWORD("ref", REF_P, UNRESERVED_KEYWORD) + PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD) + PG_KEYWORD("referencing", REFERENCING, UNRESERVED_KEYWORD) + PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD) diff --git a/pg_query.h b/pg_query.h index a11991a3..49efac4b 100644 --- a/pg_query.h +++ b/pg_query.h @@ -106,9 +106,9 @@ void pg_query_free_fingerprint_result(PgQueryFingerprintResult result); void pg_query_exit(void); // Postgres version information -#define PG_VERSION "13.3" +#define PG_VERSION "13.8" #define PG_MAJORVERSION "13" -#define PG_VERSION_NUM 130003 +#define PG_VERSION_NUM 130008 // Deprecated APIs below diff --git a/protobuf/pg_query.pb-c.c b/protobuf/pg_query.pb-c.c index 4a10d08c..5f8a2194 100644 --- a/protobuf/pg_query.pb-c.c +++ b/protobuf/pg_query.pb-c.c @@ -20686,7 +20686,7 @@ const ProtobufCMessageDescriptor pg_query__alter_table_stmt__descriptor = (ProtobufCMessageInit) pg_query__alter_table_stmt__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor pg_query__alter_table_cmd__field_descriptors[7] = +static const ProtobufCFieldDescriptor pg_query__alter_table_cmd__field_descriptors[8] = { { "subtype", @@ -20772,6 +20772,18 @@ static const ProtobufCFieldDescriptor pg_query__alter_table_cmd__field_descripto 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, + { + "recurse", + 8, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BOOL, + 0, /* quantifier_offset */ + offsetof(PgQuery__AlterTableCmd, recurse), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned pg_query__alter_table_cmd__field_indices_by_name[] = { 5, /* field[5] = behavior */ @@ -20780,12 +20792,13 @@ static const unsigned pg_query__alter_table_cmd__field_indices_by_name[] = { 1, /* field[1] = name */ 3, /* field[3] = newowner */ 2, /* field[2] = num */ + 7, /* field[7] = recurse */ 0, /* field[0] = subtype */ }; static const ProtobufCIntRange pg_query__alter_table_cmd__number_ranges[1 + 1] = { { 1, 0 }, - { 0, 7 } + { 0, 8 } }; const ProtobufCMessageDescriptor pg_query__alter_table_cmd__descriptor = { @@ -20795,7 +20808,7 @@ const ProtobufCMessageDescriptor pg_query__alter_table_cmd__descriptor = "PgQuery__AlterTableCmd", "pg_query", sizeof(PgQuery__AlterTableCmd), - 7, + 8, pg_query__alter_table_cmd__field_descriptors, pg_query__alter_table_cmd__field_indices_by_name, 1, pg_query__alter_table_cmd__number_ranges, @@ -36975,7 +36988,7 @@ static const ProtobufCEnumValue pg_query__token__enum_values_by_number[494] = { "REASSIGN", "PG_QUERY__TOKEN__REASSIGN", 579 }, { "RECHECK", "PG_QUERY__TOKEN__RECHECK", 580 }, { "RECURSIVE", "PG_QUERY__TOKEN__RECURSIVE", 581 }, - { "REF", "PG_QUERY__TOKEN__REF", 582 }, + { "REF_P", "PG_QUERY__TOKEN__REF_P", 582 }, { "REFERENCES", "PG_QUERY__TOKEN__REFERENCES", 583 }, { "REFERENCING", "PG_QUERY__TOKEN__REFERENCING", 584 }, { "REFRESH", "PG_QUERY__TOKEN__REFRESH", 585 }, @@ -37472,10 +37485,10 @@ static const ProtobufCEnumValueIndex pg_query__token__enum_values_by_name[494] = { "REASSIGN", 341 }, { "RECHECK", 342 }, { "RECURSIVE", 343 }, - { "REF", 344 }, { "REFERENCES", 345 }, { "REFERENCING", 346 }, { "REFRESH", 347 }, + { "REF_P", 344 }, { "REINDEX", 348 }, { "RELATIVE_P", 349 }, { "RELEASE", 350 }, diff --git a/protobuf/pg_query.pb-c.h b/protobuf/pg_query.pb-c.h index 3b9b4b15..85e13479 100644 --- a/protobuf/pg_query.pb-c.h +++ b/protobuf/pg_query.pb-c.h @@ -10,7 +10,7 @@ PROTOBUF_C__BEGIN_DECLS #if PROTOBUF_C_VERSION_NUMBER < 1003000 # error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. -#elif 1004000 < PROTOBUF_C_MIN_COMPILER_VERSION +#elif 1004001 < PROTOBUF_C_MIN_COMPILER_VERSION # error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. #endif @@ -1268,7 +1268,7 @@ typedef enum _PgQuery__Token { PG_QUERY__TOKEN__REASSIGN = 579, PG_QUERY__TOKEN__RECHECK = 580, PG_QUERY__TOKEN__RECURSIVE = 581, - PG_QUERY__TOKEN__REF = 582, + PG_QUERY__TOKEN__REF_P = 582, PG_QUERY__TOKEN__REFERENCES = 583, PG_QUERY__TOKEN__REFERENCING = 584, PG_QUERY__TOKEN__REFRESH = 585, @@ -3047,10 +3047,11 @@ struct PgQuery__AlterTableCmd PgQuery__Node *def; PgQuery__DropBehavior behavior; protobuf_c_boolean missing_ok; + protobuf_c_boolean recurse; }; #define PG_QUERY__ALTER_TABLE_CMD__INIT \ { PROTOBUF_C_MESSAGE_INIT (&pg_query__alter_table_cmd__descriptor) \ - , PG_QUERY__ALTER_TABLE_TYPE__ALTER_TABLE_TYPE_UNDEFINED, (char *)protobuf_c_empty_string, 0, NULL, NULL, PG_QUERY__DROP_BEHAVIOR__DROP_BEHAVIOR_UNDEFINED, 0 } + , PG_QUERY__ALTER_TABLE_TYPE__ALTER_TABLE_TYPE_UNDEFINED, (char *)protobuf_c_empty_string, 0, NULL, NULL, PG_QUERY__DROP_BEHAVIOR__DROP_BEHAVIOR_UNDEFINED, 0, 0 } struct PgQuery__AlterDomainStmt diff --git a/protobuf/pg_query.proto b/protobuf/pg_query.proto index 2e73afa4..ddb40dab 100644 --- a/protobuf/pg_query.proto +++ b/protobuf/pg_query.proto @@ -945,6 +945,7 @@ message AlterTableCmd Node def = 5 [json_name="def"]; DropBehavior behavior = 6 [json_name="behavior"]; bool missing_ok = 7 [json_name="missing_ok"]; + bool recurse = 8 [json_name="recurse"]; } message AlterDomainStmt @@ -3341,7 +3342,7 @@ enum Token { REASSIGN = 579; RECHECK = 580; RECURSIVE = 581; - REF = 582; + REF_P = 582; REFERENCES = 583; REFERENCING = 584; REFRESH = 585; diff --git a/scripts/extract_source.rb b/scripts/extract_source.rb index 3d716bbb..43b923cc 100644 --- a/scripts/extract_source.rb +++ b/scripts/extract_source.rb @@ -113,6 +113,7 @@ def run @basepath + 'src/backend/jit/llvm/llvmjit_expr.c', # Requires LLVM-C library (which we don't want to require) @basepath + 'src/backend/jit/llvm/llvmjit_deform.c', # Requires LLVM-C library (which we don't want to require) @basepath + 'src/backend/jit/llvm/llvmjit.c', # Requires LLVM-C library (which we don't want to require) + @basepath + 'src/backend/libpq/be-gssapi-common.c', # Requires GSSAPI (which we don't want to require) @basepath + 'src/backend/libpq/be-secure-gssapi.c', # Requires GSSAPI (which we don't want to require) @basepath + 'src/common/protocol_openssl.c', # Requires OpenSSL (which we don't want to require) ] - @@ -211,7 +212,15 @@ def self.analysis_filename(filename, basepath) def analyze_file(file) index = FFI::Clang::Index.new(true, true) - translation_unit = index.parse_translation_unit(file, ['-I', @basepath + 'src/include', '-I', '/usr/local/opt/openssl/include', '-I', `xcrun --sdk macosx --show-sdk-path`.strip + '/usr/include', '-DDLSUFFIX=".bundle"', '-msse4.2', '-g', '-DUSE_ASSERT_CHECKING']) + translation_unit = index.parse_translation_unit(file, [ + '-I', @basepath + 'src/include', + '-I', '/usr/local/opt/openssl/include', + '-I', `xcrun --sdk macosx --show-sdk-path`.strip + '/usr/include', + '-DDLSUFFIX=".bundle"', + '-msse4.2', + '-g', + '-DUSE_ASSERT_CHECKING' + ]) cursor = translation_unit.cursor func_cursor = nil @@ -253,10 +262,15 @@ def analyze_file(file) analysis.file_to_symbol_positions[cursor.location.file][cursor.spelling] = [start_offset, end_offset] cursor.visit_children do |child_cursor, parent| + # There seems to be a bug here on modern Clang versions where the + # cursor kind gets modified once we call "child_cursor.definition" + # - thus we make a copy ahead of calling that, for later use + child_cursor_kind = child_cursor.kind + # Ignore variable definitions from the local scope next :recurse if child_cursor.definition.semantic_parent == cursor - if child_cursor.kind == :cursor_decl_ref_expr || child_cursor.kind == :cursor_call_expr + if child_cursor_kind == :cursor_decl_ref_expr || child_cursor_kind == :cursor_call_expr analysis.references[cursor.spelling] ||= [] (analysis.references[cursor.spelling] << child_cursor.spelling).uniq! end diff --git a/src/pg_query_fingerprint_defs.c b/src/pg_query_fingerprint_defs.c index 0f7c4c64..257b0bcb 100644 --- a/src/pg_query_fingerprint_defs.c +++ b/src/pg_query_fingerprint_defs.c @@ -4166,6 +4166,11 @@ _fingerprintAlterTableCmd(FingerprintContext *ctx, const AlterTableCmd *node, co _fingerprintString(ctx, buffer); } + if (node->recurse) { + _fingerprintString(ctx, "recurse"); + _fingerprintString(ctx, "true"); + } + if (true) { _fingerprintString(ctx, "subtype"); _fingerprintString(ctx, _enumToStringAlterTableType(node->subtype)); diff --git a/src/pg_query_outfuncs_defs.c b/src/pg_query_outfuncs_defs.c index 494a1128..f7000af6 100644 --- a/src/pg_query_outfuncs_defs.c +++ b/src/pg_query_outfuncs_defs.c @@ -897,6 +897,7 @@ _outAlterTableCmd(OUT_TYPE(AlterTableCmd, AlterTableCmd) out, const AlterTableCm WRITE_NODE_PTR_FIELD(def, def, def); WRITE_ENUM_FIELD(DropBehavior, behavior, behavior, behavior); WRITE_BOOL_FIELD(missing_ok, missing_ok, missing_ok); + WRITE_BOOL_FIELD(recurse, recurse, recurse); } static void diff --git a/src/pg_query_readfuncs_defs.c b/src/pg_query_readfuncs_defs.c index 5571dd6d..cc06747a 100644 --- a/src/pg_query_readfuncs_defs.c +++ b/src/pg_query_readfuncs_defs.c @@ -1014,6 +1014,7 @@ _readAlterTableCmd(OUT_TYPE(AlterTableCmd, AlterTableCmd) msg) READ_NODE_PTR_FIELD(def, def, def); READ_ENUM_FIELD(DropBehavior, behavior, behavior, behavior); READ_BOOL_FIELD(missing_ok, missing_ok, missing_ok); + READ_BOOL_FIELD(recurse, recurse, recurse); return node; } diff --git a/src/postgres/include/access/twophase.h b/src/postgres/include/access/twophase.h index 2ca71c34..9e2125f5 100644 --- a/src/postgres/include/access/twophase.h +++ b/src/postgres/include/access/twophase.h @@ -34,6 +34,8 @@ extern void TwoPhaseShmemInit(void); extern void AtAbort_Twophase(void); extern void PostPrepare_Twophase(void); +extern TransactionId TwoPhaseGetXidByVirtualXID(VirtualTransactionId vxid, + bool *have_more); extern PGPROC *TwoPhaseGetDummyProc(TransactionId xid, bool lock_held); extern BackendId TwoPhaseGetDummyBackendId(TransactionId xid, bool lock_held); diff --git a/src/postgres/include/access/xact.h b/src/postgres/include/access/xact.h index 3c66119d..f00fe4eb 100644 --- a/src/postgres/include/access/xact.h +++ b/src/postgres/include/access/xact.h @@ -103,6 +103,12 @@ extern int MyXactFlags; */ #define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK (1U << 1) +/* + * XACT_FLAGS_NEEDIMMEDIATECOMMIT - records whether the top level statement + * is one that requires immediate commit, such as CREATE DATABASE. + */ +#define XACT_FLAGS_NEEDIMMEDIATECOMMIT (1U << 2) + /* * start- and end-of-transaction callbacks for dynamically loaded modules */ diff --git a/src/postgres/include/access/xlog_internal.h b/src/postgres/include/access/xlog_internal.h index 88f3d767..51def851 100644 --- a/src/postgres/include/access/xlog_internal.h +++ b/src/postgres/include/access/xlog_internal.h @@ -79,8 +79,10 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader; #define XLP_LONG_HEADER 0x0002 /* This flag indicates backup blocks starting in this page are optional */ #define XLP_BKP_REMOVABLE 0x0004 +/* Replaces a missing contrecord; see CreateOverwriteContrecordRecord */ +#define XLP_FIRST_IS_OVERWRITE_CONTRECORD 0x0008 /* All defined flag bits in xlp_info (used for validity checking of header) */ -#define XLP_ALL_FLAGS 0x0007 +#define XLP_ALL_FLAGS 0x000F #define XLogPageHeaderSize(hdr) \ (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD) @@ -252,6 +254,13 @@ typedef struct xl_restore_point char rp_name[MAXFNAMELEN]; } xl_restore_point; +/* Overwrite of prior contrecord */ +typedef struct xl_overwrite_contrecord +{ + XLogRecPtr overwritten_lsn; + TimestampTz overwrite_time; +} xl_overwrite_contrecord; + /* End of recovery mark, when we don't do an END_OF_RECOVERY checkpoint */ typedef struct xl_end_of_recovery { diff --git a/src/postgres/include/access/xlogreader.h b/src/postgres/include/access/xlogreader.h index b0f2a6ed..89ed9de2 100644 --- a/src/postgres/include/access/xlogreader.h +++ b/src/postgres/include/access/xlogreader.h @@ -250,6 +250,16 @@ struct XLogReaderState /* Buffer to hold error message */ char *errormsg_buf; + + /* + * Set at the end of recovery: the start point of a partial record at the + * end of WAL (InvalidXLogRecPtr if there wasn't one), and the start + * location of its first contrecord that went missing. + */ + XLogRecPtr abortedRecPtr; + XLogRecPtr missingContrecPtr; + /* Set when XLP_FIRST_IS_OVERWRITE_CONTRECORD is found */ + XLogRecPtr overwrittenRecPtr; }; /* Get a new XLogReader */ diff --git a/src/postgres/include/catalog/dependency.h b/src/postgres/include/catalog/dependency.h index 7fe3fb7e..be235ed6 100644 --- a/src/postgres/include/catalog/dependency.h +++ b/src/postgres/include/catalog/dependency.h @@ -201,6 +201,8 @@ extern void recordMultipleDependencies(const ObjectAddress *depender, extern void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace); +extern void checkMembershipInCurrentExtension(const ObjectAddress *object); + extern long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps); diff --git a/src/postgres/include/catalog/pg_class.h b/src/postgres/include/catalog/pg_class.h index 78b33b2a..e675520f 100644 --- a/src/postgres/include/catalog/pg_class.h +++ b/src/postgres/include/catalog/pg_class.h @@ -178,7 +178,7 @@ typedef FormData_pg_class *Form_pg_class; /* * an explicitly chosen candidate key's columns are used as replica identity. * Note this will still be set if the index has been dropped; in that case it - * has the same meaning as 'd'. + * has the same meaning as 'n'. */ #define REPLICA_IDENTITY_INDEX 'i' diff --git a/src/postgres/include/catalog/pg_class_d.h b/src/postgres/include/catalog/pg_class_d.h index 7f9a66c8..557e209d 100644 --- a/src/postgres/include/catalog/pg_class_d.h +++ b/src/postgres/include/catalog/pg_class_d.h @@ -82,7 +82,7 @@ /* * an explicitly chosen candidate key's columns are used as replica identity. * Note this will still be set if the index has been dropped; in that case it - * has the same meaning as 'd'. + * has the same meaning as 'n'. */ #define REPLICA_IDENTITY_INDEX 'i' diff --git a/src/postgres/include/catalog/pg_control.h b/src/postgres/include/catalog/pg_control.h index de5670e5..92013301 100644 --- a/src/postgres/include/catalog/pg_control.h +++ b/src/postgres/include/catalog/pg_control.h @@ -76,6 +76,8 @@ typedef struct CheckPoint #define XLOG_END_OF_RECOVERY 0x90 #define XLOG_FPI_FOR_HINT 0xA0 #define XLOG_FPI 0xB0 +/* 0xC0 is used in Postgres 9.5-11 */ +#define XLOG_OVERWRITE_CONTRECORD 0xD0 /* diff --git a/src/postgres/include/catalog/pg_operator.h b/src/postgres/include/catalog/pg_operator.h index 1daa2638..5aaa02e8 100644 --- a/src/postgres/include/catalog/pg_operator.h +++ b/src/postgres/include/catalog/pg_operator.h @@ -95,7 +95,9 @@ extern ObjectAddress OperatorCreate(const char *operatorName, bool canMerge, bool canHash); -extern ObjectAddress makeOperatorDependencies(HeapTuple tuple, bool isUpdate); +extern ObjectAddress makeOperatorDependencies(HeapTuple tuple, + bool makeExtensionDep, + bool isUpdate); extern void OperatorUpd(Oid baseId, Oid commId, Oid negId, bool isDelete); diff --git a/src/postgres/include/catalog/pg_publication.h b/src/postgres/include/catalog/pg_publication.h index 5955ba0c..c876085a 100644 --- a/src/postgres/include/catalog/pg_publication.h +++ b/src/postgres/include/catalog/pg_publication.h @@ -107,6 +107,9 @@ extern List *GetAllTablesPublicationRelations(bool pubviaroot); extern bool is_publishable_relation(Relation rel); extern ObjectAddress publication_add_relation(Oid pubid, Relation targetrel, bool if_not_exists); +extern List *GetPubPartitionOptionRelations(List *result, + PublicationPartOpt pub_partopt, + Oid relid); extern Oid get_publication_oid(const char *pubname, bool missing_ok); extern char *get_publication_name(Oid pubid, bool missing_ok); diff --git a/src/postgres/include/catalog/pg_type.h b/src/postgres/include/catalog/pg_type.h index 7b375626..ebde49da 100644 --- a/src/postgres/include/catalog/pg_type.h +++ b/src/postgres/include/catalog/pg_type.h @@ -359,6 +359,7 @@ extern void GenerateTypeDependencies(HeapTuple typeTuple, * rowtypes */ bool isImplicitArray, bool isDependentType, + bool makeExtensionDep, bool rebuild); extern void RenameTypeInternal(Oid typeOid, const char *newTypeName, diff --git a/src/postgres/include/commands/async.h b/src/postgres/include/commands/async.h index 4c35394f..a54bebf2 100644 --- a/src/postgres/include/commands/async.h +++ b/src/postgres/include/commands/async.h @@ -49,6 +49,6 @@ extern void ProcessCompletedNotifies(void); extern void HandleNotifyInterrupt(void); /* process interrupts */ -extern void ProcessNotifyInterrupt(void); +extern void ProcessNotifyInterrupt(bool flush); #endif /* ASYNC_H */ diff --git a/src/postgres/include/commands/tablespace.h b/src/postgres/include/commands/tablespace.h index fd1b28fc..8d142c05 100644 --- a/src/postgres/include/commands/tablespace.h +++ b/src/postgres/include/commands/tablespace.h @@ -19,6 +19,8 @@ #include "lib/stringinfo.h" #include "nodes/parsenodes.h" +extern bool allow_in_place_tablespaces; + /* XLOG stuff */ #define XLOG_TBLSPC_CREATE 0x00 #define XLOG_TBLSPC_DROP 0x10 diff --git a/src/postgres/include/commands/trigger.h b/src/postgres/include/commands/trigger.h index a40ddf5d..b76d91af 100644 --- a/src/postgres/include/commands/trigger.h +++ b/src/postgres/include/commands/trigger.h @@ -162,12 +162,20 @@ extern ObjectAddress CreateTrigger(CreateTrigStmt *stmt, const char *queryString Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid, Oid funcoid, Oid parentTriggerOid, Node *whenClause, bool isInternal, bool in_partition); +extern ObjectAddress CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, + Oid relOid, Oid refRelOid, Oid constraintOid, + Oid indexOid, Oid funcoid, Oid parentTriggerOid, + Node *whenClause, bool isInternal, bool in_partition, + char trigger_fires_when); extern void RemoveTriggerById(Oid trigOid); extern Oid get_trigger_oid(Oid relid, const char *name, bool missing_ok); extern ObjectAddress renametrig(RenameStmt *stmt); +extern void EnableDisableTriggerNew(Relation rel, const char *tgname, + char fires_when, bool skip_system, bool recurse, + LOCKMODE lockmode); extern void EnableDisableTrigger(Relation rel, const char *tgname, char fires_when, bool skip_system, LOCKMODE lockmode); diff --git a/src/postgres/include/lib/simplehash.h b/src/postgres/include/lib/simplehash.h index 90dfa8a6..e70d5a37 100644 --- a/src/postgres/include/lib/simplehash.h +++ b/src/postgres/include/lib/simplehash.h @@ -55,6 +55,11 @@ * presence is relevant to determine whether a lookup needs to continue * looking or is done - buckets following a deleted element are shifted * backwards, unless they're empty or already at their optimal position. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/lib/simplehash.h */ #include "port/pg_bitutils.h" @@ -156,7 +161,7 @@ SH_SCOPE SH_TYPE *SH_CREATE(MemoryContext ctx, uint32 nelements, #endif SH_SCOPE void SH_DESTROY(SH_TYPE * tb); SH_SCOPE void SH_RESET(SH_TYPE * tb); -SH_SCOPE void SH_GROW(SH_TYPE * tb, uint32 newsize); +SH_SCOPE void SH_GROW(SH_TYPE * tb, uint64 newsize); SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT(SH_TYPE * tb, SH_KEY_TYPE key, bool *found); SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT_HASH(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash, bool *found); @@ -218,7 +223,8 @@ SH_SCOPE void SH_STAT(SH_TYPE * tb); #define SIMPLEHASH_H #ifdef FRONTEND -#define sh_error(...) pg_log_error(__VA_ARGS__) +#define sh_error(...) \ + do { pg_log_fatal(__VA_ARGS__); exit(1); } while(0) #define sh_log(...) pg_log_info(__VA_ARGS__) #else #define sh_error(...) elog(ERROR, __VA_ARGS__) @@ -232,7 +238,7 @@ SH_SCOPE void SH_STAT(SH_TYPE * tb); * the hashtable. */ static inline void -SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint32 newsize) +SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint64 newsize) { uint64 size; @@ -247,16 +253,12 @@ SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint32 newsize) * Verify that allocation of ->data is possible on this platform, without * overflowing Size. */ - if ((((uint64) sizeof(SH_ELEMENT_TYPE)) * size) >= SIZE_MAX / 2) + if (unlikely((((uint64) sizeof(SH_ELEMENT_TYPE)) * size) >= SIZE_MAX / 2)) sh_error("hash table too large"); /* now set size */ tb->size = size; - - if (tb->size == SH_MAX_SIZE) - tb->sizemask = 0; - else - tb->sizemask = tb->size - 1; + tb->sizemask = (uint32) (size - 1); /* * Compute the next threshold at which we need to grow the hash table @@ -406,7 +408,7 @@ SH_RESET(SH_TYPE * tb) * performance-wise, when known at some point. */ SH_SCOPE void -SH_GROW(SH_TYPE * tb, uint32 newsize) +SH_GROW(SH_TYPE * tb, uint64 newsize) { uint64 oldsize = tb->size; SH_ELEMENT_TYPE *olddata = tb->data; @@ -536,10 +538,8 @@ SH_INSERT_HASH_INTERNAL(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash, bool *found) */ if (unlikely(tb->members >= tb->grow_threshold)) { - if (tb->size == SH_MAX_SIZE) - { + if (unlikely(tb->size == SH_MAX_SIZE)) sh_error("hash table size exceeded"); - } /* * When optimizing, it can be very useful to print these out. diff --git a/src/postgres/include/libpq/libpq.h b/src/postgres/include/libpq/libpq.h index b1152475..54c5fa77 100644 --- a/src/postgres/include/libpq/libpq.h +++ b/src/postgres/include/libpq/libpq.h @@ -72,6 +72,7 @@ extern int pq_getmessage(StringInfo s, int maxlen); extern int pq_getbyte(void); extern int pq_peekbyte(void); extern int pq_getbyte_if_available(unsigned char *c); +extern bool pq_buffer_has_data(void); extern int pq_putbytes(const char *s, size_t len); /* diff --git a/src/postgres/include/mb/pg_wchar.h b/src/postgres/include/mb/pg_wchar.h index 494aefc7..b43454b6 100644 --- a/src/postgres/include/mb/pg_wchar.h +++ b/src/postgres/include/mb/pg_wchar.h @@ -553,6 +553,7 @@ extern int pg_valid_server_encoding_id(int encoding); * earlier in this file are also available from libpgcommon. */ extern int pg_encoding_mblen(int encoding, const char *mbstr); +extern int pg_encoding_mblen_bounded(int encoding, const char *mbstr); extern int pg_encoding_dsplen(int encoding, const char *mbstr); extern int pg_encoding_verifymb(int encoding, const char *mbstr, int len); extern int pg_encoding_max_length(int encoding); diff --git a/src/postgres/include/miscadmin.h b/src/postgres/include/miscadmin.h index a3697fc0..7f1bb340 100644 --- a/src/postgres/include/miscadmin.h +++ b/src/postgres/include/miscadmin.h @@ -57,6 +57,15 @@ * allowing die interrupts: HOLD_CANCEL_INTERRUPTS() and * RESUME_CANCEL_INTERRUPTS(). * + * Note that ProcessInterrupts() has also acquired a number of tasks that + * do not necessarily cause a query-cancel-or-die response. Hence, it's + * possible that it will just clear InterruptPending and return. + * + * INTERRUPTS_PENDING_CONDITION() can be checked to see whether an + * interrupt needs to be serviced, without trying to do so immediately. + * Some callers are also interested in INTERRUPTS_CAN_BE_PROCESSED(), + * which tells whether ProcessInterrupts is sure to clear the interrupt. + * * Special mechanisms are used to let an interrupt be accepted when we are * waiting for a lock or when we are waiting for command input (but, of * course, only if the interrupt holdoff counter is zero). See the @@ -94,24 +103,27 @@ extern PGDLLIMPORT __thread volatile uint32 CritSectionCount; /* in tcop/postgres.c */ extern void ProcessInterrupts(void); +/* Test whether an interrupt is pending */ #ifndef WIN32 +#define INTERRUPTS_PENDING_CONDITION() \ + (unlikely(InterruptPending)) +#else +#define INTERRUPTS_PENDING_CONDITION() \ + (unlikely(UNBLOCKED_SIGNAL_QUEUE()) ? pgwin32_dispatch_queued_signals() : 0, \ + unlikely(InterruptPending)) +#endif +/* Service interrupt, if one is pending and it's safe to service it now */ #define CHECK_FOR_INTERRUPTS() \ do { \ - if (unlikely(InterruptPending)) \ - ProcessInterrupts(); \ -} while(0) -#else /* WIN32 */ - -#define CHECK_FOR_INTERRUPTS() \ -do { \ - if (unlikely(UNBLOCKED_SIGNAL_QUEUE())) \ - pgwin32_dispatch_queued_signals(); \ - if (unlikely(InterruptPending)) \ + if (INTERRUPTS_PENDING_CONDITION()) \ ProcessInterrupts(); \ } while(0) -#endif /* WIN32 */ +/* Is ProcessInterrupts() guaranteed to clear InterruptPending? */ +#define INTERRUPTS_CAN_BE_PROCESSED() \ + (InterruptHoldoffCount == 0 && CritSectionCount == 0 && \ + QueryCancelHoldoffCount == 0) #define HOLD_INTERRUPTS() (InterruptHoldoffCount++) @@ -471,6 +483,7 @@ extern bool BackupInProgress(void); extern void CancelBackup(void); /* in executor/nodeHash.c */ +extern size_t get_hash_memory_limit(void); extern int get_hash_mem(void); #endif /* MISCADMIN_H */ diff --git a/src/postgres/include/nodes/execnodes.h b/src/postgres/include/nodes/execnodes.h index 3c6fecd2..a9a45f56 100644 --- a/src/postgres/include/nodes/execnodes.h +++ b/src/postgres/include/nodes/execnodes.h @@ -1454,7 +1454,7 @@ typedef struct IndexScanState /* ---------------- * IndexOnlyScanState information * - * indexqual execution state for indexqual expressions + * recheckqual execution state for recheckqual expressions * ScanKeys Skey structures for index quals * NumScanKeys number of ScanKeys * OrderByKeys Skey structures for index ordering operators @@ -1473,7 +1473,7 @@ typedef struct IndexScanState typedef struct IndexOnlyScanState { ScanState ss; /* its first field is NodeTag */ - ExprState *indexqual; + ExprState *recheckqual; struct ScanKeyData *ioss_ScanKeys; int ioss_NumScanKeys; struct ScanKeyData *ioss_OrderByKeys; diff --git a/src/postgres/include/nodes/parsenodes.h b/src/postgres/include/nodes/parsenodes.h index 557074c2..94384878 100644 --- a/src/postgres/include/nodes/parsenodes.h +++ b/src/postgres/include/nodes/parsenodes.h @@ -915,10 +915,10 @@ typedef struct PartitionCmd * inFromCl marks those range variables that are listed in the FROM clause. * It's false for RTEs that are added to a query behind the scenes, such * as the NEW and OLD variables for a rule, or the subqueries of a UNION. - * This flag is not used anymore during parsing, since the parser now uses - * a separate "namespace" data structure to control visibility, but it is - * needed by ruleutils.c to determine whether RTEs should be shown in - * decompiled queries. + * This flag is not used during parsing (except in transformLockingClause, + * q.v.); the parser now uses a separate "namespace" data structure to + * control visibility. But it is needed by ruleutils.c to determine + * whether RTEs should be shown in decompiled queries. * * requiredPerms and checkAsUser specify run-time access permissions * checks to be performed at query startup. The user must have *all* @@ -1876,6 +1876,7 @@ typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */ * constraint, or parent table */ DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */ bool missing_ok; /* skip error if missing? */ + bool recurse; /* exec-time recursion */ } AlterTableCmd; diff --git a/src/postgres/include/nodes/pathnodes.h b/src/postgres/include/nodes/pathnodes.h index 69150e46..5ebf0709 100644 --- a/src/postgres/include/nodes/pathnodes.h +++ b/src/postgres/include/nodes/pathnodes.h @@ -258,7 +258,8 @@ struct PlannerInfo List *init_plans; /* init SubPlans for query */ - List *cte_plan_ids; /* per-CTE-item list of subplan IDs */ + List *cte_plan_ids; /* per-CTE-item list of subplan IDs (or -1 if + * no subplan was made for that CTE) */ List *multiexpr_params; /* List of Lists of Params for MULTIEXPR * subquery outputs */ diff --git a/src/postgres/include/nodes/pg_list.h b/src/postgres/include/nodes/pg_list.h index 54447bb5..b3059681 100644 --- a/src/postgres/include/nodes/pg_list.h +++ b/src/postgres/include/nodes/pg_list.h @@ -560,6 +560,7 @@ extern List *list_delete_int(List *list, int datum); extern List *list_delete_oid(List *list, Oid datum); extern List *list_delete_first(List *list); extern List *list_delete_last(List *list); +extern List *list_delete_first_n(List *list, int n); extern List *list_delete_nth_cell(List *list, int n); extern List *list_delete_cell(List *list, ListCell *cell); diff --git a/src/postgres/include/nodes/plannodes.h b/src/postgres/include/nodes/plannodes.h index 83e01074..90f02ce6 100644 --- a/src/postgres/include/nodes/plannodes.h +++ b/src/postgres/include/nodes/plannodes.h @@ -418,14 +418,28 @@ typedef struct IndexScan * index-only scan, in which the data comes from the index not the heap. * Because of this, *all* Vars in the plan node's targetlist, qual, and * index expressions reference index columns and have varno = INDEX_VAR. - * Hence we do not need separate indexqualorig and indexorderbyorig lists, - * since their contents would be equivalent to indexqual and indexorderby. + * + * We could almost use indexqual directly against the index's output tuple + * when rechecking lossy index operators, but that won't work for quals on + * index columns that are not retrievable. Hence, recheckqual is needed + * for rechecks: it expresses the same condition as indexqual, but using + * only index columns that are retrievable. (We will not generate an + * index-only scan if this is not possible. An example is that if an + * index has table column "x" in a retrievable index column "ind1", plus + * an expression f(x) in a non-retrievable column "ind2", an indexable + * query on f(x) will use "ind2" in indexqual and f(ind1) in recheckqual. + * Without the "ind1" column, an index-only scan would be disallowed.) + * + * We don't currently need a recheckable equivalent of indexorderby, + * because we don't support lossy operators in index ORDER BY. * * To help EXPLAIN interpret the index Vars for display, we provide * indextlist, which represents the contents of the index as a targetlist * with one TLE per index column. Vars appearing in this list reference * the base table, and this is the only field in the plan node that may - * contain such Vars. + * contain such Vars. Also, for the convenience of setrefs.c, TLEs in + * indextlist are marked as resjunk if they correspond to columns that + * the index AM cannot reconstruct. * ---------------- */ typedef struct IndexOnlyScan @@ -436,6 +450,7 @@ typedef struct IndexOnlyScan List *indexorderby; /* list of index ORDER BY exprs */ List *indextlist; /* TargetEntry list describing index's cols */ ScanDirection indexorderdir; /* forward or backward or don't care */ + List *recheckqual; /* index quals in recheckable form */ } IndexOnlyScan; /* ---------------- diff --git a/src/postgres/include/optimizer/optimizer.h b/src/postgres/include/optimizer/optimizer.h index 3c588def..4729cd01 100644 --- a/src/postgres/include/optimizer/optimizer.h +++ b/src/postgres/include/optimizer/optimizer.h @@ -24,11 +24,6 @@ #include "nodes/parsenodes.h" -/* Test if an expression node represents a SRF call. Beware multiple eval! */ -#define IS_SRF_CALL(node) \ - ((IsA(node, FuncExpr) && ((FuncExpr *) (node))->funcretset) || \ - (IsA(node, OpExpr) && ((OpExpr *) (node))->opretset)) - /* * We don't want to include nodes/pathnodes.h here, because non-planner * code should generally treat PlannerInfo as an opaque typedef. diff --git a/src/postgres/include/parser/gram.h b/src/postgres/include/parser/gram.h index 7cae4f3b..243349f1 100644 --- a/src/postgres/include/parser/gram.h +++ b/src/postgres/include/parser/gram.h @@ -363,7 +363,7 @@ REASSIGN = 579, RECHECK = 580, RECURSIVE = 581, - REF = 582, + REF_P = 582, REFERENCES = 583, REFERENCING = 584, REFRESH = 585, @@ -840,7 +840,7 @@ #define REASSIGN 579 #define RECHECK 580 #define RECURSIVE 581 -#define REF 582 +#define REF_P 582 #define REFERENCES 583 #define REFERENCING 584 #define REFRESH 585 diff --git a/src/postgres/include/parser/kwlist.h b/src/postgres/include/parser/kwlist.h index 08f22ce2..4121a53b 100644 --- a/src/postgres/include/parser/kwlist.h +++ b/src/postgres/include/parser/kwlist.h @@ -330,7 +330,7 @@ PG_KEYWORD("real", REAL, COL_NAME_KEYWORD) PG_KEYWORD("reassign", REASSIGN, UNRESERVED_KEYWORD) PG_KEYWORD("recheck", RECHECK, UNRESERVED_KEYWORD) PG_KEYWORD("recursive", RECURSIVE, UNRESERVED_KEYWORD) -PG_KEYWORD("ref", REF, UNRESERVED_KEYWORD) +PG_KEYWORD("ref", REF_P, UNRESERVED_KEYWORD) PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD) PG_KEYWORD("referencing", REFERENCING, UNRESERVED_KEYWORD) PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD) diff --git a/src/postgres/include/parser/parse_coerce.h b/src/postgres/include/parser/parse_coerce.h index 8686eaac..9481d807 100644 --- a/src/postgres/include/parser/parse_coerce.h +++ b/src/postgres/include/parser/parse_coerce.h @@ -70,6 +70,7 @@ extern Oid select_common_type(ParseState *pstate, List *exprs, extern Node *coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *context); +extern bool verify_common_type(Oid common_type, List *exprs); extern bool check_generic_type_consistency(const Oid *actual_arg_types, const Oid *declared_arg_types, diff --git a/src/postgres/include/pg_config.h b/src/postgres/include/pg_config.h index 3456af53..7808cc8d 100644 --- a/src/postgres/include/pg_config.h +++ b/src/postgres/include/pg_config.h @@ -317,9 +317,6 @@ /* Define to 1 if you have the `ldap' library (-lldap). */ /* #undef HAVE_LIBLDAP */ -/* Define to 1 if you have the `ldap_r' library (-lldap_r). */ -/* #undef HAVE_LIBLDAP_R */ - /* Define to 1 if you have the `m' library (-lm). */ #define HAVE_LIBM 1 @@ -474,6 +471,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_SECURITY_PAM_APPL_H */ +/* Define to 1 if you have the `setenv' function. */ +#define HAVE_SETENV 1 + /* Define to 1 if you have the `setproctitle' function. */ /* #undef HAVE_SETPROCTITLE */ @@ -685,7 +685,7 @@ /* #undef HAVE_X509_GET_SIGNATURE_NID */ /* Define to 1 if the assembler supports X86_64's POPCNTQ instruction. */ -#define HAVE_X86_64_POPCNTQ 1 +/* #undef HAVE_X86_64_POPCNTQ */ /* Define to 1 if the system has the type `_Bool'. */ #define HAVE__BOOL 1 @@ -708,6 +708,9 @@ /* Define to 1 if your compiler understands __builtin_ctz. */ #define HAVE__BUILTIN_CTZ 1 +/* Define to 1 if your compiler understands __builtin_frame_address. */ +#define HAVE__BUILTIN_FRAME_ADDRESS 1 + /* Define to 1 if your compiler understands __builtin_$op_overflow. */ #define HAVE__BUILTIN_OP_OVERFLOW 1 @@ -727,7 +730,7 @@ /* #undef HAVE__CPUID */ /* Define to 1 if you have __get_cpuid. */ -#define HAVE__GET_CPUID 1 +/* #undef HAVE__GET_CPUID */ /* Define to 1 if your compiler understands _Static_assert. */ #define HAVE__STATIC_ASSERT 1 @@ -757,7 +760,7 @@ #define PACKAGE_NAME "PostgreSQL" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PostgreSQL 13.3" +#define PACKAGE_STRING "PostgreSQL 13.8" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "postgresql" @@ -766,7 +769,7 @@ #define PACKAGE_URL "https://www.postgresql.org/" /* Define to the version of this package. */ -#define PACKAGE_VERSION "13.3" +#define PACKAGE_VERSION "13.8" /* Define to the name of a signed 128-bit integer type. */ #define PG_INT128_TYPE __int128 @@ -785,7 +788,7 @@ #define PG_MAJORVERSION_NUM 13 /* PostgreSQL minor version number */ -#define PG_MINORVERSION_NUM 3 +#define PG_MINORVERSION_NUM 8 /* Define to best printf format archetype, usually gnu_printf if available. */ #define PG_PRINTF_ATTRIBUTE printf @@ -794,13 +797,13 @@ #define PG_USE_STDBOOL 1 /* PostgreSQL version as a string */ -#define PG_VERSION "13.3" +#define PG_VERSION "13.8" /* PostgreSQL version as a number */ -#define PG_VERSION_NUM 130003 +#define PG_VERSION_NUM 130008 /* A string containing the version number, platform, and C compiler */ -#define PG_VERSION_STR "PostgreSQL 13.3 on x86_64-apple-darwin19.6.0, compiled by Apple clang version 12.0.0 (clang-1200.0.32.29), 64-bit" +#define PG_VERSION_STR "PostgreSQL 13.8 on arm-apple-darwin21.6.0, compiled by Apple clang version 14.0.0 (clang-1400.0.29.202), 64-bit" /* Define to 1 to allow profiling output to be saved separately for each process. */ @@ -845,7 +848,7 @@ #define STRERROR_R_INT 1 /* Define to 1 to use ARMv8 CRC Extension. */ -/* #undef USE_ARMV8_CRC32C */ +#define USE_ARMV8_CRC32C 1 /* Define to 1 to use ARMv8 CRC Extension with a runtime check. */ /* #undef USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK */ @@ -897,7 +900,7 @@ /* #undef USE_SSE42_CRC32C */ /* Define to 1 to use Intel SSE 4.2 CRC instructions with a runtime check. */ -#define USE_SSE42_CRC32C_WITH_RUNTIME_CHECK 1 +/* #undef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK */ /* Define to build with systemd support. (--with-systemd) */ /* #undef USE_SYSTEMD */ diff --git a/src/postgres/include/pgstat.h b/src/postgres/include/pgstat.h index c55dc148..46fa42c2 100644 --- a/src/postgres/include/pgstat.h +++ b/src/postgres/include/pgstat.h @@ -902,7 +902,8 @@ typedef enum WAIT_EVENT_PG_SLEEP, WAIT_EVENT_RECOVERY_APPLY_DELAY, WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL, - WAIT_EVENT_VACUUM_DELAY + WAIT_EVENT_VACUUM_DELAY, + WAIT_EVENT_REGISTER_SYNC_REQUEST } WaitEventTimeout; /* ---------- diff --git a/src/postgres/include/plpgsql.h b/src/postgres/include/plpgsql.h index 81a0dca7..87593cdc 100644 --- a/src/postgres/include/plpgsql.h +++ b/src/postgres/include/plpgsql.h @@ -919,10 +919,10 @@ typedef struct PLpgSQL_stmt_execsql int lineno; unsigned int stmtid; PLpgSQL_expr *sqlstmt; - bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? Note: - * mod_stmt is set when we plan the query */ + bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? */ bool into; /* INTO supplied? */ bool strict; /* INTO STRICT flag */ + bool mod_stmt_set; /* is mod_stmt valid yet? */ PLpgSQL_variable *target; /* INTO target (record or row) */ } PLpgSQL_stmt_execsql; diff --git a/src/postgres/include/port.h b/src/postgres/include/port.h index 271ff0d0..d4c94a44 100644 --- a/src/postgres/include/port.h +++ b/src/postgres/include/port.h @@ -429,6 +429,10 @@ extern size_t strnlen(const char *str, size_t maxlen); extern long random(void); #endif +#ifndef HAVE_SETENV +extern int setenv(const char *name, const char *value, int overwrite); +#endif + #ifndef HAVE_UNSETENV extern void unsetenv(const char *name); #endif diff --git a/src/postgres/include/port/pg_bitutils.h b/src/postgres/include/port/pg_bitutils.h index 887e7829..77fe42c6 100644 --- a/src/postgres/include/port/pg_bitutils.h +++ b/src/postgres/include/port/pg_bitutils.h @@ -137,7 +137,7 @@ pg_rightmost_one_pos64(uint64 word) /* * pg_nextpower2_32 - * Returns the next highest power of 2 of 'num', or 'num', if it's + * Returns the next higher power of 2 above 'num', or 'num' if it's * already a power of 2. * * 'num' mustn't be 0 or be above PG_UINT32_MAX / 2 + 1. @@ -160,7 +160,7 @@ pg_nextpower2_32(uint32 num) /* * pg_nextpower2_64 - * Returns the next highest power of 2 of 'num', or 'num', if it's + * Returns the next higher power of 2 above 'num', or 'num' if it's * already a power of 2. * * 'num' mustn't be 0 or be above PG_UINT64_MAX / 2 + 1. @@ -181,6 +181,52 @@ pg_nextpower2_64(uint64 num) return ((uint64) 1) << (pg_leftmost_one_pos64(num) + 1); } +/* + * pg_nextpower2_size_t + * Returns the next higher power of 2 above 'num', for a size_t input. + */ +#if SIZEOF_SIZE_T == 4 +#define pg_nextpower2_size_t(num) pg_nextpower2_32(num) +#else +#define pg_nextpower2_size_t(num) pg_nextpower2_64(num) +#endif + +/* + * pg_prevpower2_32 + * Returns the next lower power of 2 below 'num', or 'num' if it's + * already a power of 2. + * + * 'num' mustn't be 0. + */ +static inline uint32 +pg_prevpower2_32(uint32 num) +{ + return ((uint32) 1) << pg_leftmost_one_pos32(num); +} + +/* + * pg_prevpower2_64 + * Returns the next lower power of 2 below 'num', or 'num' if it's + * already a power of 2. + * + * 'num' mustn't be 0. + */ +static inline uint64 +pg_prevpower2_64(uint64 num) +{ + return ((uint64) 1) << pg_leftmost_one_pos64(num); +} + +/* + * pg_prevpower2_size_t + * Returns the next lower power of 2 below 'num', for a size_t input. + */ +#if SIZEOF_SIZE_T == 4 +#define pg_prevpower2_size_t(num) pg_prevpower2_32(num) +#else +#define pg_prevpower2_size_t(num) pg_prevpower2_64(num) +#endif + /* * pg_ceil_log2_32 * Returns equivalent of ceil(log2(num)) diff --git a/src/postgres/include/replication/reorderbuffer.h b/src/postgres/include/replication/reorderbuffer.h index 019bd382..5347597e 100644 --- a/src/postgres/include/replication/reorderbuffer.h +++ b/src/postgres/include/replication/reorderbuffer.h @@ -46,10 +46,10 @@ typedef struct ReorderBufferTupleBuf * changes. Users of the decoding facilities will never see changes with * *_INTERNAL_* actions. * - * The INTERNAL_SPEC_INSERT and INTERNAL_SPEC_CONFIRM changes concern - * "speculative insertions", and their confirmation respectively. They're - * used by INSERT .. ON CONFLICT .. UPDATE. Users of logical decoding don't - * have to care about these. + * The INTERNAL_SPEC_INSERT and INTERNAL_SPEC_CONFIRM, and INTERNAL_SPEC_ABORT + * changes concern "speculative insertions", their confirmation, and abort + * respectively. They're used by INSERT .. ON CONFLICT .. UPDATE. Users of + * logical decoding don't have to care about these. */ enum ReorderBufferChangeType { @@ -62,7 +62,8 @@ enum ReorderBufferChangeType REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID, REORDER_BUFFER_CHANGE_INTERNAL_SPEC_INSERT, REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM, - REORDER_BUFFER_CHANGE_TRUNCATE + REORDER_BUFFER_CHANGE_TRUNCATE, + REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT }; /* forward declaration */ diff --git a/src/postgres/include/replication/slot.h b/src/postgres/include/replication/slot.h index 31362585..12c68ddb 100644 --- a/src/postgres/include/replication/slot.h +++ b/src/postgres/include/replication/slot.h @@ -209,7 +209,7 @@ extern void ReplicationSlotsComputeRequiredLSN(void); extern XLogRecPtr ReplicationSlotsComputeLogicalRestartLSN(void); extern bool ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive); extern void ReplicationSlotsDropDBSlots(Oid dboid); -extern void InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno); +extern bool InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno); extern void StartupReplicationSlots(void); extern void CheckPointReplicationSlots(void); diff --git a/src/postgres/include/storage/block.h b/src/postgres/include/storage/block.h index d73e3930..a87039bf 100644 --- a/src/postgres/include/storage/block.h +++ b/src/postgres/include/storage/block.h @@ -115,7 +115,7 @@ typedef BlockIdData *BlockId; /* block identifier */ #define BlockIdGetBlockNumber(blockId) \ ( \ AssertMacro(BlockIdIsValid(blockId)), \ - (BlockNumber) (((blockId)->bi_hi << 16) | ((uint16) (blockId)->bi_lo)) \ + ((((BlockNumber) (blockId)->bi_hi) << 16) | ((BlockNumber) (blockId)->bi_lo)) \ ) #endif /* BLOCK_H */ diff --git a/src/postgres/include/storage/lock.h b/src/postgres/include/storage/lock.h index 2987c5e4..ab42f6b0 100644 --- a/src/postgres/include/storage/lock.h +++ b/src/postgres/include/storage/lock.h @@ -46,10 +46,11 @@ extern bool Debug_deadlocks; /* * Top-level transactions are identified by VirtualTransactionIDs comprising - * PGPROC fields backendId and lxid. For prepared transactions, the - * LocalTransactionId is an ordinary XID. These are guaranteed unique over - * the short term, but will be reused after a database restart or XID - * wraparound; hence they should never be stored on disk. + * PGPROC fields backendId and lxid. For recovered prepared transactions, the + * LocalTransactionId is an ordinary XID; LOCKTAG_VIRTUALTRANSACTION never + * refers to that kind. These are guaranteed unique over the short term, but + * will be reused after a database restart or XID wraparound; hence they + * should never be stored on disk. * * Note that struct VirtualTransactionId can not be assumed to be atomically * assignable as a whole. However, type LocalTransactionId is assumed to @@ -69,7 +70,7 @@ typedef struct #define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId) #define VirtualTransactionIdIsValid(vxid) \ (LocalTransactionIdIsValid((vxid).localTransactionId)) -#define VirtualTransactionIdIsPreparedXact(vxid) \ +#define VirtualTransactionIdIsRecoveredPreparedXact(vxid) \ ((vxid).backendId == InvalidBackendId) #define VirtualTransactionIdEquals(vxid1, vxid2) \ ((vxid1).backendId == (vxid2).backendId && \ diff --git a/src/postgres/include/storage/lwlock.h b/src/postgres/include/storage/lwlock.h index c04ae971..cdbfbed1 100644 --- a/src/postgres/include/storage/lwlock.h +++ b/src/postgres/include/storage/lwlock.h @@ -149,6 +149,7 @@ extern void LWLockRelease(LWLock *lock); extern void LWLockReleaseClearVar(LWLock *lock, uint64 *valptr, uint64 val); extern void LWLockReleaseAll(void); extern bool LWLockHeldByMe(LWLock *lock); +extern bool LWLockAnyHeldByMe(LWLock *lock, int nlocks, size_t stride); extern bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode); extern bool LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval); diff --git a/src/postgres/include/storage/proc.h b/src/postgres/include/storage/proc.h index 1ee9000b..7c85b564 100644 --- a/src/postgres/include/storage/proc.h +++ b/src/postgres/include/storage/proc.h @@ -62,6 +62,12 @@ struct XidCache #define PROC_VACUUM_STATE_MASK \ (PROC_IN_VACUUM | PROC_IN_ANALYZE | PROC_VACUUM_FOR_WRAPAROUND) +/* + * Xmin-related flags. Make sure any flags that affect how the process' Xmin + * value is interpreted by VACUUM are included here. + */ +#define PROC_XMIN_FLAGS (PROC_IN_VACUUM) + /* * We allow a small number of "weak" relation locks (AccessShareLock, * RowShareLock, RowExclusiveLock) to be recorded in the PGPROC structure @@ -76,6 +82,13 @@ struct XidCache */ #define INVALID_PGPROCNO PG_INT32_MAX +/* + * Flags used only for type of internal functions + * GetVirtualXIDsDelayingChkptGuts and HaveVirtualXIDsDelayingChkptGuts. + */ +#define DELAY_CHKPT_START (1<<0) +#define DELAY_CHKPT_COMPLETE (1<<1) + /* * Each backend has a PGPROC struct in shared memory. There is also a list of * currently-unused PGPROC structs that will be reallocated to new backends. @@ -143,6 +156,7 @@ struct PGPROC * lock object by this backend */ bool delayChkpt; /* true if this proc delays checkpoint start */ + bool delayChkptEnd; /* true if this proc delays checkpoint end */ /* * Info to allow us to wait for synchronous replication, if needed. diff --git a/src/postgres/include/storage/s_lock.h b/src/postgres/include/storage/s_lock.h index 31a5ca6f..6b368a5a 100644 --- a/src/postgres/include/storage/s_lock.h +++ b/src/postgres/include/storage/s_lock.h @@ -314,6 +314,7 @@ tas(volatile slock_t *lock) #endif /* __INTEL_COMPILER */ #endif /* __ia64__ || __ia64 */ + /* * On ARM and ARM64, we use __sync_lock_test_and_set(int *, int) if available. * @@ -340,6 +341,29 @@ tas(volatile slock_t *lock) #endif /* __arm__ || __arm || __aarch64__ || __aarch64 */ +/* + * RISC-V likewise uses __sync_lock_test_and_set(int *, int) if available. + */ +#if defined(__riscv) +#ifdef HAVE_GCC__SYNC_INT32_TAS +#define HAS_TEST_AND_SET + +#define TAS(lock) tas(lock) + +typedef int slock_t; + +static __inline__ int +tas(volatile slock_t *lock) +{ + return __sync_lock_test_and_set(lock, 1); +} + +#define S_UNLOCK(lock) __sync_lock_release(lock) + +#endif /* HAVE_GCC__SYNC_INT32_TAS */ +#endif /* __riscv */ + + /* S/390 and S/390x Linux (32- and 64-bit zSeries) */ #if defined(__s390__) || defined(__s390x__) #define HAS_TEST_AND_SET diff --git a/src/postgres/include/tcop/pquery.h b/src/postgres/include/tcop/pquery.h index 437642cc..1385a007 100644 --- a/src/postgres/include/tcop/pquery.h +++ b/src/postgres/include/tcop/pquery.h @@ -17,6 +17,8 @@ #include "nodes/parsenodes.h" #include "utils/portal.h" +struct PlannedStmt; /* avoid including plannodes.h here */ + extern PGDLLIMPORT Portal ActivePortal; @@ -42,4 +44,8 @@ extern uint64 PortalRunFetch(Portal portal, long count, DestReceiver *dest); +extern bool PlannedStmtRequiresSnapshot(struct PlannedStmt *pstmt); + +extern void EnsurePortalSnapshotExists(void); + #endif /* PQUERY_H */ diff --git a/src/postgres/include/utils/builtins.h b/src/postgres/include/utils/builtins.h index 9519a3fa..8d7248dc 100644 --- a/src/postgres/include/utils/builtins.h +++ b/src/postgres/include/utils/builtins.h @@ -89,6 +89,7 @@ extern void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len); /* xid.c */ extern int xidComparator(const void *arg1, const void *arg2); +extern int xidLogicalComparator(const void *arg1, const void *arg2); /* inet_cidr_ntop.c */ extern char *pg_inet_cidr_ntop(int af, const void *src, int bits, diff --git a/src/postgres/include/utils/inval.h b/src/postgres/include/utils/inval.h index bc5081cf..4c6b86c9 100644 --- a/src/postgres/include/utils/inval.h +++ b/src/postgres/include/utils/inval.h @@ -61,4 +61,5 @@ extern void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func, extern void CallSyscacheCallbacks(int cacheid, uint32 hashvalue); extern void InvalidateSystemCaches(void); +extern void InvalidateSystemCachesExtended(bool debug_discard); #endif /* INVAL_H */ diff --git a/src/postgres/include/utils/portal.h b/src/postgres/include/utils/portal.h index d41ff2ef..af0afcf9 100644 --- a/src/postgres/include/utils/portal.h +++ b/src/postgres/include/utils/portal.h @@ -194,6 +194,17 @@ typedef struct PortalData /* Presentation data, primarily used by the pg_cursors system view */ TimestampTz creation_time; /* time at which this portal was defined */ bool visible; /* include this portal in pg_cursors? */ + + /* Stuff added at the end to avoid ABI break in stable branches: */ + + /* + * Outermost ActiveSnapshot for execution of the portal's queries. For + * all but a few utility commands, we require such a snapshot to exist. + * This ensures that TOAST references in query results can be detoasted, + * and helps to reduce thrashing of the process's exposed xmin. + */ + Snapshot portalSnapshot; /* active snapshot, or NULL if none */ + int createLevel; /* creating subxact's nesting level */ } PortalData; /* @@ -211,6 +222,7 @@ extern void AtCleanup_Portals(void); extern void PortalErrorCleanup(void); extern void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, + int parentLevel, ResourceOwner parentXactOwner); extern void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, @@ -237,5 +249,6 @@ extern void PortalCreateHoldStore(Portal portal); extern void PortalHashTableDeleteAll(void); extern bool ThereAreNoReadyPortals(void); extern void HoldPinnedPortals(void); +extern void ForgetPortalSnapshots(void); #endif /* PORTAL_H */ diff --git a/src/postgres/include/utils/rel.h b/src/postgres/include/utils/rel.h index 0b5957ba..b7c10864 100644 --- a/src/postgres/include/utils/rel.h +++ b/src/postgres/include/utils/rel.h @@ -298,7 +298,6 @@ typedef struct StdRdOptions { int32 vl_len_; /* varlena header (do not touch directly!) */ int fillfactor; /* page fill factor in percent (0..100) */ - /* fraction of newly inserted tuples prior to trigger index cleanup */ int toast_tuple_target; /* target for tuple toasting */ AutoVacOpts autovacuum; /* autovacuum-related options */ bool user_catalog_table; /* use as an additional catalog relation */ diff --git a/src/postgres/include/utils/relcache.h b/src/postgres/include/utils/relcache.h index 9a85b7dd..ff478c3b 100644 --- a/src/postgres/include/utils/relcache.h +++ b/src/postgres/include/utils/relcache.h @@ -14,7 +14,6 @@ #ifndef RELCACHE_H #define RELCACHE_H -#include "postgres.h" #include "access/tupdesc.h" #include "nodes/bitmapset.h" @@ -121,7 +120,7 @@ extern void RelationForgetRelation(Oid rid); extern void RelationCacheInvalidateEntry(Oid relationId); -extern void RelationCacheInvalidate(void); +extern void RelationCacheInvalidate(bool debug_discard); extern void RelationCloseSmgrByOid(Oid relationId); diff --git a/src/postgres/include/utils/snapmgr.h b/src/postgres/include/utils/snapmgr.h index ad7c15dc..651ff609 100644 --- a/src/postgres/include/utils/snapmgr.h +++ b/src/postgres/include/utils/snapmgr.h @@ -110,6 +110,7 @@ extern void InvalidateCatalogSnapshot(void); extern void InvalidateCatalogSnapshotConditionally(void); extern void PushActiveSnapshot(Snapshot snapshot); +extern void PushActiveSnapshotWithLevel(Snapshot snapshot, int snap_level); extern void PushCopiedSnapshot(Snapshot snapshot); extern void UpdateActiveSnapshotCommandId(void); extern void PopActiveSnapshot(void); diff --git a/src/postgres/src_backend_catalog_namespace.c b/src/postgres/src_backend_catalog_namespace.c index 2841ebf7..9c0f722c 100644 --- a/src/postgres/src_backend_catalog_namespace.c +++ b/src/postgres/src_backend_catalog_namespace.c @@ -62,6 +62,7 @@ #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" +#include "utils/snapmgr.h" #include "utils/syscache.h" #include "utils/varlena.h" diff --git a/src/postgres/src_backend_libpq_pqcomm.c b/src/postgres/src_backend_libpq_pqcomm.c index 504bdf96..5be9b386 100644 --- a/src/postgres/src_backend_libpq_pqcomm.c +++ b/src/postgres/src_backend_libpq_pqcomm.c @@ -404,6 +404,14 @@ const PQcommMethods *PqCommMethods = NULL; */ +/* -------------------------------- + * pq_buffer_has_data - is any buffered data available to read? + * + * This will *not* attempt to read more data. + * -------------------------------- + */ + + /* -------------------------------- * pq_startmsgread - begin reading a message from the client. diff --git a/src/postgres/src_backend_nodes_copyfuncs.c b/src/postgres/src_backend_nodes_copyfuncs.c index 2a840848..7bad04f5 100644 --- a/src/postgres/src_backend_nodes_copyfuncs.c +++ b/src/postgres/src_backend_nodes_copyfuncs.c @@ -345,8 +345,11 @@ #define COPY_POINTER_FIELD(fldname, sz) \ do { \ Size _size = (sz); \ - newnode->fldname = palloc(_size); \ - memcpy(newnode->fldname, from->fldname, _size); \ + if (_size > 0) \ + { \ + newnode->fldname = palloc(_size); \ + memcpy(newnode->fldname, from->fldname, _size); \ + } \ } while (0) /* Copy a parse location field (for Copy, this is same as scalar case) */ @@ -584,12 +587,9 @@ _copyRecursiveUnion(const RecursiveUnion *from) */ COPY_SCALAR_FIELD(wtParam); COPY_SCALAR_FIELD(numCols); - if (from->numCols > 0) - { - COPY_POINTER_FIELD(dupColIdx, from->numCols * sizeof(AttrNumber)); - COPY_POINTER_FIELD(dupOperators, from->numCols * sizeof(Oid)); - COPY_POINTER_FIELD(dupCollations, from->numCols * sizeof(Oid)); - } + COPY_POINTER_FIELD(dupColIdx, from->numCols * sizeof(AttrNumber)); + COPY_POINTER_FIELD(dupOperators, from->numCols * sizeof(Oid)); + COPY_POINTER_FIELD(dupCollations, from->numCols * sizeof(Oid)); COPY_SCALAR_FIELD(numGroups); return newnode; @@ -803,6 +803,7 @@ _copyIndexOnlyScan(const IndexOnlyScan *from) */ COPY_SCALAR_FIELD(indexid); COPY_NODE_FIELD(indexqual); + COPY_NODE_FIELD(recheckqual); COPY_NODE_FIELD(indexorderby); COPY_NODE_FIELD(indextlist); COPY_SCALAR_FIELD(indexorderdir); @@ -1162,13 +1163,10 @@ _copyMergeJoin(const MergeJoin *from) COPY_SCALAR_FIELD(skip_mark_restore); COPY_NODE_FIELD(mergeclauses); numCols = list_length(from->mergeclauses); - if (numCols > 0) - { - COPY_POINTER_FIELD(mergeFamilies, numCols * sizeof(Oid)); - COPY_POINTER_FIELD(mergeCollations, numCols * sizeof(Oid)); - COPY_POINTER_FIELD(mergeStrategies, numCols * sizeof(int)); - COPY_POINTER_FIELD(mergeNullsFirst, numCols * sizeof(bool)); - } + COPY_POINTER_FIELD(mergeFamilies, numCols * sizeof(Oid)); + COPY_POINTER_FIELD(mergeCollations, numCols * sizeof(Oid)); + COPY_POINTER_FIELD(mergeStrategies, numCols * sizeof(int)); + COPY_POINTER_FIELD(mergeNullsFirst, numCols * sizeof(bool)); return newnode; } @@ -1303,12 +1301,9 @@ _copyAgg(const Agg *from) COPY_SCALAR_FIELD(aggstrategy); COPY_SCALAR_FIELD(aggsplit); COPY_SCALAR_FIELD(numCols); - if (from->numCols > 0) - { - COPY_POINTER_FIELD(grpColIdx, from->numCols * sizeof(AttrNumber)); - COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid)); - COPY_POINTER_FIELD(grpCollations, from->numCols * sizeof(Oid)); - } + COPY_POINTER_FIELD(grpColIdx, from->numCols * sizeof(AttrNumber)); + COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid)); + COPY_POINTER_FIELD(grpCollations, from->numCols * sizeof(Oid)); COPY_SCALAR_FIELD(numGroups); COPY_SCALAR_FIELD(transitionSpace); COPY_BITMAPSET_FIELD(aggParams); @@ -1330,19 +1325,13 @@ _copyWindowAgg(const WindowAgg *from) COPY_SCALAR_FIELD(winref); COPY_SCALAR_FIELD(partNumCols); - if (from->partNumCols > 0) - { - COPY_POINTER_FIELD(partColIdx, from->partNumCols * sizeof(AttrNumber)); - COPY_POINTER_FIELD(partOperators, from->partNumCols * sizeof(Oid)); - COPY_POINTER_FIELD(partCollations, from->partNumCols * sizeof(Oid)); - } + COPY_POINTER_FIELD(partColIdx, from->partNumCols * sizeof(AttrNumber)); + COPY_POINTER_FIELD(partOperators, from->partNumCols * sizeof(Oid)); + COPY_POINTER_FIELD(partCollations, from->partNumCols * sizeof(Oid)); COPY_SCALAR_FIELD(ordNumCols); - if (from->ordNumCols > 0) - { - COPY_POINTER_FIELD(ordColIdx, from->ordNumCols * sizeof(AttrNumber)); - COPY_POINTER_FIELD(ordOperators, from->ordNumCols * sizeof(Oid)); - COPY_POINTER_FIELD(ordCollations, from->ordNumCols * sizeof(Oid)); - } + COPY_POINTER_FIELD(ordColIdx, from->ordNumCols * sizeof(AttrNumber)); + COPY_POINTER_FIELD(ordOperators, from->ordNumCols * sizeof(Oid)); + COPY_POINTER_FIELD(ordCollations, from->ordNumCols * sizeof(Oid)); COPY_SCALAR_FIELD(frameOptions); COPY_NODE_FIELD(startOffset); COPY_NODE_FIELD(endOffset); @@ -3510,6 +3499,7 @@ _copyAlterTableCmd(const AlterTableCmd *from) COPY_NODE_FIELD(def); COPY_SCALAR_FIELD(behavior); COPY_SCALAR_FIELD(missing_ok); + COPY_SCALAR_FIELD(recurse); return newnode; } diff --git a/src/postgres/src_backend_nodes_equalfuncs.c b/src/postgres/src_backend_nodes_equalfuncs.c index 504ce290..c55de26c 100644 --- a/src/postgres/src_backend_nodes_equalfuncs.c +++ b/src/postgres/src_backend_nodes_equalfuncs.c @@ -1335,6 +1335,7 @@ _equalAlterTableCmd(const AlterTableCmd *a, const AlterTableCmd *b) COMPARE_NODE_FIELD(def); COMPARE_SCALAR_FIELD(behavior); COMPARE_SCALAR_FIELD(missing_ok); + COMPARE_SCALAR_FIELD(recurse); return true; } diff --git a/src/postgres/src_backend_nodes_list.c b/src/postgres/src_backend_nodes_list.c index e787561b..6943c8fb 100644 --- a/src/postgres/src_backend_nodes_list.c +++ b/src/postgres/src_backend_nodes_list.c @@ -642,6 +642,18 @@ list_delete_cell(List *list, ListCell *cell) */ +/* + * Delete the first N cells of the list. + * + * The List is pfree'd if the request causes all cells to be deleted. + */ +#ifndef DEBUG_LIST_MEMORY_USAGE +#else +#ifdef CLOBBER_FREED_MEMORY +#else +#endif +#endif + /* * Generate the union of two lists. This is calculated by copying * list1 via list_copy(), then adding to it all the members of list2 diff --git a/src/postgres/src_backend_parser_gram.c b/src/postgres/src_backend_parser_gram.c index 0b60f0ec..230204af 100644 --- a/src/postgres/src_backend_parser_gram.c +++ b/src/postgres/src_backend_parser_gram.c @@ -457,7 +457,7 @@ REASSIGN = 579, RECHECK = 580, RECURSIVE = 581, - REF = 582, + REF_P = 582, REFERENCES = 583, REFERENCING = 584, REFRESH = 585, @@ -934,7 +934,7 @@ #define REASSIGN 579 #define RECHECK 580 #define RECURSIVE 581 -#define REF 582 +#define REF_P 582 #define REFERENCES 583 #define REFERENCING 584 #define REFRESH 585 @@ -3354,7 +3354,7 @@ static const char *const yytname[] = "PRESERVE", "PREPARE", "PREPARED", "PRIMARY", "PRIOR", "PRIVILEGES", "PROCEDURAL", "PROCEDURE", "PROCEDURES", "PROGRAM", "PUBLICATION", "QUOTE", "RANGE", "READ", "REAL", "REASSIGN", "RECHECK", "RECURSIVE", - "REF", "REFERENCES", "REFERENCING", "REFRESH", "REINDEX", "RELATIVE_P", + "REF_P", "REFERENCES", "REFERENCING", "REFRESH", "REINDEX", "RELATIVE_P", "RELEASE", "RENAME", "REPEATABLE", "REPLACE", "REPLICA", "RESET", "RESTART", "RESTRICT", "RETURNING", "RETURNS", "REVOKE", "RIGHT", "ROLE", "ROLLBACK", "ROLLUP", "ROUTINE", "ROUTINES", "ROW", "ROWS", "RULE", @@ -46994,6 +46994,21 @@ insertSelectOptions(SelectStmt *stmt, ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("WITH TIES cannot be specified without ORDER BY clause"))); + if (limitClause->limitOption == LIMIT_OPTION_WITH_TIES && stmt->lockingClause) + { + ListCell *lc; + + foreach(lc, stmt->lockingClause) + { + LockingClause *lock = lfirst_node(LockingClause, lc); + + if (lock->waitPolicy == LockWaitSkip) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("%s and %s options cannot be used together", + "SKIP LOCKED", "WITH TIES"))); + } + } stmt->limitOption = limitClause->limitOption; } if (withClause) diff --git a/src/postgres/src_backend_parser_scan.c b/src/postgres/src_backend_parser_scan.c index 9eea0c44..33ea1fdb 100644 --- a/src/postgres/src_backend_parser_scan.c +++ b/src/postgres/src_backend_parser_scan.c @@ -43,8 +43,7 @@ *-------------------------------------------------------------------- */ -#line 2 "scan.c" -#line 2 "scan.l" +#line 1 "scan.c" /*------------------------------------------------------------------------- * * scan.l @@ -87,9 +86,7 @@ #include "parser/scansup.h" #include "mb/pg_wchar.h" - - -#line 48 "scan.c" +#line 44 "scan.c" #define YY_INT_ALIGNED short int @@ -97,12 +94,246 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif +#ifdef yy_create_buffer +#define core_yy_create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer core_yy_create_buffer +#endif + +#ifdef yy_delete_buffer +#define core_yy_delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer core_yy_delete_buffer +#endif + +#ifdef yy_scan_buffer +#define core_yy_scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer core_yy_scan_buffer +#endif + +#ifdef yy_scan_string +#define core_yy_scan_string_ALREADY_DEFINED +#else +#define yy_scan_string core_yy_scan_string +#endif + +#ifdef yy_scan_bytes +#define core_yy_scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes core_yy_scan_bytes +#endif + +#ifdef yy_init_buffer +#define core_yy_init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer core_yy_init_buffer +#endif + +#ifdef yy_flush_buffer +#define core_yy_flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer core_yy_flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define core_yy_load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state core_yy_load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define core_yy_switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer core_yy_switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define core_yypush_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state core_yypush_buffer_state +#endif + +#ifdef yypop_buffer_state +#define core_yypop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state core_yypop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define core_yyensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack core_yyensure_buffer_stack +#endif + +#ifdef yylex +#define core_yylex_ALREADY_DEFINED +#else +#define yylex core_yylex +#endif + +#ifdef yyrestart +#define core_yyrestart_ALREADY_DEFINED +#else +#define yyrestart core_yyrestart +#endif + +#ifdef yylex_init +#define core_yylex_init_ALREADY_DEFINED +#else +#define yylex_init core_yylex_init +#endif + +#ifdef yylex_init_extra +#define core_yylex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra core_yylex_init_extra +#endif + +#ifdef yylex_destroy +#define core_yylex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy core_yylex_destroy +#endif + +#ifdef yyget_debug +#define core_yyget_debug_ALREADY_DEFINED +#else +#define yyget_debug core_yyget_debug +#endif + +#ifdef yyset_debug +#define core_yyset_debug_ALREADY_DEFINED +#else +#define yyset_debug core_yyset_debug +#endif + +#ifdef yyget_extra +#define core_yyget_extra_ALREADY_DEFINED +#else +#define yyget_extra core_yyget_extra +#endif + +#ifdef yyset_extra +#define core_yyset_extra_ALREADY_DEFINED +#else +#define yyset_extra core_yyset_extra +#endif + +#ifdef yyget_in +#define core_yyget_in_ALREADY_DEFINED +#else +#define yyget_in core_yyget_in +#endif + +#ifdef yyset_in +#define core_yyset_in_ALREADY_DEFINED +#else +#define yyset_in core_yyset_in +#endif + +#ifdef yyget_out +#define core_yyget_out_ALREADY_DEFINED +#else +#define yyget_out core_yyget_out +#endif + +#ifdef yyset_out +#define core_yyset_out_ALREADY_DEFINED +#else +#define yyset_out core_yyset_out +#endif + +#ifdef yyget_leng +#define core_yyget_leng_ALREADY_DEFINED +#else +#define yyget_leng core_yyget_leng +#endif + +#ifdef yyget_text +#define core_yyget_text_ALREADY_DEFINED +#else +#define yyget_text core_yyget_text +#endif + +#ifdef yyget_lineno +#define core_yyget_lineno_ALREADY_DEFINED +#else +#define yyget_lineno core_yyget_lineno +#endif + +#ifdef yyset_lineno +#define core_yyset_lineno_ALREADY_DEFINED +#else +#define yyset_lineno core_yyset_lineno +#endif + +#ifdef yyget_column +#define core_yyget_column_ALREADY_DEFINED +#else +#define yyget_column core_yyget_column +#endif + +#ifdef yyset_column +#define core_yyset_column_ALREADY_DEFINED +#else +#define yyset_column core_yyset_column +#endif + +#ifdef yywrap +#define core_yywrap_ALREADY_DEFINED +#else +#define yywrap core_yywrap +#endif + +#ifdef yyget_lval +#define core_yyget_lval_ALREADY_DEFINED +#else +#define yyget_lval core_yyget_lval +#endif + +#ifdef yyset_lval +#define core_yyset_lval_ALREADY_DEFINED +#else +#define yyset_lval core_yyset_lval +#endif + +#ifdef yyget_lloc +#define core_yyget_lloc_ALREADY_DEFINED +#else +#define yyget_lloc core_yyget_lloc +#endif + +#ifdef yyset_lloc +#define core_yyset_lloc_ALREADY_DEFINED +#else +#define yyset_lloc core_yyset_lloc +#endif + +#ifdef yyalloc +#define core_yyalloc_ALREADY_DEFINED +#else +#define yyalloc core_yyalloc +#endif + +#ifdef yyrealloc +#define core_yyrealloc_ALREADY_DEFINED +#else +#define yyrealloc core_yyrealloc +#endif + +#ifdef yyfree +#define core_yyfree_ALREADY_DEFINED +#else +#define yyfree core_yyfree +#endif + /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ @@ -144,7 +375,6 @@ typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -175,38 +405,32 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) +#endif /* ! C99 */ -#define YY_USE_CONST +#endif /* ! FLEXINT_H */ -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ +/* begin standard C++ headers. */ -#ifdef YY_USE_CONST +/* TODO: this is always defined, so inline it */ #define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) #else -#define yyconst +#define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -230,25 +454,29 @@ typedef void* yyscan_t; * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * - /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START - /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - /* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE core_yyrestart(yyin ,yyscanner ) - +#define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else #define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. @@ -268,8 +496,9 @@ typedef size_t yy_size_t; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 - + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ @@ -284,7 +513,6 @@ typedef size_t yy_size_t; YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) - #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE @@ -299,7 +527,7 @@ struct yy_buffer_state /* Size of input buffer in bytes, not including room for EOB * characters. */ - yy_size_t yy_buf_size; + int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. @@ -327,7 +555,7 @@ struct yy_buffer_state int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ - + /* Whether to try to fill the input buffer when we reach the * end of it. */ @@ -344,7 +572,7 @@ struct yy_buffer_state * possible backing-up. * * When we actually see the EOF, we change the status to "new" - * (via core_yyrestart()), so that the user can continue scanning by + * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 @@ -361,73 +589,67 @@ struct yy_buffer_state #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) - /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] -void core_yyrestart (FILE *input_file ,yyscan_t yyscanner ); -void core_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE core_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void core_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void core_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void core_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void core_yypop_buffer_state (yyscan_t yyscanner ); +void yyrestart ( FILE *input_file , yyscan_t yyscanner ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); +void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); +void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); +void yypop_buffer_state ( yyscan_t yyscanner ); -static void core_yyensure_buffer_stack (yyscan_t yyscanner ); -static void core_yy_load_buffer_state (yyscan_t yyscanner ); -static void core_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); +static void yyensure_buffer_stack ( yyscan_t yyscanner ); +static void yy_load_buffer_state ( yyscan_t yyscanner ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) -#define YY_FLUSH_BUFFER core_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, yy_size_t len , yyscan_t yyscanner ); -YY_BUFFER_STATE core_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE core_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE core_yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); - -void *core_yyalloc (yy_size_t ,yyscan_t yyscanner ); -void *core_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void core_yyfree (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer core_yy_create_buffer +void *yyalloc ( yy_size_t , yyscan_t yyscanner ); +void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); +void yyfree ( void * , yyscan_t yyscanner ); +#define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ - core_yyensure_buffer_stack (yyscanner); \ + yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ - core_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } - #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ - core_yyensure_buffer_stack (yyscanner); \ + yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ - core_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } - #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ -#define core_yywrap(n) 1 +#define core_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP +typedef flex_uint8_t YY_CHAR; -typedef unsigned char YY_CHAR; - -typedef yyconst struct yy_trans_info *yy_state_type; +typedef const struct yy_trans_info *yy_state_type; #define yytext_ptr yytext_r -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); +static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); +static int yy_get_next_buffer ( yyscan_t yyscanner ); +static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. @@ -438,7 +660,6 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; - #define YY_NUM_RULES 66 #define YY_END_OF_BUFFER 67 struct yy_trans_info @@ -446,7 +667,7 @@ struct yy_trans_info flex_int16_t yy_verify; flex_int16_t yy_nxt; }; -static yyconst struct yy_trans_info yy_transition[17678] = +static const struct yy_trans_info yy_transition[17678] = { { 0, 0 }, { 0,17422 }, { 0, 0 }, { 0,17420 }, { 1,6192 }, { 2,6192 }, { 3,6192 }, { 4,6192 }, { 5,6192 }, { 6,6192 }, @@ -4282,7 +4503,7 @@ static yyconst struct yy_trans_info yy_transition[17678] = { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 257, 67 }, { 1, 0 }, }; -static __thread yyconst struct yy_trans_info *yy_start_state_list[25] = +static __thread const struct yy_trans_info *yy_start_state_list[25] = { &yy_transition[1], &yy_transition[3], @@ -4376,7 +4597,7 @@ const uint16 ScanKeywordTokens[] = { #define YY_EXTRA_TYPE core_yy_extra_type * /* - * Each call to core_yylex must set yylloc to the location of the found token + * Each call to yylex must set yylloc to the location of the found token * (expressed as a byte offset from the start of the input text). * When we parse a token that requires multiple lexer rules to process, * this should be done in the first such rule, else yylloc will point @@ -4425,6 +4646,7 @@ static void check_escape_warning(core_yyscan_t yyscanner); extern int core_yyget_column(yyscan_t yyscanner); extern void core_yyset_column(int column_no, yyscan_t yyscanner); +#line 4600 "scan.c" #define YY_NO_INPUT 1 /* * OK, here is a short description of lex/flex rules behavior. @@ -4453,16 +4675,6 @@ extern void core_yyset_column(int column_no, yyscan_t yyscanner); * The default one is probably not the right thing. */ - - - - - - - - - - /* * In order to make the world safe for Windows and Mac clients as well as * Unix ones, we accept either \n or \r as a newline. A DOS-style \r\n @@ -4583,7 +4795,7 @@ extern void core_yyset_column(int column_no, yyscan_t yyscanner); * Note that xcstart must appear before operator, as explained above! * Also whitespace (comment) must appear before operator. */ -#line 4538 "scan.c" +#line 4749 "scan.c" #define INITIAL 0 #define xb 1 @@ -4648,7 +4860,7 @@ struct yyguts_t }; /* end struct yyguts_t */ -static int yy_init_globals (yyscan_t yyscanner ); +static int yy_init_globals ( yyscan_t yyscanner ); /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ @@ -4656,46 +4868,50 @@ static int yy_init_globals (yyscan_t yyscanner ); # define yylloc yyg->yylloc_r -int core_yylex_init (yyscan_t* scanner); +int yylex_init (yyscan_t* scanner); -int core_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); +int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ -int core_yylex_destroy (yyscan_t yyscanner ); +int yylex_destroy ( yyscan_t yyscanner ); + +int yyget_debug ( yyscan_t yyscanner ); + +void yyset_debug ( int debug_flag , yyscan_t yyscanner ); -int core_yyget_debug (yyscan_t yyscanner ); +YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); -void core_yyset_debug (int debug_flag ,yyscan_t yyscanner ); +void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); -YY_EXTRA_TYPE core_yyget_extra (yyscan_t yyscanner ); +FILE *yyget_in ( yyscan_t yyscanner ); -void core_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); +void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); -FILE *core_yyget_in (yyscan_t yyscanner ); +FILE *yyget_out ( yyscan_t yyscanner ); -void core_yyset_in (FILE * in_str ,yyscan_t yyscanner ); +void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); -FILE *core_yyget_out (yyscan_t yyscanner ); + yy_size_t yyget_leng ( yyscan_t yyscanner ); -void core_yyset_out (FILE * out_str ,yyscan_t yyscanner ); +char *yyget_text ( yyscan_t yyscanner ); -yy_size_t core_yyget_leng (yyscan_t yyscanner ); +int yyget_lineno ( yyscan_t yyscanner ); -char *core_yyget_text (yyscan_t yyscanner ); +void yyset_lineno ( int _line_number , yyscan_t yyscanner ); -int core_yyget_lineno (yyscan_t yyscanner ); +int yyget_column ( yyscan_t yyscanner ); -void core_yyset_lineno (int line_number ,yyscan_t yyscanner ); +void yyset_column ( int _column_no , yyscan_t yyscanner ); -YYSTYPE * core_yyget_lval (yyscan_t yyscanner ); +YYSTYPE * yyget_lval ( yyscan_t yyscanner ); -void core_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); +void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); - YYLTYPE *core_yyget_lloc (yyscan_t yyscanner ); + YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); - void core_yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); + void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. @@ -4703,33 +4919,41 @@ void core_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus -extern "C" int core_yywrap (yyscan_t yyscanner ); +extern "C" int yywrap ( yyscan_t yyscanner ); #else -extern int core_yywrap (yyscan_t yyscanner ); +extern int yywrap ( yyscan_t yyscanner ); #endif #endif +#ifndef YY_NO_UNPUT + +#endif + #ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT - #ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); +static int yyinput ( yyscan_t yyscanner ); #else -static int input (yyscan_t yyscanner ); +static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else #define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ @@ -4737,7 +4961,7 @@ static int input (yyscan_t yyscanner ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -4761,7 +4985,7 @@ static int input (yyscan_t yyscanner ); else \ { \ errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ @@ -4802,10 +5026,10 @@ static int input (yyscan_t yyscanner ); #ifndef YY_DECL #define YY_DECL_IS_OURS 1 -extern int core_yylex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); +extern int yylex \ + (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); -#define YY_DECL int core_yylex \ +#define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ @@ -4818,7 +5042,7 @@ extern int core_yylex \ /* Code executed at the end of each rule. */ #ifndef YY_BREAK -#define YY_BREAK break; +#define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ @@ -4828,16 +5052,11 @@ extern int core_yylex \ */ YY_DECL { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 420 "scan.l" - - -#line 4791 "scan.c" - yylval = yylval_param; yylloc = yylloc_param; @@ -4860,15 +5079,21 @@ YY_DECL yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { - core_yyensure_buffer_stack (yyscanner); + yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = - core_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } - core_yy_load_buffer_state(yyscanner ); + yy_load_buffer_state( yyscanner ); } - while ( 1 ) /* loops until end-of-file is reached */ + { +#line 420 "scan.l" + + +#line 5045 "scan.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; @@ -4883,12 +5108,12 @@ YY_DECL yy_current_state = yy_start_state_list[yyg->yy_start]; yy_match: { - register yyconst struct yy_trans_info *yy_trans_info; + const struct yy_trans_info *yy_trans_info; - register YY_CHAR yy_c; + YY_CHAR yy_c; for ( yy_c = YY_SC_TO_UI(*yy_cp); - (yy_trans_info = &yy_current_state[(unsigned int) yy_c])-> + (yy_trans_info = &yy_current_state[yy_c])-> yy_verify == yy_c; yy_c = YY_SC_TO_UI(*++yy_cp) ) yy_current_state += yy_trans_info->yy_nxt; @@ -5140,6 +5365,7 @@ case 19: case 20: /* rule 20 can match eol */ #line 585 "scan.l" +YY_RULE_SETUP case YY_STATE_EOF(xqs): #line 585 "scan.l" { @@ -5267,6 +5493,7 @@ case 26: case 27: /* rule 27 can match eol */ #line 685 "scan.l" +YY_RULE_SETUP case YY_STATE_EOF(xeu): #line 685 "scan.l" { @@ -5722,7 +5949,7 @@ YY_RULE_SETUP YY_BREAK case 57: YY_RULE_SETUP -#line 1016 "scan.l" +#line 1019 "scan.l" { SET_YYLLOC(); yylval->ival = atol(yytext + 1); @@ -5731,7 +5958,7 @@ YY_RULE_SETUP YY_BREAK case 58: YY_RULE_SETUP -#line 1022 "scan.l" +#line 1025 "scan.l" { SET_YYLLOC(); return process_integer_literal(yytext, yylval); @@ -5739,7 +5966,7 @@ YY_RULE_SETUP YY_BREAK case 59: YY_RULE_SETUP -#line 1026 "scan.l" +#line 1029 "scan.l" { SET_YYLLOC(); yylval->str = pstrdup(yytext); @@ -5748,7 +5975,7 @@ YY_RULE_SETUP YY_BREAK case 60: YY_RULE_SETUP -#line 1031 "scan.l" +#line 1034 "scan.l" { /* throw back the .., and treat as integer */ yyless(yyleng - 2); @@ -5758,7 +5985,7 @@ YY_RULE_SETUP YY_BREAK case 61: YY_RULE_SETUP -#line 1037 "scan.l" +#line 1040 "scan.l" { SET_YYLLOC(); yylval->str = pstrdup(yytext); @@ -5767,7 +5994,7 @@ YY_RULE_SETUP YY_BREAK case 62: YY_RULE_SETUP -#line 1042 "scan.l" +#line 1045 "scan.l" { /* * throw back the [Ee], and figure out whether what @@ -5780,7 +6007,7 @@ YY_RULE_SETUP YY_BREAK case 63: YY_RULE_SETUP -#line 1051 "scan.l" +#line 1054 "scan.l" { /* throw back the [Ee][+-], and proceed as above */ yyless(yyleng - 2); @@ -5790,7 +6017,7 @@ YY_RULE_SETUP YY_BREAK case 64: YY_RULE_SETUP -#line 1059 "scan.l" +#line 1062 "scan.l" { int kwnum; char *ident; @@ -5824,14 +6051,14 @@ YY_RULE_SETUP YY_BREAK case 65: YY_RULE_SETUP -#line 1090 "scan.l" +#line 1093 "scan.l" { SET_YYLLOC(); return yytext[0]; } YY_BREAK case YY_STATE_EOF(INITIAL): -#line 1095 "scan.l" +#line 1098 "scan.l" { SET_YYLLOC(); yyterminate(); @@ -5839,10 +6066,10 @@ case YY_STATE_EOF(INITIAL): YY_BREAK case 66: YY_RULE_SETUP -#line 1100 "scan.l" +#line 1103 "scan.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 5794 "scan.c" +#line 6023 "scan.c" case YY_END_OF_BUFFER: { @@ -5858,7 +6085,7 @@ YY_FATAL_ERROR( "flex scanner jammed" ); /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called - * core_yylex(). If so, then we have to assure + * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a @@ -5918,7 +6145,7 @@ YY_FATAL_ERROR( "flex scanner jammed" ); { yyg->yy_did_buffer_switch_on_eof = 0; - if ( core_yywrap(yyscanner ) ) + if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up @@ -5971,7 +6198,8 @@ YY_FATAL_ERROR( "flex scanner jammed" ); "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ -} /* end of core_yylex */ + } /* end of user's declarations */ +} /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * @@ -5983,9 +6211,9 @@ YY_FATAL_ERROR( "flex scanner jammed" ); static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = yyg->yytext_ptr; + int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) @@ -6014,7 +6242,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* Try to read more data. */ /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); @@ -6034,7 +6262,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); @@ -6050,11 +6278,12 @@ static int yy_get_next_buffer (yyscan_t yyscanner) b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ - core_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; + b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( @@ -6082,7 +6311,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; - core_yyrestart(yyin ,yyscanner); + yyrestart( yyin , yyscanner); } else @@ -6096,12 +6325,15 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else ret_val = EOB_ACT_CONTINUE_SCAN; - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) core_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; @@ -6117,8 +6349,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner) static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { - register yy_state_type yy_current_state; - register char *yy_cp; + yy_state_type yy_current_state; + char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yy_start_state_list[yyg->yy_start]; @@ -6138,20 +6370,24 @@ static int yy_get_next_buffer (yyscan_t yyscanner) */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { - register int yy_is_jam; + int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register int yy_c = 256; - register yyconst struct yy_trans_info *yy_trans_info; + int yy_c = 256; + const struct yy_trans_info *yy_trans_info; yy_trans_info = &yy_current_state[(unsigned int) yy_c]; yy_current_state += yy_trans_info->yy_nxt; yy_is_jam = (yy_trans_info->yy_verify != yy_c); - (void) yyg; + (void)yyg; return yy_is_jam ? 0 : yy_current_state; } +#ifndef YY_NO_UNPUT + +#endif + #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) @@ -6194,13 +6430,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner) */ /* Reset buffer status. */ - core_yyrestart(yyin ,yyscanner); + yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { - if ( core_yywrap(yyscanner ) ) + if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) @@ -6232,34 +6468,34 @@ static int yy_get_next_buffer (yyscan_t yyscanner) * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ - void core_yyrestart (FILE * input_file , yyscan_t yyscanner) + void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ - core_yyensure_buffer_stack (yyscanner); + yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = - core_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } - core_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - core_yy_load_buffer_state(yyscanner ); + yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); + yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ - void core_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with - * core_yypop_buffer_state(); - * core_yypush_buffer_state(new_buffer); + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); */ - core_yyensure_buffer_stack (yyscanner); + yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; @@ -6272,17 +6508,17 @@ static int yy_get_next_buffer (yyscan_t yyscanner) } YY_CURRENT_BUFFER_LVALUE = new_buffer; - core_yy_load_buffer_state(yyscanner ); + yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during - * EOF (core_yywrap()) processing, but the only time this flag - * is looked at is after core_yywrap() is called, so it's safe + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } -static void core_yy_load_buffer_state (yyscan_t yyscanner) +static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; @@ -6297,32 +6533,32 @@ static void core_yy_load_buffer_state (yyscan_t yyscanner) * @param yyscanner The scanner object. * @return the allocated buffer state. */ - YY_BUFFER_STATE core_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; - b = (YY_BUFFER_STATE) core_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in core_yy_create_buffer()" ); + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ - b->yy_ch_buf = (char *) core_yyalloc(b->yy_buf_size + 2 ,yyscanner ); + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in core_yy_create_buffer()" ); + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; - core_yy_init_buffer(b,file ,yyscanner); + yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. - * @param b a buffer created with core_yy_create_buffer() + * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ @@ -6330,21 +6566,21 @@ static void core_yy_load_buffer_state (yyscan_t yyscanner) /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, - * such as during a core_yyrestart() or at EOF. + * such as during a yyrestart() or at EOF. */ - static void core_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - core_yy_flush_buffer(b ,yyscanner); + yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; - /* If b is the current buffer, then core_yy_init_buffer was _probably_ - * called from core_yyrestart() or through yy_get_next_buffer. + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ @@ -6361,7 +6597,7 @@ static void core_yy_load_buffer_state (yyscan_t yyscanner) * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ - void core_yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) + void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) @@ -6382,7 +6618,7 @@ static void core_yy_load_buffer_state (yyscan_t yyscanner) b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) - core_yy_load_buffer_state(yyscanner ); + yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes @@ -6402,7 +6638,7 @@ static void core_yy_load_buffer_state (yyscan_t yyscanner) /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ -static void core_yyensure_buffer_stack (yyscan_t yyscanner) +static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; @@ -6413,15 +6649,15 @@ static void core_yyensure_buffer_stack (yyscan_t yyscanner) * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)core_yyalloc + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in core_yyensure_buffer_stack()" ); - + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - + yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; @@ -6430,15 +6666,15 @@ static void core_yyensure_buffer_stack (yyscan_t yyscanner) if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; + yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)core_yyrealloc + yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in core_yyensure_buffer_stack()" ); + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); @@ -6450,9 +6686,9 @@ static void core_yyensure_buffer_stack (yyscan_t yyscanner) * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. + * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE core_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; @@ -6460,41 +6696,41 @@ YY_BUFFER_STATE core_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yy base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ - return 0; + return NULL; - b = (YY_BUFFER_STATE) core_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in core_yy_scan_buffer()" ); + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; - b->yy_input_file = 0; + b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; - core_yy_switch_to_buffer(b ,yyscanner ); + yy_switch_to_buffer( b , yyscanner ); return b; } -/** Setup the input buffer state to scan a string. The next call to core_yylex() will +/** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use - * core_yy_scan_bytes() instead. + * yy_scan_bytes() instead. */ -/** Setup the input buffer state to scan the given bytes. The next call to core_yylex() will +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ @@ -6504,9 +6740,11 @@ YY_BUFFER_STATE core_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yy #define YY_EXIT_FAILURE 2 #endif -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) +static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner) { - (void) fprintf( stderr, "%s\n", msg ); + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } @@ -6517,7 +6755,7 @@ static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) do \ { \ /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ + yy_size_t yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ @@ -6569,29 +6807,29 @@ static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ -void core_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) +void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. - * @param line_number + * @param _line_number line number * @param yyscanner The scanner object. */ /** Set the current column. - * @param line_number + * @param _column_no column number * @param yyscanner The scanner object. */ /** Set the input stream. This does not discard the current * input buffer. - * @param in_str A readable stream. + * @param _in_str A readable stream. * @param yyscanner The scanner object. - * @see core_yy_switch_to_buffer + * @see yy_switch_to_buffer */ @@ -6613,20 +6851,18 @@ void core_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) /* User-visible API */ -/* core_yylex_init is special because it creates the scanner itself, so it is +/* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ - -int core_yylex_init(yyscan_t* ptr_yy_globals) - +int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } - *ptr_yy_globals = (yyscan_t) core_yyalloc ( sizeof( struct yyguts_t ), NULL ); + *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; @@ -6639,27 +6875,26 @@ int core_yylex_init(yyscan_t* ptr_yy_globals) return yy_init_globals ( *ptr_yy_globals ); } -/* core_yylex_init_extra has the same functionality as core_yylex_init, but follows the +/* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to core_yyalloc in + * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ - static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. - * This function is called from core_yylex_destroy(), so don't allocate here. + * This function is called from yylex_destroy(), so don't allocate here. */ - yyg->yy_buffer_stack = 0; + yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; + yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; @@ -6672,17 +6907,17 @@ static int yy_init_globals (yyscan_t yyscanner) yyin = stdin; yyout = stdout; #else - yyin = (FILE *) 0; - yyout = (FILE *) 0; + yyin = NULL; + yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by - * core_yylex_init() + * yylex_init() */ return 0; } -/* core_yylex_destroy is for both reentrant and non-reentrant scanners. */ +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ /* @@ -6690,18 +6925,21 @@ static int yy_init_globals (yyscan_t yyscanner) */ #ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) +static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { - register int i; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + + int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) +static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { - register int n; + int n; for ( n = 0; s[n]; ++n ) ; @@ -6711,14 +6949,13 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 1100 "scan.l" - +#line 1103 "scan.l" /* LCOV_EXCL_STOP */ /* - * Arrange access to yyextra for subroutines of the main core_yylex() function. + * Arrange access to yyextra for subroutines of the main yylex() function. * We expect each subroutine to have a yyscanner parameter. Rather than * use the yyget_xxx functions, which might or might not get inlined by the * compiler, we cheat just a bit and cast yyscanner to the right type. @@ -6820,7 +7057,7 @@ cancel_scanner_errposition_callback(ScannerCallbackState *scbstate) * Report a lexer or grammar error. * * The message's cursor position is whatever YYLLOC was last set to, - * ie, the start of the current token if called within core_yylex(), or the + * ie, the start of the current token if called within yylex(), or the * most recently lexed token if called from the grammar. * This is OK for syntax error messages from the Bison parser, because Bison * parsers report error as soon as the first unparsable token is reached. @@ -6863,8 +7100,8 @@ scanner_init(const char *str, Size slen = strlen(str); yyscan_t scanner; - if (core_yylex_init(&scanner) != 0) - elog(ERROR, "core_yylex_init() failed: %m"); + if (yylex_init(&scanner) != 0) + elog(ERROR, "yylex_init() failed: %m"); core_yyset_extra(yyext, scanner); @@ -6882,7 +7119,7 @@ scanner_init(const char *str, yyext->scanbuflen = slen; memcpy(yyext->scanbuf, str, slen); yyext->scanbuf[slen] = yyext->scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR; - core_yy_scan_buffer(yyext->scanbuf,slen + 2,scanner); + yy_scan_buffer(yyext->scanbuf, slen + 2, scanner); /* initialize literal buffer to a reasonable but expansible size */ yyext->literalalloc = 1024; @@ -6900,7 +7137,7 @@ void scanner_finish(core_yyscan_t yyscanner) { /* - * We don't bother to call core_yylex_destroy(), because all it would do is + * We don't bother to call yylex_destroy(), because all it would do is * pfree a small amount of control storage. It's cheaper to leak the * storage until the parsing context is destroyed. The amount of space * involved is usually negligible compared to the output parse tree diff --git a/src/postgres/src_backend_tcop_postgres.c b/src/postgres/src_backend_tcop_postgres.c index d7c84962..02d4d313 100644 --- a/src/postgres/src_backend_tcop_postgres.c +++ b/src/postgres/src_backend_tcop_postgres.c @@ -55,7 +55,6 @@ #include "catalog/pg_type.h" #include "commands/async.h" #include "commands/prepare.h" -#include "executor/spi.h" #include "jit/jit.h" #include "libpq/libpq.h" #include "libpq/pqformat.h" @@ -520,6 +519,12 @@ static void disable_statement_timeout(void); * If an interrupt condition is pending, and it's safe to service it, * then clear the flag and accept the interrupt. Called only when * InterruptPending is true. + * + * Note: if INTERRUPTS_CAN_BE_PROCESSED() is true, then ProcessInterrupts + * is guaranteed to clear the InterruptPending flag before returning. + * (This is not the same as guaranteeing that it's still clear when we + * return; another interrupt could have arrived. But we promise that + * any pre-existing one will have been serviced.) */ void ProcessInterrupts(void) {} @@ -568,9 +573,14 @@ ia64_get_bsp(void) * * Returns the old reference point, if any. */ +#ifndef HAVE__BUILTIN_FRAME_ADDRESS +#endif #if defined(__ia64__) || defined(__ia64) #else #endif +#ifdef HAVE__BUILTIN_FRAME_ADDRESS +#else +#endif #if defined(__ia64__) || defined(__ia64) #endif diff --git a/src/postgres/src_backend_utils_adt_ruleutils.c b/src/postgres/src_backend_utils_adt_ruleutils.c index 567afdb7..00ea82ef 100644 --- a/src/postgres/src_backend_utils_adt_ruleutils.c +++ b/src/postgres/src_backend_utils_adt_ruleutils.c @@ -62,6 +62,7 @@ #include "parser/parse_func.h" #include "parser/parse_node.h" #include "parser/parse_oper.h" +#include "parser/parse_relation.h" #include "parser/parser.h" #include "parser/parsetree.h" #include "rewrite/rewriteHandler.h" @@ -392,26 +393,29 @@ static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, int prettyFlags, int wrapColumn); static void get_query_def(Query *query, StringInfo buf, List *parentnamespace, - TupleDesc resultDesc, + TupleDesc resultDesc, bool colNamesVisible, int prettyFlags, int wrapColumn, int startIndent); static void get_values_def(List *values_lists, deparse_context *context); static void get_with_clause(Query *query, deparse_context *context); static void get_select_query_def(Query *query, deparse_context *context, - TupleDesc resultDesc); -static void get_insert_query_def(Query *query, deparse_context *context); -static void get_update_query_def(Query *query, deparse_context *context); + TupleDesc resultDesc, bool colNamesVisible); +static void get_insert_query_def(Query *query, deparse_context *context, + bool colNamesVisible); +static void get_update_query_def(Query *query, deparse_context *context, + bool colNamesVisible); static void get_update_query_targetlist_def(Query *query, List *targetList, deparse_context *context, RangeTblEntry *rte); -static void get_delete_query_def(Query *query, deparse_context *context); +static void get_delete_query_def(Query *query, deparse_context *context, + bool colNamesVisible); static void get_utility_query_def(Query *query, deparse_context *context); static void get_basic_select_query(Query *query, deparse_context *context, - TupleDesc resultDesc); + TupleDesc resultDesc, bool colNamesVisible); static void get_target_list(List *targetList, deparse_context *context, - TupleDesc resultDesc); + TupleDesc resultDesc, bool colNamesVisible); static void get_setop_query(Node *setOp, Query *query, deparse_context *context, - TupleDesc resultDesc); + TupleDesc resultDesc, bool colNamesVisible); static Node *get_rule_sortgroupclause(Index ref, List *tlist, bool force_colno, deparse_context *context); @@ -440,6 +444,8 @@ static void get_rule_expr(Node *node, deparse_context *context, bool showimplicit); static void get_rule_expr_toplevel(Node *node, deparse_context *context, bool showimplicit); +static void get_rule_list_toplevel(List *lst, deparse_context *context, + bool showimplicit); static void get_rule_expr_funccall(Node *node, deparse_context *context, bool showimplicit); static bool looks_like_function(Node *node); @@ -1037,8 +1043,18 @@ static void get_reloptions(StringInfo buf, Datum reloptions); /* ---------- * get_query_def - Parse back one query parsetree * - * If resultDesc is not NULL, then it is the output tuple descriptor for - * the view represented by a SELECT query. + * query: parsetree to be displayed + * buf: output text is appended to buf + * parentnamespace: list (initially empty) of outer-level deparse_namespace's + * resultDesc: if not NULL, the output tuple descriptor for the view + * represented by a SELECT query. We use the column names from it + * to label SELECT output columns, in preference to names in the query + * colNamesVisible: true if the surrounding context cares about the output + * column names at all (as, for example, an EXISTS() context does not); + * when false, we can suppress dummy column labels such as "?column?" + * prettyFlags: bitmask of PRETTYFLAG_XXX options + * wrapColumn: maximum line length, or -1 to disable wrapping + * startIndent: initial indentation amount * ---------- */ @@ -1074,6 +1090,8 @@ static void get_reloptions(StringInfo buf, Datum reloptions); * get_target_list - Parse back a SELECT target list * * This is also used for RETURNING lists in INSERT/UPDATE/DELETE. + * + * resultDesc and colNamesVisible are as for get_query_def() * ---------- */ @@ -1291,6 +1309,16 @@ static void get_reloptions(StringInfo buf, Datum reloptions); */ +/* + * get_rule_list_toplevel - Parse back a list of toplevel expressions + * + * Apply get_rule_expr_toplevel() to each element of a List. + * + * This adds commas between the expressions, but caller is responsible + * for printing surrounding decoration. + */ + + /* * get_rule_expr_funccall - Parse back a function-call expression * diff --git a/src/postgres/src_backend_utils_misc_guc.c b/src/postgres/src_backend_utils_misc_guc.c index 5be929b9..0155ef79 100644 --- a/src/postgres/src_backend_utils_misc_guc.c +++ b/src/postgres/src_backend_utils_misc_guc.c @@ -49,6 +49,7 @@ #include "catalog/storage.h" #include "commands/async.h" #include "commands/prepare.h" +#include "commands/tablespace.h" #include "commands/trigger.h" #include "commands/user.h" #include "commands/vacuum.h" diff --git a/src/postgres/src_common_wchar.c b/src/postgres/src_common_wchar.c index 8a1228e5..339ede6d 100644 --- a/src/postgres/src_common_wchar.c +++ b/src/postgres/src_common_wchar.c @@ -1618,6 +1618,11 @@ const pg_wchar_tbl pg_wchar_table[] = { /* * Returns the byte length of a multibyte character. + * + * Caution: when dealing with text that is not certainly valid in the + * specified encoding, the result may exceed the actual remaining + * string length. Callers that are not prepared to deal with that + * should use pg_encoding_mblen_bounded() instead. */ int pg_encoding_mblen(int encoding, const char *mbstr) @@ -1627,6 +1632,12 @@ pg_encoding_mblen(int encoding, const char *mbstr) pg_wchar_table[PG_SQL_ASCII].mblen((const unsigned char *) mbstr)); } +/* + * Returns the byte length of a multibyte character; but not more than + * the distance to end of string. + */ + + /* * Returns the display length of a multibyte character. */ diff --git a/src/postgres/src_pl_plpgsql_src_pl_comp.c b/src/postgres/src_pl_plpgsql_src_pl_comp.c index 3f54b842..95d60a68 100644 --- a/src/postgres/src_pl_plpgsql_src_pl_comp.c +++ b/src/postgres/src_pl_plpgsql_src_pl_comp.c @@ -385,9 +385,11 @@ add_dummy_return(PLpgSQL_function *function) /* * If the outer block has an EXCEPTION clause, we need to make a new outer * block, since the added RETURN shouldn't act like it is inside the - * EXCEPTION clause. + * EXCEPTION clause. Likewise, if it has a label, wrap it in a new outer + * block so that EXIT doesn't skip the RETURN. */ - if (function->action->exceptions != NULL) + if (function->action->exceptions != NULL || + function->action->label != NULL) { PLpgSQL_stmt_block *new; diff --git a/src/postgres/src_pl_plpgsql_src_pl_gram.c b/src/postgres/src_pl_plpgsql_src_pl_gram.c index a3ac4064..ab91977e 100644 --- a/src/postgres/src_pl_plpgsql_src_pl_gram.c +++ b/src/postgres/src_pl_plpgsql_src_pl_gram.c @@ -5535,7 +5535,7 @@ make_execsql_stmt(int firsttoken, int location) check_sql_expr(expr->query, location, 0); - execsql = palloc(sizeof(PLpgSQL_stmt_execsql)); + execsql = palloc0(sizeof(PLpgSQL_stmt_execsql)); execsql->cmd_type = PLPGSQL_STMT_EXECSQL; execsql->lineno = plpgsql_location_to_lineno(location); execsql->stmtid = ++plpgsql_curr_compile->nstatements; diff --git a/src/postgres/src_port_pg_bitutils.c b/src/postgres/src_port_pg_bitutils.c index 847c02a3..39a16f19 100644 --- a/src/postgres/src_port_pg_bitutils.c +++ b/src/postgres/src_port_pg_bitutils.c @@ -1,13 +1,6 @@ /*-------------------------------------------------------------------- * Symbols referenced in this file: * - pg_popcount64 - * - pg_popcount64_choose - * - pg_popcount32 - * - pg_popcount32_choose - * - pg_popcount_available - * - pg_popcount32_asm - * - pg_popcount64_asm - * - pg_popcount32_slow * - pg_popcount64_slow *-------------------------------------------------------------------- */ @@ -92,7 +85,7 @@ static int pg_popcount64_asm(uint64 word); int (*pg_popcount32) (uint32 word) = pg_popcount32_choose; int (*pg_popcount64) (uint64 word) = pg_popcount64_choose; #else -int (*pg_popcount32) (uint32 word) = pg_popcount32_slow; + int (*pg_popcount64) (uint64 word) = pg_popcount64_slow; #endif /* USE_POPCNT_ASM */ @@ -190,23 +183,9 @@ __asm__ __volatile__(" popcntq %1,%0\n":"=q"(res):"rm"(word):"cc"); * pg_popcount32_slow * Return the number of 1 bits set in word */ -static int -pg_popcount32_slow(uint32 word) -{ #ifdef HAVE__BUILTIN_POPCOUNT - return __builtin_popcount(word); #else /* !HAVE__BUILTIN_POPCOUNT */ - int result = 0; - - while (word != 0) - { - result += pg_number_of_ones[word & 255]; - word >>= 8; - } - - return result; #endif /* HAVE__BUILTIN_POPCOUNT */ -} /* * pg_popcount64_slow diff --git a/src/postgres/src_port_snprintf.c b/src/postgres/src_port_snprintf.c index 1b3f1710..578e5fd9 100644 --- a/src/postgres/src_port_snprintf.c +++ b/src/postgres/src_port_snprintf.c @@ -344,7 +344,7 @@ static bool find_arguments(const char *format, va_list args, PrintfArgValue *argvalues); static void fmtstr(const char *value, int leftjust, int minlen, int maxwidth, int pointflag, PrintfTarget *target); -static void fmtptr(void *value, PrintfTarget *target); +static void fmtptr(const void *value, PrintfTarget *target); static void fmtint(long long value, char type, int forcesign, int leftjust, int minlen, int zpad, int precision, int pointflag, PrintfTarget *target); @@ -418,7 +418,7 @@ dopr(PrintfTarget *target, const char *format, va_list args) int cvalue; long long numvalue; double fvalue; - char *strvalue; + const char *strvalue; PrintfArgValue argvalues[PG_NL_ARGMAX + 1]; /* @@ -463,7 +463,8 @@ dopr(PrintfTarget *target, const char *format, va_list args) { format++; strvalue = va_arg(args, char *); - Assert(strvalue != NULL); + if (strvalue == NULL) + strvalue = "(null)"; dostr(strvalue, strlen(strvalue), target); if (target->failed) break; @@ -694,8 +695,9 @@ dopr(PrintfTarget *target, const char *format, va_list args) strvalue = argvalues[fmtpos].cptr; else strvalue = va_arg(args, char *); - /* Whine if someone tries to print a NULL string */ - Assert(strvalue != NULL); + /* If string is NULL, silently substitute "(null)" */ + if (strvalue == NULL) + strvalue = "(null)"; fmtstr(strvalue, leftjust, fieldwidth, precision, pointflag, target); break; @@ -705,7 +707,7 @@ dopr(PrintfTarget *target, const char *format, va_list args) strvalue = argvalues[fmtpos].cptr; else strvalue = va_arg(args, char *); - fmtptr((void *) strvalue, target); + fmtptr((const void *) strvalue, target); break; case 'e': case 'E': @@ -1019,7 +1021,7 @@ fmtstr(const char *value, int leftjust, int minlen, int maxwidth, } static void -fmtptr(void *value, PrintfTarget *target) +fmtptr(const void *value, PrintfTarget *target) { int vallen; char convert[64]; diff --git a/srcdata/enum_defs.json b/srcdata/enum_defs.json index 7137e705..5566eb94 100644 --- a/srcdata/enum_defs.json +++ b/srcdata/enum_defs.json @@ -356,7 +356,7 @@ "comment": "/* RTE represents an empty FROM clause; such\n\t\t\t\t\t\t\t\t * RTEs are added by the planner, they're not\n\t\t\t\t\t\t\t\t * present during parsing or rewriting */\n" } ], - "comment": "/*--------------------\n * RangeTblEntry -\n *\t A range table is a List of RangeTblEntry nodes.\n *\n *\t A range table entry may represent a plain relation, a sub-select in\n *\t FROM, or the result of a JOIN clause. (Only explicit JOIN syntax\n *\t produces an RTE, not the implicit join resulting from multiple FROM\n *\t items. This is because we only need the RTE to deal with SQL features\n *\t like outer joins and join-output-column aliasing.) Other special\n *\t RTE types also exist, as indicated by RTEKind.\n *\n *\t Note that we consider RTE_RELATION to cover anything that has a pg_class\n *\t entry. relkind distinguishes the sub-cases.\n *\n *\t alias is an Alias node representing the AS alias-clause attached to the\n *\t FROM expression, or NULL if no clause.\n *\n *\t eref is the table reference name and column reference names (either\n *\t real or aliases). Note that system columns (OID etc) are not included\n *\t in the column list.\n *\t eref->aliasname is required to be present, and should generally be used\n *\t to identify the RTE for error messages etc.\n *\n *\t In RELATION RTEs, the colnames in both alias and eref are indexed by\n *\t physical attribute number; this means there must be colname entries for\n *\t dropped columns. When building an RTE we insert empty strings (\"\") for\n *\t dropped columns. Note however that a stored rule may have nonempty\n *\t colnames for columns dropped since the rule was created (and for that\n *\t matter the colnames might be out of date due to column renamings).\n *\t The same comments apply to FUNCTION RTEs when a function's return type\n *\t is a named composite type.\n *\n *\t In JOIN RTEs, the colnames in both alias and eref are one-to-one with\n *\t joinaliasvars entries. A JOIN RTE will omit columns of its inputs when\n *\t those columns are known to be dropped at parse time. Again, however,\n *\t a stored rule might contain entries for columns dropped since the rule\n *\t was created. (This is only possible for columns not actually referenced\n *\t in the rule.) When loading a stored rule, we replace the joinaliasvars\n *\t items for any such columns with null pointers. (We can't simply delete\n *\t them from the joinaliasvars list, because that would affect the attnums\n *\t of Vars referencing the rest of the list.)\n *\n *\t inh is true for relation references that should be expanded to include\n *\t inheritance children, if the rel has any. This *must* be false for\n *\t RTEs other than RTE_RELATION entries.\n *\n *\t inFromCl marks those range variables that are listed in the FROM clause.\n *\t It's false for RTEs that are added to a query behind the scenes, such\n *\t as the NEW and OLD variables for a rule, or the subqueries of a UNION.\n *\t This flag is not used anymore during parsing, since the parser now uses\n *\t a separate \"namespace\" data structure to control visibility, but it is\n *\t needed by ruleutils.c to determine whether RTEs should be shown in\n *\t decompiled queries.\n *\n *\t requiredPerms and checkAsUser specify run-time access permissions\n *\t checks to be performed at query startup. The user must have *all*\n *\t of the permissions that are OR'd together in requiredPerms (zero\n *\t indicates no permissions checking). If checkAsUser is not zero,\n *\t then do the permissions checks using the access rights of that user,\n *\t not the current effective user ID. (This allows rules to act as\n *\t setuid gateways.) Permissions checks only apply to RELATION RTEs.\n *\n *\t For SELECT/INSERT/UPDATE permissions, if the user doesn't have\n *\t table-wide permissions then it is sufficient to have the permissions\n *\t on all columns identified in selectedCols (for SELECT) and/or\n *\t insertedCols and/or updatedCols (INSERT with ON CONFLICT DO UPDATE may\n *\t have all 3). selectedCols, insertedCols and updatedCols are bitmapsets,\n *\t which cannot have negative integer members, so we subtract\n *\t FirstLowInvalidHeapAttributeNumber from column numbers before storing\n *\t them in these fields. A whole-row Var reference is represented by\n *\t setting the bit for InvalidAttrNumber.\n *\n *\t updatedCols is also used in some other places, for example, to determine\n *\t which triggers to fire and in FDWs to know which changed columns they\n *\t need to ship off.\n *\n *\t Generated columns that are caused to be updated by an update to a base\n *\t column are listed in extraUpdatedCols. This is not considered for\n *\t permission checking, but it is useful in those places that want to know\n *\t the full set of columns being updated as opposed to only the ones the\n *\t user explicitly mentioned in the query. (There is currently no need for\n *\t an extraInsertedCols, but it could exist.) Note that extraUpdatedCols\n *\t is populated during query rewrite, NOT in the parser, since generated\n *\t columns could be added after a rule has been parsed and stored.\n *\n *\t securityQuals is a list of security barrier quals (boolean expressions),\n *\t to be tested in the listed order before returning a row from the\n *\t relation. It is always NIL in parser output. Entries are added by the\n *\t rewriter to implement security-barrier views and/or row-level security.\n *\t Note that the planner turns each boolean expression into an implicitly\n *\t AND'ed sublist, as is its usual habit with qualification expressions.\n *--------------------\n */\n" + "comment": "/*--------------------\n * RangeTblEntry -\n *\t A range table is a List of RangeTblEntry nodes.\n *\n *\t A range table entry may represent a plain relation, a sub-select in\n *\t FROM, or the result of a JOIN clause. (Only explicit JOIN syntax\n *\t produces an RTE, not the implicit join resulting from multiple FROM\n *\t items. This is because we only need the RTE to deal with SQL features\n *\t like outer joins and join-output-column aliasing.) Other special\n *\t RTE types also exist, as indicated by RTEKind.\n *\n *\t Note that we consider RTE_RELATION to cover anything that has a pg_class\n *\t entry. relkind distinguishes the sub-cases.\n *\n *\t alias is an Alias node representing the AS alias-clause attached to the\n *\t FROM expression, or NULL if no clause.\n *\n *\t eref is the table reference name and column reference names (either\n *\t real or aliases). Note that system columns (OID etc) are not included\n *\t in the column list.\n *\t eref->aliasname is required to be present, and should generally be used\n *\t to identify the RTE for error messages etc.\n *\n *\t In RELATION RTEs, the colnames in both alias and eref are indexed by\n *\t physical attribute number; this means there must be colname entries for\n *\t dropped columns. When building an RTE we insert empty strings (\"\") for\n *\t dropped columns. Note however that a stored rule may have nonempty\n *\t colnames for columns dropped since the rule was created (and for that\n *\t matter the colnames might be out of date due to column renamings).\n *\t The same comments apply to FUNCTION RTEs when a function's return type\n *\t is a named composite type.\n *\n *\t In JOIN RTEs, the colnames in both alias and eref are one-to-one with\n *\t joinaliasvars entries. A JOIN RTE will omit columns of its inputs when\n *\t those columns are known to be dropped at parse time. Again, however,\n *\t a stored rule might contain entries for columns dropped since the rule\n *\t was created. (This is only possible for columns not actually referenced\n *\t in the rule.) When loading a stored rule, we replace the joinaliasvars\n *\t items for any such columns with null pointers. (We can't simply delete\n *\t them from the joinaliasvars list, because that would affect the attnums\n *\t of Vars referencing the rest of the list.)\n *\n *\t inh is true for relation references that should be expanded to include\n *\t inheritance children, if the rel has any. This *must* be false for\n *\t RTEs other than RTE_RELATION entries.\n *\n *\t inFromCl marks those range variables that are listed in the FROM clause.\n *\t It's false for RTEs that are added to a query behind the scenes, such\n *\t as the NEW and OLD variables for a rule, or the subqueries of a UNION.\n *\t This flag is not used during parsing (except in transformLockingClause,\n *\t q.v.); the parser now uses a separate \"namespace\" data structure to\n *\t control visibility. But it is needed by ruleutils.c to determine\n *\t whether RTEs should be shown in decompiled queries.\n *\n *\t requiredPerms and checkAsUser specify run-time access permissions\n *\t checks to be performed at query startup. The user must have *all*\n *\t of the permissions that are OR'd together in requiredPerms (zero\n *\t indicates no permissions checking). If checkAsUser is not zero,\n *\t then do the permissions checks using the access rights of that user,\n *\t not the current effective user ID. (This allows rules to act as\n *\t setuid gateways.) Permissions checks only apply to RELATION RTEs.\n *\n *\t For SELECT/INSERT/UPDATE permissions, if the user doesn't have\n *\t table-wide permissions then it is sufficient to have the permissions\n *\t on all columns identified in selectedCols (for SELECT) and/or\n *\t insertedCols and/or updatedCols (INSERT with ON CONFLICT DO UPDATE may\n *\t have all 3). selectedCols, insertedCols and updatedCols are bitmapsets,\n *\t which cannot have negative integer members, so we subtract\n *\t FirstLowInvalidHeapAttributeNumber from column numbers before storing\n *\t them in these fields. A whole-row Var reference is represented by\n *\t setting the bit for InvalidAttrNumber.\n *\n *\t updatedCols is also used in some other places, for example, to determine\n *\t which triggers to fire and in FDWs to know which changed columns they\n *\t need to ship off.\n *\n *\t Generated columns that are caused to be updated by an update to a base\n *\t column are listed in extraUpdatedCols. This is not considered for\n *\t permission checking, but it is useful in those places that want to know\n *\t the full set of columns being updated as opposed to only the ones the\n *\t user explicitly mentioned in the query. (There is currently no need for\n *\t an extraInsertedCols, but it could exist.) Note that extraUpdatedCols\n *\t is populated during query rewrite, NOT in the parser, since generated\n *\t columns could be added after a rule has been parsed and stored.\n *\n *\t securityQuals is a list of security barrier quals (boolean expressions),\n *\t to be tested in the listed order before returning a row from the\n *\t relation. It is always NIL in parser output. Entries are added by the\n *\t rewriter to implement security-barrier views and/or row-level security.\n *\t Note that the planner turns each boolean expression into an implicitly\n *\t AND'ed sublist, as is its usual habit with qualification expressions.\n *--------------------\n */\n" }, "WCOKind": { "values": [ @@ -5683,7 +5683,7 @@ "value": 581 }, { - "name": "REF", + "name": "REF_P", "value": 582 }, { diff --git a/srcdata/struct_defs.json b/srcdata/struct_defs.json index 51b9a254..14445f85 100644 --- a/srcdata/struct_defs.json +++ b/srcdata/struct_defs.json @@ -1660,7 +1660,7 @@ "comment": "/* security barrier quals to apply, if any */" } ], - "comment": "/*--------------------\n * RangeTblEntry -\n *\t A range table is a List of RangeTblEntry nodes.\n *\n *\t A range table entry may represent a plain relation, a sub-select in\n *\t FROM, or the result of a JOIN clause. (Only explicit JOIN syntax\n *\t produces an RTE, not the implicit join resulting from multiple FROM\n *\t items. This is because we only need the RTE to deal with SQL features\n *\t like outer joins and join-output-column aliasing.) Other special\n *\t RTE types also exist, as indicated by RTEKind.\n *\n *\t Note that we consider RTE_RELATION to cover anything that has a pg_class\n *\t entry. relkind distinguishes the sub-cases.\n *\n *\t alias is an Alias node representing the AS alias-clause attached to the\n *\t FROM expression, or NULL if no clause.\n *\n *\t eref is the table reference name and column reference names (either\n *\t real or aliases). Note that system columns (OID etc) are not included\n *\t in the column list.\n *\t eref->aliasname is required to be present, and should generally be used\n *\t to identify the RTE for error messages etc.\n *\n *\t In RELATION RTEs, the colnames in both alias and eref are indexed by\n *\t physical attribute number; this means there must be colname entries for\n *\t dropped columns. When building an RTE we insert empty strings (\"\") for\n *\t dropped columns. Note however that a stored rule may have nonempty\n *\t colnames for columns dropped since the rule was created (and for that\n *\t matter the colnames might be out of date due to column renamings).\n *\t The same comments apply to FUNCTION RTEs when a function's return type\n *\t is a named composite type.\n *\n *\t In JOIN RTEs, the colnames in both alias and eref are one-to-one with\n *\t joinaliasvars entries. A JOIN RTE will omit columns of its inputs when\n *\t those columns are known to be dropped at parse time. Again, however,\n *\t a stored rule might contain entries for columns dropped since the rule\n *\t was created. (This is only possible for columns not actually referenced\n *\t in the rule.) When loading a stored rule, we replace the joinaliasvars\n *\t items for any such columns with null pointers. (We can't simply delete\n *\t them from the joinaliasvars list, because that would affect the attnums\n *\t of Vars referencing the rest of the list.)\n *\n *\t inh is true for relation references that should be expanded to include\n *\t inheritance children, if the rel has any. This *must* be false for\n *\t RTEs other than RTE_RELATION entries.\n *\n *\t inFromCl marks those range variables that are listed in the FROM clause.\n *\t It's false for RTEs that are added to a query behind the scenes, such\n *\t as the NEW and OLD variables for a rule, or the subqueries of a UNION.\n *\t This flag is not used anymore during parsing, since the parser now uses\n *\t a separate \"namespace\" data structure to control visibility, but it is\n *\t needed by ruleutils.c to determine whether RTEs should be shown in\n *\t decompiled queries.\n *\n *\t requiredPerms and checkAsUser specify run-time access permissions\n *\t checks to be performed at query startup. The user must have *all*\n *\t of the permissions that are OR'd together in requiredPerms (zero\n *\t indicates no permissions checking). If checkAsUser is not zero,\n *\t then do the permissions checks using the access rights of that user,\n *\t not the current effective user ID. (This allows rules to act as\n *\t setuid gateways.) Permissions checks only apply to RELATION RTEs.\n *\n *\t For SELECT/INSERT/UPDATE permissions, if the user doesn't have\n *\t table-wide permissions then it is sufficient to have the permissions\n *\t on all columns identified in selectedCols (for SELECT) and/or\n *\t insertedCols and/or updatedCols (INSERT with ON CONFLICT DO UPDATE may\n *\t have all 3). selectedCols, insertedCols and updatedCols are bitmapsets,\n *\t which cannot have negative integer members, so we subtract\n *\t FirstLowInvalidHeapAttributeNumber from column numbers before storing\n *\t them in these fields. A whole-row Var reference is represented by\n *\t setting the bit for InvalidAttrNumber.\n *\n *\t updatedCols is also used in some other places, for example, to determine\n *\t which triggers to fire and in FDWs to know which changed columns they\n *\t need to ship off.\n *\n *\t Generated columns that are caused to be updated by an update to a base\n *\t column are listed in extraUpdatedCols. This is not considered for\n *\t permission checking, but it is useful in those places that want to know\n *\t the full set of columns being updated as opposed to only the ones the\n *\t user explicitly mentioned in the query. (There is currently no need for\n *\t an extraInsertedCols, but it could exist.) Note that extraUpdatedCols\n *\t is populated during query rewrite, NOT in the parser, since generated\n *\t columns could be added after a rule has been parsed and stored.\n *\n *\t securityQuals is a list of security barrier quals (boolean expressions),\n *\t to be tested in the listed order before returning a row from the\n *\t relation. It is always NIL in parser output. Entries are added by the\n *\t rewriter to implement security-barrier views and/or row-level security.\n *\t Note that the planner turns each boolean expression into an implicitly\n *\t AND'ed sublist, as is its usual habit with qualification expressions.\n *--------------------\n */\n" + "comment": "/*--------------------\n * RangeTblEntry -\n *\t A range table is a List of RangeTblEntry nodes.\n *\n *\t A range table entry may represent a plain relation, a sub-select in\n *\t FROM, or the result of a JOIN clause. (Only explicit JOIN syntax\n *\t produces an RTE, not the implicit join resulting from multiple FROM\n *\t items. This is because we only need the RTE to deal with SQL features\n *\t like outer joins and join-output-column aliasing.) Other special\n *\t RTE types also exist, as indicated by RTEKind.\n *\n *\t Note that we consider RTE_RELATION to cover anything that has a pg_class\n *\t entry. relkind distinguishes the sub-cases.\n *\n *\t alias is an Alias node representing the AS alias-clause attached to the\n *\t FROM expression, or NULL if no clause.\n *\n *\t eref is the table reference name and column reference names (either\n *\t real or aliases). Note that system columns (OID etc) are not included\n *\t in the column list.\n *\t eref->aliasname is required to be present, and should generally be used\n *\t to identify the RTE for error messages etc.\n *\n *\t In RELATION RTEs, the colnames in both alias and eref are indexed by\n *\t physical attribute number; this means there must be colname entries for\n *\t dropped columns. When building an RTE we insert empty strings (\"\") for\n *\t dropped columns. Note however that a stored rule may have nonempty\n *\t colnames for columns dropped since the rule was created (and for that\n *\t matter the colnames might be out of date due to column renamings).\n *\t The same comments apply to FUNCTION RTEs when a function's return type\n *\t is a named composite type.\n *\n *\t In JOIN RTEs, the colnames in both alias and eref are one-to-one with\n *\t joinaliasvars entries. A JOIN RTE will omit columns of its inputs when\n *\t those columns are known to be dropped at parse time. Again, however,\n *\t a stored rule might contain entries for columns dropped since the rule\n *\t was created. (This is only possible for columns not actually referenced\n *\t in the rule.) When loading a stored rule, we replace the joinaliasvars\n *\t items for any such columns with null pointers. (We can't simply delete\n *\t them from the joinaliasvars list, because that would affect the attnums\n *\t of Vars referencing the rest of the list.)\n *\n *\t inh is true for relation references that should be expanded to include\n *\t inheritance children, if the rel has any. This *must* be false for\n *\t RTEs other than RTE_RELATION entries.\n *\n *\t inFromCl marks those range variables that are listed in the FROM clause.\n *\t It's false for RTEs that are added to a query behind the scenes, such\n *\t as the NEW and OLD variables for a rule, or the subqueries of a UNION.\n *\t This flag is not used during parsing (except in transformLockingClause,\n *\t q.v.); the parser now uses a separate \"namespace\" data structure to\n *\t control visibility. But it is needed by ruleutils.c to determine\n *\t whether RTEs should be shown in decompiled queries.\n *\n *\t requiredPerms and checkAsUser specify run-time access permissions\n *\t checks to be performed at query startup. The user must have *all*\n *\t of the permissions that are OR'd together in requiredPerms (zero\n *\t indicates no permissions checking). If checkAsUser is not zero,\n *\t then do the permissions checks using the access rights of that user,\n *\t not the current effective user ID. (This allows rules to act as\n *\t setuid gateways.) Permissions checks only apply to RELATION RTEs.\n *\n *\t For SELECT/INSERT/UPDATE permissions, if the user doesn't have\n *\t table-wide permissions then it is sufficient to have the permissions\n *\t on all columns identified in selectedCols (for SELECT) and/or\n *\t insertedCols and/or updatedCols (INSERT with ON CONFLICT DO UPDATE may\n *\t have all 3). selectedCols, insertedCols and updatedCols are bitmapsets,\n *\t which cannot have negative integer members, so we subtract\n *\t FirstLowInvalidHeapAttributeNumber from column numbers before storing\n *\t them in these fields. A whole-row Var reference is represented by\n *\t setting the bit for InvalidAttrNumber.\n *\n *\t updatedCols is also used in some other places, for example, to determine\n *\t which triggers to fire and in FDWs to know which changed columns they\n *\t need to ship off.\n *\n *\t Generated columns that are caused to be updated by an update to a base\n *\t column are listed in extraUpdatedCols. This is not considered for\n *\t permission checking, but it is useful in those places that want to know\n *\t the full set of columns being updated as opposed to only the ones the\n *\t user explicitly mentioned in the query. (There is currently no need for\n *\t an extraInsertedCols, but it could exist.) Note that extraUpdatedCols\n *\t is populated during query rewrite, NOT in the parser, since generated\n *\t columns could be added after a rule has been parsed and stored.\n *\n *\t securityQuals is a list of security barrier quals (boolean expressions),\n *\t to be tested in the listed order before returning a row from the\n *\t relation. It is always NIL in parser output. Entries are added by the\n *\t rewriter to implement security-barrier views and/or row-level security.\n *\t Note that the planner turns each boolean expression into an implicitly\n *\t AND'ed sublist, as is its usual habit with qualification expressions.\n *--------------------\n */\n" }, "RangeTblFunction": { "fields": [ @@ -2592,6 +2592,11 @@ "name": "missing_ok", "c_type": "bool", "comment": "/* skip error if missing? */" + }, + { + "name": "recurse", + "c_type": "bool", + "comment": "/* exec-time recursion */" } ], "comment": "/* ----------------------\n *\tAlter Table\n * ----------------------\n */\n" diff --git a/test/parse_tests.c b/test/parse_tests.c index 19da1956..63b804f4 100644 --- a/test/parse_tests.c +++ b/test/parse_tests.c @@ -1,58 +1,58 @@ const char* tests[] = { "SELECT 1", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":7}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":7}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "SELECT 1; SELECT 2", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":7}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}},\"stmt_len\":8},{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":2}},\"location\":17}},\"location\":17}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}},\"stmt_location\":9}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":7}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}},\"stmt_len\":8},{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":2}},\"location\":17}},\"location\":17}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}},\"stmt_location\":9}]}", "select sum(unique1) FILTER (WHERE unique1 IN (SELECT unique1 FROM onek where unique1 < 100)) FROM tenk1", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"sum\"}}],\"args\":[{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":11}}],\"agg_filter\":{\"SubLink\":{\"subLinkType\":\"ANY_SUBLINK\",\"testexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":34}},\"subselect\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":53}},\"location\":53}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"onek\",\"inh\":true,\"relpersistence\":\"p\",\"location\":66}}],\"whereClause\":{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"\\u003c\"}}],\"lexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":77}},\"rexpr\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":100}},\"location\":87}},\"location\":85}},\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}},\"location\":42}},\"location\":7}},\"location\":7}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"tenk1\",\"inh\":true,\"relpersistence\":\"p\",\"location\":98}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"sum\"}}],\"args\":[{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":11}}],\"agg_filter\":{\"SubLink\":{\"subLinkType\":\"ANY_SUBLINK\",\"testexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":34}},\"subselect\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":53}},\"location\":53}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"onek\",\"inh\":true,\"relpersistence\":\"p\",\"location\":66}}],\"whereClause\":{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"\\u003c\"}}],\"lexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":77}},\"rexpr\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":100}},\"location\":87}},\"location\":85}},\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}},\"location\":42}},\"location\":7}},\"location\":7}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"tenk1\",\"inh\":true,\"relpersistence\":\"p\",\"location\":98}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "select sum(unique1) FILTER (WHERE unique1 = ANY (SELECT unique1 FROM onek where unique1 < 100)) FROM tenk1", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"sum\"}}],\"args\":[{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":11}}],\"agg_filter\":{\"SubLink\":{\"subLinkType\":\"ANY_SUBLINK\",\"testexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":34}},\"operName\":[{\"String\":{\"str\":\"=\"}}],\"subselect\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":56}},\"location\":56}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"onek\",\"inh\":true,\"relpersistence\":\"p\",\"location\":69}}],\"whereClause\":{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"\\u003c\"}}],\"lexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":80}},\"rexpr\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":100}},\"location\":90}},\"location\":88}},\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}},\"location\":42}},\"location\":7}},\"location\":7}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"tenk1\",\"inh\":true,\"relpersistence\":\"p\",\"location\":101}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"sum\"}}],\"args\":[{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":11}}],\"agg_filter\":{\"SubLink\":{\"subLinkType\":\"ANY_SUBLINK\",\"testexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":34}},\"operName\":[{\"String\":{\"str\":\"=\"}}],\"subselect\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":56}},\"location\":56}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"onek\",\"inh\":true,\"relpersistence\":\"p\",\"location\":69}}],\"whereClause\":{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"\\u003c\"}}],\"lexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"unique1\"}}],\"location\":80}},\"rexpr\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":100}},\"location\":90}},\"location\":88}},\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}},\"location\":42}},\"location\":7}},\"location\":7}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"tenk1\",\"inh\":true,\"relpersistence\":\"p\",\"location\":101}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "CREATE FOREIGN TABLE films (code char(5) NOT NULL, title varchar(40) NOT NULL, did integer NOT NULL, date_prod date, kind varchar(10), len interval hour to minute) SERVER film_server;", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"CreateForeignTableStmt\":{\"base\":{\"relation\":{\"relname\":\"films\",\"inh\":true,\"relpersistence\":\"p\",\"location\":21},\"tableElts\":[{\"ColumnDef\":{\"colname\":\"code\",\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"bpchar\"}}],\"typmods\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":5}},\"location\":38}}],\"typemod\":-1,\"location\":33},\"is_local\":true,\"constraints\":[{\"Constraint\":{\"contype\":\"CONSTR_NOTNULL\",\"location\":41}}],\"location\":28}},{\"ColumnDef\":{\"colname\":\"title\",\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"varchar\"}}],\"typmods\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":40}},\"location\":65}}],\"typemod\":-1,\"location\":57},\"is_local\":true,\"constraints\":[{\"Constraint\":{\"contype\":\"CONSTR_NOTNULL\",\"location\":69}}],\"location\":51}},{\"ColumnDef\":{\"colname\":\"did\",\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"int4\"}}],\"typemod\":-1,\"location\":83},\"is_local\":true,\"constraints\":[{\"Constraint\":{\"contype\":\"CONSTR_NOTNULL\",\"location\":91}}],\"location\":79}},{\"ColumnDef\":{\"colname\":\"date_prod\",\"typeName\":{\"names\":[{\"String\":{\"str\":\"date\"}}],\"typemod\":-1,\"location\":111},\"is_local\":true,\"location\":101}},{\"ColumnDef\":{\"colname\":\"kind\",\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"varchar\"}}],\"typmods\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":10}},\"location\":130}}],\"typemod\":-1,\"location\":122},\"is_local\":true,\"location\":117}},{\"ColumnDef\":{\"colname\":\"len\",\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"interval\"}}],\"typmods\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":3072}},\"location\":148}}],\"typemod\":-1,\"location\":139},\"is_local\":true,\"location\":135}}],\"oncommit\":\"ONCOMMIT_NOOP\"},\"servername\":\"film_server\"}},\"stmt_len\":182}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"CreateForeignTableStmt\":{\"base\":{\"relation\":{\"relname\":\"films\",\"inh\":true,\"relpersistence\":\"p\",\"location\":21},\"tableElts\":[{\"ColumnDef\":{\"colname\":\"code\",\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"bpchar\"}}],\"typmods\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":5}},\"location\":38}}],\"typemod\":-1,\"location\":33},\"is_local\":true,\"constraints\":[{\"Constraint\":{\"contype\":\"CONSTR_NOTNULL\",\"location\":41}}],\"location\":28}},{\"ColumnDef\":{\"colname\":\"title\",\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"varchar\"}}],\"typmods\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":40}},\"location\":65}}],\"typemod\":-1,\"location\":57},\"is_local\":true,\"constraints\":[{\"Constraint\":{\"contype\":\"CONSTR_NOTNULL\",\"location\":69}}],\"location\":51}},{\"ColumnDef\":{\"colname\":\"did\",\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"int4\"}}],\"typemod\":-1,\"location\":83},\"is_local\":true,\"constraints\":[{\"Constraint\":{\"contype\":\"CONSTR_NOTNULL\",\"location\":91}}],\"location\":79}},{\"ColumnDef\":{\"colname\":\"date_prod\",\"typeName\":{\"names\":[{\"String\":{\"str\":\"date\"}}],\"typemod\":-1,\"location\":111},\"is_local\":true,\"location\":101}},{\"ColumnDef\":{\"colname\":\"kind\",\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"varchar\"}}],\"typmods\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":10}},\"location\":130}}],\"typemod\":-1,\"location\":122},\"is_local\":true,\"location\":117}},{\"ColumnDef\":{\"colname\":\"len\",\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"interval\"}}],\"typmods\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":3072}},\"location\":148}}],\"typemod\":-1,\"location\":139},\"is_local\":true,\"location\":135}}],\"oncommit\":\"ONCOMMIT_NOOP\"},\"servername\":\"film_server\"}},\"stmt_len\":182}]}", "CREATE FOREIGN TABLE ft1 () SERVER no_server", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"CreateForeignTableStmt\":{\"base\":{\"relation\":{\"relname\":\"ft1\",\"inh\":true,\"relpersistence\":\"p\",\"location\":21},\"oncommit\":\"ONCOMMIT_NOOP\"},\"servername\":\"no_server\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"CreateForeignTableStmt\":{\"base\":{\"relation\":{\"relname\":\"ft1\",\"inh\":true,\"relpersistence\":\"p\",\"location\":21},\"oncommit\":\"ONCOMMIT_NOOP\"},\"servername\":\"no_server\"}}}]}", "SELECT parse_ident(E'\"c\".X XXXX\002XXXXXX')", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"parse_ident\"}}],\"args\":[{\"A_Const\":{\"val\":{\"String\":{\"str\":\"\\\"c\\\".X XXXX\\u0002XXXXXX\"}},\"location\":19}}],\"location\":7}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"parse_ident\"}}],\"args\":[{\"A_Const\":{\"val\":{\"String\":{\"str\":\"\\\"c\\\".X XXXX\\u0002XXXXXX\"}},\"location\":19}}],\"location\":7}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "ALTER ROLE postgres LOGIN SUPERUSER PASSWORD 'xyz'", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"AlterRoleStmt\":{\"role\":{\"roletype\":\"ROLESPEC_CSTRING\",\"rolename\":\"postgres\",\"location\":11},\"options\":[{\"DefElem\":{\"defname\":\"canlogin\",\"arg\":{\"Integer\":{\"ival\":1}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":20}},{\"DefElem\":{\"defname\":\"superuser\",\"arg\":{\"Integer\":{\"ival\":1}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":26}},{\"DefElem\":{\"defname\":\"password\",\"arg\":{\"String\":{\"str\":\"xyz\"}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":36}}],\"action\":1}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"AlterRoleStmt\":{\"role\":{\"roletype\":\"ROLESPEC_CSTRING\",\"rolename\":\"postgres\",\"location\":11},\"options\":[{\"DefElem\":{\"defname\":\"canlogin\",\"arg\":{\"Integer\":{\"ival\":1}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":20}},{\"DefElem\":{\"defname\":\"superuser\",\"arg\":{\"Integer\":{\"ival\":1}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":26}},{\"DefElem\":{\"defname\":\"password\",\"arg\":{\"String\":{\"str\":\"xyz\"}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":36}}],\"action\":1}}}]}", "SELECT extract($1 FROM $2)", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"date_part\"}}],\"args\":[{\"ParamRef\":{\"number\":1,\"location\":15}},{\"ParamRef\":{\"number\":2,\"location\":23}}],\"location\":7}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"date_part\"}}],\"args\":[{\"ParamRef\":{\"number\":1,\"location\":15}},{\"ParamRef\":{\"number\":2,\"location\":23}}],\"location\":7}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "WITH w AS NOT MATERIALIZED (SELECT * FROM big_table) SELECT * FROM w LIMIT 1", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"A_Star\":{}}],\"location\":60}},\"location\":60}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"w\",\"inh\":true,\"relpersistence\":\"p\",\"location\":67}}],\"limitCount\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":75}},\"limitOption\":\"LIMIT_OPTION_COUNT\",\"withClause\":{\"ctes\":[{\"CommonTableExpr\":{\"ctename\":\"w\",\"ctematerialized\":\"CTEMaterializeNever\",\"ctequery\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"A_Star\":{}}],\"location\":35}},\"location\":35}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"big_table\",\"inh\":true,\"relpersistence\":\"p\",\"location\":42}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}},\"location\":5}}]},\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"A_Star\":{}}],\"location\":60}},\"location\":60}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"w\",\"inh\":true,\"relpersistence\":\"p\",\"location\":67}}],\"limitCount\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":75}},\"limitOption\":\"LIMIT_OPTION_COUNT\",\"withClause\":{\"ctes\":[{\"CommonTableExpr\":{\"ctename\":\"w\",\"ctematerialized\":\"CTEMaterializeNever\",\"ctequery\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"A_Star\":{}}],\"location\":35}},\"location\":35}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"big_table\",\"inh\":true,\"relpersistence\":\"p\",\"location\":42}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}},\"location\":5}}]},\"op\":\"SETOP_NONE\"}}}]}", "CREATE USER test PASSWORD $1", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"CreateRoleStmt\":{\"stmt_type\":\"ROLESTMT_USER\",\"role\":\"test\",\"options\":[{\"DefElem\":{\"defname\":\"password\",\"arg\":{\"ParamRef\":{\"number\":1,\"location\":26}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":17}}]}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"CreateRoleStmt\":{\"stmt_type\":\"ROLESTMT_USER\",\"role\":\"test\",\"options\":[{\"DefElem\":{\"defname\":\"password\",\"arg\":{\"ParamRef\":{\"number\":1,\"location\":26}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":17}}]}}}]}", "ALTER USER test ENCRYPTED PASSWORD $2", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"AlterRoleStmt\":{\"role\":{\"roletype\":\"ROLESPEC_CSTRING\",\"rolename\":\"test\",\"location\":11},\"options\":[{\"DefElem\":{\"defname\":\"password\",\"arg\":{\"ParamRef\":{\"number\":2,\"location\":35}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":16}}],\"action\":1}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"AlterRoleStmt\":{\"role\":{\"roletype\":\"ROLESPEC_CSTRING\",\"rolename\":\"test\",\"location\":11},\"options\":[{\"DefElem\":{\"defname\":\"password\",\"arg\":{\"ParamRef\":{\"number\":2,\"location\":35}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":16}}],\"action\":1}}}]}", "SET SCHEMA $3", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"VariableSetStmt\":{\"kind\":\"VAR_SET_VALUE\",\"name\":\"search_path\",\"args\":[{\"ParamRef\":{\"number\":3,\"location\":11}}]}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"VariableSetStmt\":{\"kind\":\"VAR_SET_VALUE\",\"name\":\"search_path\",\"args\":[{\"ParamRef\":{\"number\":3,\"location\":11}}]}}}]}", "SET ROLE $4", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"VariableSetStmt\":{\"kind\":\"VAR_SET_VALUE\",\"name\":\"role\",\"args\":[{\"ParamRef\":{\"number\":4,\"location\":9}}]}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"VariableSetStmt\":{\"kind\":\"VAR_SET_VALUE\",\"name\":\"role\",\"args\":[{\"ParamRef\":{\"number\":4,\"location\":9}}]}}}]}", "SET SESSION AUTHORIZATION $5", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"VariableSetStmt\":{\"kind\":\"VAR_SET_VALUE\",\"name\":\"session_authorization\",\"args\":[{\"ParamRef\":{\"number\":5,\"location\":26}}]}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"VariableSetStmt\":{\"kind\":\"VAR_SET_VALUE\",\"name\":\"session_authorization\",\"args\":[{\"ParamRef\":{\"number\":5,\"location\":26}}]}}}]}", "SELECT EXTRACT($1 FROM TIMESTAMP $2)", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"date_part\"}}],\"args\":[{\"ParamRef\":{\"number\":1,\"location\":15}},{\"TypeCast\":{\"arg\":{\"ParamRef\":{\"number\":2,\"location\":33}},\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"timestamp\"}}],\"typemod\":-1,\"location\":23},\"location\":-1}}],\"location\":7}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"date_part\"}}],\"args\":[{\"ParamRef\":{\"number\":1,\"location\":15}},{\"TypeCast\":{\"arg\":{\"ParamRef\":{\"number\":2,\"location\":33}},\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"timestamp\"}}],\"typemod\":-1,\"location\":23},\"location\":-1}}],\"location\":7}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "SELECT DATE $1", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"TypeCast\":{\"arg\":{\"ParamRef\":{\"number\":1,\"location\":12}},\"typeName\":{\"names\":[{\"String\":{\"str\":\"date\"}}],\"typemod\":-1,\"location\":7},\"location\":-1}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"TypeCast\":{\"arg\":{\"ParamRef\":{\"number\":1,\"location\":12}},\"typeName\":{\"names\":[{\"String\":{\"str\":\"date\"}}],\"typemod\":-1,\"location\":7},\"location\":-1}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "SELECT INTERVAL $1", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"TypeCast\":{\"arg\":{\"ParamRef\":{\"number\":1,\"location\":16}},\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"interval\"}}],\"typemod\":-1,\"location\":7},\"location\":-1}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"TypeCast\":{\"arg\":{\"ParamRef\":{\"number\":1,\"location\":16}},\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"interval\"}}],\"typemod\":-1,\"location\":7},\"location\":-1}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "SELECT INTERVAL $1 YEAR", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"TypeCast\":{\"arg\":{\"ParamRef\":{\"number\":1,\"location\":16}},\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"interval\"}}],\"typmods\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":4}},\"location\":19}}],\"typemod\":-1,\"location\":7},\"location\":-1}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"TypeCast\":{\"arg\":{\"ParamRef\":{\"number\":1,\"location\":16}},\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"interval\"}}],\"typmods\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":4}},\"location\":19}}],\"typemod\":-1,\"location\":7},\"location\":-1}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "SELECT INTERVAL (6) $1", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"TypeCast\":{\"arg\":{\"ParamRef\":{\"number\":1,\"location\":20}},\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"interval\"}}],\"typmods\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":32767}},\"location\":-1}},{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":6}},\"location\":17}}],\"typemod\":-1,\"location\":7},\"location\":-1}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"TypeCast\":{\"arg\":{\"ParamRef\":{\"number\":1,\"location\":20}},\"typeName\":{\"names\":[{\"String\":{\"str\":\"pg_catalog\"}},{\"String\":{\"str\":\"interval\"}}],\"typmods\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":32767}},\"location\":-1}},{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":6}},\"location\":17}}],\"typemod\":-1,\"location\":7},\"location\":-1}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "SET search_path = $1", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"VariableSetStmt\":{\"kind\":\"VAR_SET_VALUE\",\"name\":\"search_path\",\"args\":[{\"ParamRef\":{\"number\":1,\"location\":18}}]}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"VariableSetStmt\":{\"kind\":\"VAR_SET_VALUE\",\"name\":\"search_path\",\"args\":[{\"ParamRef\":{\"number\":1,\"location\":18}}]}}}]}", "ALTER ROLE postgres LOGIN SUPERUSER PASSWORD ?", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"AlterRoleStmt\":{\"role\":{\"roletype\":\"ROLESPEC_CSTRING\",\"rolename\":\"postgres\",\"location\":11},\"options\":[{\"DefElem\":{\"defname\":\"canlogin\",\"arg\":{\"Integer\":{\"ival\":1}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":20}},{\"DefElem\":{\"defname\":\"superuser\",\"arg\":{\"Integer\":{\"ival\":1}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":26}},{\"DefElem\":{\"defname\":\"password\",\"arg\":{\"ParamRef\":{\"location\":45}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":36}}],\"action\":1}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"AlterRoleStmt\":{\"role\":{\"roletype\":\"ROLESPEC_CSTRING\",\"rolename\":\"postgres\",\"location\":11},\"options\":[{\"DefElem\":{\"defname\":\"canlogin\",\"arg\":{\"Integer\":{\"ival\":1}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":20}},{\"DefElem\":{\"defname\":\"superuser\",\"arg\":{\"Integer\":{\"ival\":1}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":26}},{\"DefElem\":{\"defname\":\"password\",\"arg\":{\"ParamRef\":{\"location\":45}},\"defaction\":\"DEFELEM_UNSPEC\",\"location\":36}}],\"action\":1}}}]}", "WITH a AS (SELECT * FROM x WHERE x.y = ? AND x.z = 1) SELECT * FROM a WHERE b = 5", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"A_Star\":{}}],\"location\":61}},\"location\":61}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"a\",\"inh\":true,\"relpersistence\":\"p\",\"location\":68}}],\"whereClause\":{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"=\"}}],\"lexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"b\"}}],\"location\":76}},\"rexpr\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":5}},\"location\":80}},\"location\":78}},\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"withClause\":{\"ctes\":[{\"CommonTableExpr\":{\"ctename\":\"a\",\"ctematerialized\":\"CTEMaterializeDefault\",\"ctequery\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"A_Star\":{}}],\"location\":18}},\"location\":18}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"x\",\"inh\":true,\"relpersistence\":\"p\",\"location\":25}}],\"whereClause\":{\"BoolExpr\":{\"boolop\":\"AND_EXPR\",\"args\":[{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"=\"}}],\"lexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"x\"}},{\"String\":{\"str\":\"y\"}}],\"location\":33}},\"rexpr\":{\"ParamRef\":{\"location\":39}},\"location\":37}},{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"=\"}}],\"lexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"x\"}},{\"String\":{\"str\":\"z\"}}],\"location\":45}},\"rexpr\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":51}},\"location\":49}}],\"location\":41}},\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}},\"location\":5}}]},\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"A_Star\":{}}],\"location\":61}},\"location\":61}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"a\",\"inh\":true,\"relpersistence\":\"p\",\"location\":68}}],\"whereClause\":{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"=\"}}],\"lexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"b\"}}],\"location\":76}},\"rexpr\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":5}},\"location\":80}},\"location\":78}},\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"withClause\":{\"ctes\":[{\"CommonTableExpr\":{\"ctename\":\"a\",\"ctematerialized\":\"CTEMaterializeDefault\",\"ctequery\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"A_Star\":{}}],\"location\":18}},\"location\":18}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"x\",\"inh\":true,\"relpersistence\":\"p\",\"location\":25}}],\"whereClause\":{\"BoolExpr\":{\"boolop\":\"AND_EXPR\",\"args\":[{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"=\"}}],\"lexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"x\"}},{\"String\":{\"str\":\"y\"}}],\"location\":33}},\"rexpr\":{\"ParamRef\":{\"location\":39}},\"location\":37}},{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"=\"}}],\"lexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"x\"}},{\"String\":{\"str\":\"z\"}}],\"location\":45}},\"rexpr\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":51}},\"location\":49}}],\"location\":41}},\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}},\"location\":5}}]},\"op\":\"SETOP_NONE\"}}}]}", "SELECT count(*) from testjsonb WHERE j->'array' ? 'bar'", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"count\"}}],\"agg_star\":true,\"location\":7}},\"location\":7}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"testjsonb\",\"inh\":true,\"relpersistence\":\"p\",\"location\":21}}],\"whereClause\":{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"?\"}}],\"lexpr\":{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"-\\u003e\"}}],\"lexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"j\"}}],\"location\":38}},\"rexpr\":{\"A_Const\":{\"val\":{\"String\":{\"str\":\"array\"}},\"location\":41}},\"location\":39}},\"rexpr\":{\"A_Const\":{\"val\":{\"String\":{\"str\":\"bar\"}},\"location\":51}},\"location\":49}},\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"count\"}}],\"agg_star\":true,\"location\":7}},\"location\":7}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"testjsonb\",\"inh\":true,\"relpersistence\":\"p\",\"location\":21}}],\"whereClause\":{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"?\"}}],\"lexpr\":{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"-\\u003e\"}}],\"lexpr\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"j\"}}],\"location\":38}},\"rexpr\":{\"A_Const\":{\"val\":{\"String\":{\"str\":\"array\"}},\"location\":41}},\"location\":39}},\"rexpr\":{\"A_Const\":{\"val\":{\"String\":{\"str\":\"bar\"}},\"location\":51}},\"location\":49}},\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "SELECT DISTINCT a FROM b", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"distinctClause\":[{}],\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"a\"}}],\"location\":16}},\"location\":16}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"b\",\"inh\":true,\"relpersistence\":\"p\",\"location\":23}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"distinctClause\":[{}],\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"String\":{\"str\":\"a\"}}],\"location\":16}},\"location\":16}}],\"fromClause\":[{\"RangeVar\":{\"relname\":\"b\",\"inh\":true,\"relpersistence\":\"p\",\"location\":23}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "SELECT * FROM generate_series(1, 2)", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"A_Star\":{}}],\"location\":7}},\"location\":7}}],\"fromClause\":[{\"RangeFunction\":{\"functions\":[{\"List\":{\"items\":[{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"generate_series\"}}],\"args\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":30}},{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":2}},\"location\":33}}],\"location\":14}},{}]}}]}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"ColumnRef\":{\"fields\":[{\"A_Star\":{}}],\"location\":7}},\"location\":7}}],\"fromClause\":[{\"RangeFunction\":{\"functions\":[{\"List\":{\"items\":[{\"FuncCall\":{\"funcname\":[{\"String\":{\"str\":\"generate_series\"}}],\"args\":[{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":30}},{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":2}},\"location\":33}}],\"location\":14}},{}]}}]}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}", "SELECT 1 + 1", - "{\"version\":130003,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"+\"}}],\"lexpr\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":7}},\"rexpr\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":11}},\"location\":9}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}" + "{\"version\":130008,\"stmts\":[{\"stmt\":{\"SelectStmt\":{\"targetList\":[{\"ResTarget\":{\"val\":{\"A_Expr\":{\"kind\":\"AEXPR_OP\",\"name\":[{\"String\":{\"str\":\"+\"}}],\"lexpr\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":7}},\"rexpr\":{\"A_Const\":{\"val\":{\"Integer\":{\"ival\":1}},\"location\":11}},\"location\":9}},\"location\":7}}],\"limitOption\":\"LIMIT_OPTION_DEFAULT\",\"op\":\"SETOP_NONE\"}}}]}" }; size_t testsLength = __LINE__ - 4; diff --git a/test/sql/postgres_regress/aggregates.sql b/test/sql/postgres_regress/aggregates.sql index 044d5155..d61359fb 100644 --- a/test/sql/postgres_regress/aggregates.sql +++ b/test/sql/postgres_regress/aggregates.sql @@ -660,6 +660,17 @@ select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), generate_series(1,2) i; +-- check handling of bare boolean Var in FILTER +select max(0) filter (where b1) from bool_test; +select (select max(0) filter (where b1)) from bool_test; + +-- check for correct detection of nested-aggregate errors in FILTER +select max(unique1) filter (where sum(ten) > 0) from tenk1; +select (select max(unique1) filter (where sum(ten) > 0) from int8_tbl) from tenk1; +select max(unique1) filter (where bool_or(ten > 0)) from tenk1; +select (select max(unique1) filter (where bool_or(ten > 0)) from int8_tbl) from tenk1; + + -- ordered-set aggregates select p, percentile_cont(p) within group (order by x::float8) diff --git a/test/sql/postgres_regress/alter_table.sql b/test/sql/postgres_regress/alter_table.sql index 4cc55d85..4884476c 100644 --- a/test/sql/postgres_regress/alter_table.sql +++ b/test/sql/postgres_regress/alter_table.sql @@ -158,6 +158,10 @@ ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS -1; DROP TABLE attmp; +-- fails with incorrect object type +CREATE VIEW at_v1 AS SELECT 1 as a; +ALTER TABLE at_v1 ALTER COLUMN a SET STATISTICS 0; +DROP VIEW at_v1; -- -- rename - check on both non-temp and temp tables @@ -227,6 +231,37 @@ SET ROLE regress_alter_table_user1; ALTER INDEX onek_unique1 RENAME TO fail; -- permission denied RESET ROLE; +-- rename statements with mismatching statement and object types +CREATE TABLE alter_idx_rename_test (a INT); +CREATE INDEX alter_idx_rename_test_idx ON alter_idx_rename_test (a); +CREATE TABLE alter_idx_rename_test_parted (a INT) PARTITION BY LIST (a); +CREATE INDEX alter_idx_rename_test_parted_idx ON alter_idx_rename_test_parted (a); +BEGIN; +ALTER INDEX alter_idx_rename_test RENAME TO alter_idx_rename_test_2; +ALTER INDEX alter_idx_rename_test_parted RENAME TO alter_idx_rename_test_parted_2; +SELECT relation::regclass, mode FROM pg_locks +WHERE pid = pg_backend_pid() AND locktype = 'relation' + AND relation::regclass::text LIKE 'alter\_idx%' +ORDER BY relation::regclass::text COLLATE "C"; +COMMIT; +BEGIN; +ALTER INDEX alter_idx_rename_test_idx RENAME TO alter_idx_rename_test_idx_2; +ALTER INDEX alter_idx_rename_test_parted_idx RENAME TO alter_idx_rename_test_parted_idx_2; +SELECT relation::regclass, mode FROM pg_locks +WHERE pid = pg_backend_pid() AND locktype = 'relation' + AND relation::regclass::text LIKE 'alter\_idx%' +ORDER BY relation::regclass::text COLLATE "C"; +COMMIT; +BEGIN; +ALTER TABLE alter_idx_rename_test_idx_2 RENAME TO alter_idx_rename_test_idx_3; +ALTER TABLE alter_idx_rename_test_parted_idx_2 RENAME TO alter_idx_rename_test_parted_idx_3; +SELECT relation::regclass, mode FROM pg_locks +WHERE pid = pg_backend_pid() AND locktype = 'relation' + AND relation::regclass::text LIKE 'alter\_idx%' +ORDER BY relation::regclass::text COLLATE "C"; +COMMIT; +DROP TABLE alter_idx_rename_test_2; + -- renaming views CREATE VIEW attmp_view (unique1) AS SELECT unique1 FROM tenk1; ALTER TABLE attmp_view RENAME TO attmp_view_new; @@ -1389,10 +1424,21 @@ create table skip_wal_skip_rewrite_index (c varchar(10) primary key); alter table skip_wal_skip_rewrite_index alter c type varchar(20); commit; --- table's row type -create table tab1 (a int, b text); -create table tab2 (x int, y tab1); -alter table tab1 alter column b type varchar; -- fails +-- We disallow changing table's row type if it's used for storage +create table at_tab1 (a int, b text); +create table at_tab2 (x int, y at_tab1); +alter table at_tab1 alter column b type varchar; -- fails +drop table at_tab2; +-- Use of row type in an expression is defended differently +create table at_tab2 (x int, y text, check((x,y)::at_tab1 = (1,'42')::at_tab1)); +alter table at_tab1 alter column b type varchar; -- allowed, but ... +insert into at_tab2 values(1,'42'); -- ... this will fail +drop table at_tab1, at_tab2; +-- Check it for a partitioned table, too +create table at_tab1 (a int, b text) partition by list(a); +create table at_tab2 (x int, y at_tab1); +alter table at_tab1 alter column b type varchar; -- fails +drop table at_tab1, at_tab2; -- Alter column type that's part of a partitioned index create table at_partitioned (a int, b text) partition by range (a); @@ -2640,6 +2686,11 @@ ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, R ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 3, REMAINDER 2); DROP TABLE fail_part; +-- fails with incorrect object type +CREATE VIEW at_v1 AS SELECT 1 as a; +ALTER TABLE at_v1 ATTACH PARTITION dummy default; +DROP VIEW at_v1; + -- -- DETACH PARTITION -- @@ -2914,3 +2965,22 @@ select indexrelid::regclass, indisclustered from pg_index where indrelid = 'alttype_cluster'::regclass order by indexrelid::regclass::text; drop table alttype_cluster; + +-- +-- Check that attaching or detaching a partitioned partition correctly leads +-- to its partitions' constraint being updated to reflect the parent's +-- newly added/removed constraint +create table target_parted (a int, b int) partition by list (a); +create table attach_parted (a int, b int) partition by list (b); +create table attach_parted_part1 partition of attach_parted for values in (1); +-- insert a row directly into the leaf partition so that its partition +-- constraint is built and stored in the relcache +insert into attach_parted_part1 values (1, 1); +-- the following better invalidate the partition constraint of the leaf +-- partition too... +alter table target_parted attach partition attach_parted for values in (1); +-- ...such that the following insert fails +insert into attach_parted_part1 values (2, 1); +-- ...and doesn't when the partition is detached along with its own partition +alter table target_parted detach partition attach_parted; +insert into attach_parted_part1 values (2, 1); diff --git a/test/sql/postgres_regress/arrays.sql b/test/sql/postgres_regress/arrays.sql index 25dd4e2c..bf9319c7 100644 --- a/test/sql/postgres_regress/arrays.sql +++ b/test/sql/postgres_regress/arrays.sql @@ -311,6 +311,8 @@ SELECT ARRAY[[['hello','world']]] || ARRAY[[['happy','birthday']]] AS "ARRAY"; SELECT ARRAY[[1,2],[3,4]] || ARRAY[5,6] AS "{{1,2},{3,4},{5,6}}"; SELECT ARRAY[0,0] || ARRAY[1,1] || ARRAY[2,2] AS "{0,0,1,1,2,2}"; SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}"; +SELECT array_agg(x) || array_agg(x) FROM (VALUES (ROW(1,2)), (ROW(3,4))) v(x); +SELECT ROW(1,2) || array_agg(x) FROM (VALUES (ROW(3,4)), (ROW(5,6))) v(x); SELECT * FROM array_op_test WHERE i @> '{32}' ORDER BY seqno; SELECT * FROM array_op_test WHERE i && '{32}' ORDER BY seqno; diff --git a/test/sql/postgres_regress/btree_index.sql b/test/sql/postgres_regress/btree_index.sql index c60312db..c3450224 100644 --- a/test/sql/postgres_regress/btree_index.sql +++ b/test/sql/postgres_regress/btree_index.sql @@ -172,3 +172,14 @@ INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,1000) i; -- Test unsupported btree opclass parameters create index on btree_tall_tbl (id int4_ops(foo=1)); + +-- Test case of ALTER INDEX with abuse of column names for indexes. +-- This grammar is not officially supported, but the parser allows it. +CREATE INDEX btree_tall_idx2 ON btree_tall_tbl (id); +ALTER INDEX btree_tall_idx2 ALTER COLUMN id SET (n_distinct=100); +DROP INDEX btree_tall_idx2; +-- Partitioned index +CREATE TABLE btree_part (id int4) PARTITION BY RANGE (id); +CREATE INDEX btree_part_idx ON btree_part(id); +ALTER INDEX btree_part_idx ALTER COLUMN id SET (n_distinct=100); +DROP TABLE btree_part; diff --git a/test/sql/postgres_regress/cluster.sql b/test/sql/postgres_regress/cluster.sql index aee9cf83..99ee533c 100644 --- a/test/sql/postgres_regress/cluster.sql +++ b/test/sql/postgres_regress/cluster.sql @@ -245,6 +245,9 @@ COMMIT; -- and after clustering on clstr_expression_minus_a CLUSTER clstr_expression USING clstr_expression_minus_a; +WITH rows AS + (SELECT ctid, lag(a) OVER (ORDER BY ctid) AS la, a FROM clstr_expression) +SELECT * FROM rows WHERE la < a; BEGIN; SET LOCAL enable_seqscan = false; EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'; @@ -255,6 +258,9 @@ COMMIT; -- and after clustering on clstr_expression_upper_b CLUSTER clstr_expression USING clstr_expression_upper_b; +WITH rows AS + (SELECT ctid, lag(b) OVER (ORDER BY ctid) AS lb, b FROM clstr_expression) +SELECT * FROM rows WHERE upper(lb) > upper(b); BEGIN; SET LOCAL enable_seqscan = false; EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'; diff --git a/test/sql/postgres_regress/create_index.sql b/test/sql/postgres_regress/create_index.sql index c0392f05..13690630 100644 --- a/test/sql/postgres_regress/create_index.sql +++ b/test/sql/postgres_regress/create_index.sql @@ -255,6 +255,10 @@ EXPLAIN (COSTS OFF) SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10; SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10; +EXPLAIN (COSTS OFF) +SELECT point(x,x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x,x) LIMIT 1) as c FROM generate_series(0,10,1) x; +SELECT point(x,x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x,x) LIMIT 1) as c FROM generate_series(0,10,1) x; + -- Now check the results from bitmap indexscan SET enable_seqscan = OFF; SET enable_indexscan = OFF; @@ -481,11 +485,22 @@ CREATE INDEX CONCURRENTLY concur_index4 on concur_heap(f2) WHERE f1='a'; CREATE INDEX CONCURRENTLY concur_index5 on concur_heap(f2) WHERE f1='x'; -- here we also check that you can default the index name CREATE INDEX CONCURRENTLY on concur_heap((f2||f1)); - -- You can't do a concurrent index build in a transaction BEGIN; CREATE INDEX CONCURRENTLY concur_index7 ON concur_heap(f1); COMMIT; +-- test where predicate is able to do a transactional update during +-- a concurrent build before switching pg_index state flags. +CREATE FUNCTION predicate_stable() RETURNS bool IMMUTABLE +LANGUAGE plpgsql AS $$ +BEGIN + EXECUTE 'SELECT txid_current()'; + RETURN true; +END; $$; +CREATE INDEX CONCURRENTLY concur_index8 ON concur_heap (f1) + WHERE predicate_stable(); +DROP INDEX concur_index8; +DROP FUNCTION predicate_stable(); -- But you can do a regular index build in a transaction BEGIN; @@ -877,6 +892,15 @@ REINDEX TABLE CONCURRENTLY concur_replident; SELECT indexrelid::regclass, indisreplident FROM pg_index WHERE indrelid = 'concur_replident'::regclass; DROP TABLE concur_replident; +-- Check that opclass parameters are preserved +CREATE TABLE concur_appclass_tab(i tsvector, j tsvector, k tsvector); +CREATE INDEX concur_appclass_ind on concur_appclass_tab + USING gist (i tsvector_ops (siglen='1000'), j tsvector_ops (siglen='500')); +CREATE INDEX concur_appclass_ind_2 on concur_appclass_tab + USING gist (k tsvector_ops (siglen='300'), j tsvector_ops); +REINDEX TABLE CONCURRENTLY concur_appclass_tab; +\d concur_appclass_tab +DROP TABLE concur_appclass_tab; -- Partitions -- Create some partitioned tables diff --git a/test/sql/postgres_regress/create_view.sql b/test/sql/postgres_regress/create_view.sql index e7af0bf2..638449cf 100644 --- a/test/sql/postgres_regress/create_view.sql +++ b/test/sql/postgres_regress/create_view.sql @@ -515,9 +515,11 @@ begin; -- this perhaps should be rejected, but it isn't: alter table tt14t drop column f3; --- f3 is still in the view ... +-- column f3 is still in the view, sort of ... select pg_get_viewdef('tt14v', true); --- but will fail at execution +-- ... and you can even EXPLAIN it ... +explain (verbose, costs off) select * from tt14v; +-- but it will fail at execution select f1, f4 from tt14v; select * from tt14v; @@ -554,6 +556,11 @@ select * from tt17v; select pg_get_viewdef('tt17v', true); select * from int8_tbl i where i.* in (values(i.*::int8_tbl)); +create table tt15v_log(o tt15v, n tt15v, incr bool); +create rule updlog as on update to tt15v do also + insert into tt15v_log values(old, new, row(old,old) < row(new,new)); +\d+ tt15v + -- check unique-ification of overlength names create view tt18v as diff --git a/test/sql/postgres_regress/dbsize.sql b/test/sql/postgres_regress/dbsize.sql index d10a4d7f..6a45c5eb 100644 --- a/test/sql/postgres_regress/dbsize.sql +++ b/test/sql/postgres_regress/dbsize.sql @@ -11,6 +11,22 @@ SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM (1000000000.5::numeric), (1000000000000.5::numeric), (1000000000000000.5::numeric)) x(size); +-- test where units change up +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10239::bigint), (10240::bigint), + (10485247::bigint), (10485248::bigint), + (10736893951::bigint), (10736893952::bigint), + (10994579406847::bigint), (10994579406848::bigint), + (11258449312612351::bigint), (11258449312612352::bigint)) x(size); + +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10239::numeric), (10240::numeric), + (10485247::numeric), (10485248::numeric), + (10736893951::numeric), (10736893952::numeric), + (10994579406847::numeric), (10994579406848::numeric), + (11258449312612351::numeric), (11258449312612352::numeric)) x(size); + +-- pg_size_bytes() tests SELECT size, pg_size_bytes(size) FROM (VALUES ('1'), ('123bytes'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '), ('1TB'), ('3000 TB'), ('1e6 MB')) x(size); diff --git a/test/sql/postgres_regress/domain.sql b/test/sql/postgres_regress/domain.sql index 1291d550..d19e2bdf 100644 --- a/test/sql/postgres_regress/domain.sql +++ b/test/sql/postgres_regress/domain.sql @@ -155,6 +155,15 @@ create rule silly as on delete to dcomptable do instead update dcomptable set d1.r = (d1).r - 1, d1.i = (d1).i + 1 where (d1).i > 0; \d+ dcomptable +create function makedcomp(r float8, i float8) returns dcomptype +as 'select row(r, i)' language sql; + +select makedcomp(1,2); +select makedcomp(2,1); -- fail +select * from makedcomp(1,2) m; +select m, m is not null from makedcomp(1,2) m; + +drop function makedcomp(float8, float8); drop table dcomptable; drop type comptype cascade; @@ -268,6 +277,23 @@ drop table dposintatable; drop domain posint cascade; +-- Test arrays over domains of composite + +create type comptype as (cf1 int, cf2 int); +create domain dcomptype as comptype check ((value).cf1 > 0); + +create table dcomptable (f1 dcomptype[]); +insert into dcomptable values (null); +update dcomptable set f1[1].cf2 = 5; +table dcomptable; +update dcomptable set f1[1].cf1 = -1; -- fail +update dcomptable set f1[1].cf1 = 1; +table dcomptable; + +drop table dcomptable; +drop type comptype cascade; + + -- Test not-null restrictions create domain dnotnull varchar(15) NOT NULL; diff --git a/test/sql/postgres_regress/errors.sql b/test/sql/postgres_regress/errors.sql index 66a56b28..a7fcf72d 100644 --- a/test/sql/postgres_regress/errors.sql +++ b/test/sql/postgres_regress/errors.sql @@ -37,6 +37,10 @@ select * from pg_database where pg_database.datname = nonesuch; -- bad attribute name in select distinct on select distinct on (foobar) * from pg_database; +-- grouping with FOR UPDATE +select null from pg_database group by datname for update; +select null from pg_database group by grouping sets (()) for update; + -- -- DELETE diff --git a/test/sql/postgres_regress/event_trigger.sql b/test/sql/postgres_regress/event_trigger.sql index e79c5f0b..e9dd0b47 100644 --- a/test/sql/postgres_regress/event_trigger.sql +++ b/test/sql/postgres_regress/event_trigger.sql @@ -273,6 +273,7 @@ DROP ROLE regress_evt_user; DROP EVENT TRIGGER regress_event_trigger_drop_objects; DROP EVENT TRIGGER undroppable; +-- Event triggers on relations. CREATE OR REPLACE FUNCTION event_trigger_report_dropped() RETURNS event_trigger LANGUAGE plpgsql @@ -291,10 +292,28 @@ BEGIN END; $$; CREATE EVENT TRIGGER regress_event_trigger_report_dropped ON sql_drop EXECUTE PROCEDURE event_trigger_report_dropped(); +CREATE OR REPLACE FUNCTION event_trigger_report_end() + RETURNS event_trigger + LANGUAGE plpgsql +AS $$ +DECLARE r RECORD; +BEGIN + FOR r IN SELECT * FROM pg_event_trigger_ddl_commands() + LOOP + RAISE NOTICE 'END: command_tag=% type=% identity=%', + r.command_tag, r.object_type, r.object_identity; + END LOOP; +EXCEPTION WHEN SQLSTATE 'XX000' THEN + RAISE NOTICE 'END: got internal exception'; +END; $$; +CREATE EVENT TRIGGER regress_event_trigger_report_end ON ddl_command_end + EXECUTE PROCEDURE event_trigger_report_end(); + CREATE SCHEMA evttrig - CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two') + CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two', col_c SERIAL) CREATE INDEX one_idx ON one (col_b) - CREATE TABLE two (col_c INTEGER CHECK (col_c > 0) REFERENCES one DEFAULT 42); + CREATE TABLE two (col_c INTEGER CHECK (col_c > 0) REFERENCES one DEFAULT 42) + CREATE TABLE id (col_d int NOT NULL GENERATED ALWAYS AS IDENTITY); -- Partitioned tables with a partitioned index CREATE TABLE evttrig.parted ( @@ -312,11 +331,20 @@ CREATE TABLE evttrig.part_15_20 PARTITION OF evttrig.part_10_20 (id) ALTER TABLE evttrig.two DROP COLUMN col_c; ALTER TABLE evttrig.one ALTER COLUMN col_b DROP DEFAULT; ALTER TABLE evttrig.one DROP CONSTRAINT one_pkey; +ALTER TABLE evttrig.one DROP COLUMN col_c; +ALTER TABLE evttrig.id ALTER COLUMN col_d SET DATA TYPE bigint; +ALTER TABLE evttrig.id ALTER COLUMN col_d DROP IDENTITY, + ALTER COLUMN col_d SET DATA TYPE int; DROP INDEX evttrig.one_idx; DROP SCHEMA evttrig CASCADE; DROP TABLE a_temp_tbl; +-- CREATE OPERATOR CLASS without FAMILY clause should report +-- both CREATE OPERATOR FAMILY and CREATE OPERATOR CLASS +CREATE OPERATOR CLASS evttrigopclass FOR TYPE int USING btree AS STORAGE int; + DROP EVENT TRIGGER regress_event_trigger_report_dropped; +DROP EVENT TRIGGER regress_event_trigger_report_end; -- only allowed from within an event trigger function, should fail select pg_event_trigger_table_rewrite_oid(); diff --git a/test/sql/postgres_regress/expressions.sql b/test/sql/postgres_regress/expressions.sql index 1ca8bb15..86f20ef5 100644 --- a/test/sql/postgres_regress/expressions.sql +++ b/test/sql/postgres_regress/expressions.sql @@ -65,3 +65,55 @@ select count(*) from date_tbl where f1 not between symmetric '1997-01-01' and '1998-01-01'; select count(*) from date_tbl where f1 not between symmetric '1997-01-01' and '1998-01-01'; + + +-- +-- Test parsing of a no-op cast to a type with unspecified typmod +-- +begin; + +create table numeric_tbl (f1 numeric(18,3), f2 numeric); + +create view numeric_view as + select + f1, f1::numeric(16,4) as f1164, f1::numeric as f1n, + f2, f2::numeric(16,4) as f2164, f2::numeric as f2n + from numeric_tbl; + +\d+ numeric_view + +explain (verbose, costs off) select * from numeric_view; + +-- bpchar, lacking planner support for its length coercion function, +-- could behave differently + +create table bpchar_tbl (f1 character(16) unique, f2 bpchar); + +create view bpchar_view as + select + f1, f1::character(14) as f114, f1::bpchar as f1n, + f2, f2::character(14) as f214, f2::bpchar as f2n + from bpchar_tbl; + +\d+ bpchar_view + +explain (verbose, costs off) select * from bpchar_view + where f1::bpchar = 'foo'; + +rollback; + + +-- +-- Ordinarily, IN/NOT IN can be converted to a ScalarArrayOpExpr +-- with a suitably-chosen array type. +-- +explain (verbose, costs off) +select random() IN (1, 4, 8.0); +explain (verbose, costs off) +select random()::int IN (1, 4, 8.0); +-- However, if there's not a common supertype for the IN elements, +-- we should instead try to produce "x = v1 OR x = v2 OR ...". +-- In most cases that'll fail for lack of all the requisite = operators, +-- but it can succeed sometimes. So this should complain about lack of +-- an = operator, not about cast failure. +select '(0,0)'::point in ('(0,0,0,0)'::box, point(0,0)); diff --git a/test/sql/postgres_regress/fast_default.sql b/test/sql/postgres_regress/fast_default.sql index 4589b9e5..16a3b7ca 100644 --- a/test/sql/postgres_regress/fast_default.sql +++ b/test/sql/postgres_regress/fast_default.sql @@ -524,8 +524,22 @@ SET LOCAL enable_seqscan = false; SELECT * FROM t WHERE a IS NULL; ROLLBACK; +-- verify that a default set on a non-plain table doesn't set a missing +-- value on the attribute +CREATE FOREIGN DATA WRAPPER dummy; +CREATE SERVER s0 FOREIGN DATA WRAPPER dummy; +CREATE FOREIGN TABLE ft1 (c1 integer NOT NULL) SERVER s0; +ALTER FOREIGN TABLE ft1 ADD COLUMN c8 integer DEFAULT 0; +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10); +SELECT count(*) + FROM pg_attribute + WHERE attrelid = 'ft1'::regclass AND + (attmissingval IS NOT NULL OR atthasmissing); -- cleanup +DROP FOREIGN TABLE ft1; +DROP SERVER s0; +DROP FOREIGN DATA WRAPPER dummy; DROP TABLE vtype; DROP TABLE vtype2; DROP TABLE follower; diff --git a/test/sql/postgres_regress/foreign_data.sql b/test/sql/postgres_regress/foreign_data.sql index 73f9f621..279786f4 100644 --- a/test/sql/postgres_regress/foreign_data.sql +++ b/test/sql/postgres_regress/foreign_data.sql @@ -408,6 +408,7 @@ ALTER FOREIGN TABLE ft1 DROP COLUMN IF EXISTS no_column; ALTER FOREIGN TABLE ft1 DROP COLUMN c9; ALTER FOREIGN TABLE ft1 SET SCHEMA foreign_schema; ALTER FOREIGN TABLE ft1 SET TABLESPACE ts; -- ERROR +ALTER FOREIGN TABLE foreign_schema.ft1 SET TABLESPACE ts; -- ERROR ALTER FOREIGN TABLE foreign_schema.ft1 RENAME c1 TO foreign_column_1; ALTER FOREIGN TABLE foreign_schema.ft1 RENAME TO foreign_table_1; \d foreign_schema.foreign_table_1 diff --git a/test/sql/postgres_regress/generated.sql b/test/sql/postgres_regress/generated.sql index 5400510e..58a7d410 100644 --- a/test/sql/postgres_regress/generated.sql +++ b/test/sql/postgres_regress/generated.sql @@ -17,6 +17,9 @@ CREATE TABLE gtest_err_1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) S -- references to other generated columns, including self-references CREATE TABLE gtest_err_2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STORED); CREATE TABLE gtest_err_2b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED, c int GENERATED ALWAYS AS (b * 3) STORED); +-- a whole-row var is a self-reference on steroids, so disallow that too +CREATE TABLE gtest_err_2c (a int PRIMARY KEY, + b int GENERATED ALWAYS AS (num_nulls(gtest_err_2c)) STORED); -- invalid reference CREATE TABLE gtest_err_3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STORED); @@ -29,6 +32,7 @@ CREATE TABLE gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ALWAYS A CREATE TABLE gtest_err_5b (a int PRIMARY KEY, b int GENERATED ALWAYS AS identity GENERATED ALWAYS AS (a * 2) STORED); -- reference to system column not allowed in generated column +-- (except tableoid, which we test below) CREATE TABLE gtest_err_6a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37) STORED); -- various prohibited constructs @@ -201,9 +205,11 @@ DROP TYPE double_int; -- using tableoid is allowed CREATE TABLE gtest_tableoid ( a int PRIMARY KEY, - b bool GENERATED ALWAYS AS (tableoid <> 0) STORED + b bool GENERATED ALWAYS AS (tableoid = 'gtest_tableoid'::regclass) STORED ); INSERT INTO gtest_tableoid VALUES (1), (2); +ALTER TABLE gtest_tableoid ADD COLUMN + c regclass GENERATED ALWAYS AS (tableoid) STORED; SELECT * FROM gtest_tableoid; -- drop column behavior diff --git a/test/sql/postgres_regress/gist.sql b/test/sql/postgres_regress/gist.sql index b9d398ea..d94a0bb2 100644 --- a/test/sql/postgres_regress/gist.sql +++ b/test/sql/postgres_regress/gist.sql @@ -142,6 +142,33 @@ and p <@ box(point(5,5), point(6, 6)); drop index gist_tbl_multi_index; +-- Test that we don't try to return the value of a non-returnable +-- column in an index-only scan. (This isn't GIST-specific, but +-- it only applies to index AMs that can return some columns and not +-- others, so GIST with appropriate opclasses is a convenient test case.) +create index gist_tbl_multi_index on gist_tbl using gist (circle(p,1), p); +explain (verbose, costs off) +select circle(p,1) from gist_tbl +where p <@ box(point(5, 5), point(5.3, 5.3)); +select circle(p,1) from gist_tbl +where p <@ box(point(5, 5), point(5.3, 5.3)); + +-- Similarly, test that index rechecks involving a non-returnable column +-- are done correctly. +explain (verbose, costs off) +select p from gist_tbl where circle(p,1) @> circle(point(0,0),0.95); +select p from gist_tbl where circle(p,1) @> circle(point(0,0),0.95); + +-- Also check that use_physical_tlist doesn't trigger in such cases. +explain (verbose, costs off) +select count(*) from gist_tbl; +select count(*) from gist_tbl; + +-- This case isn't supported, but it should at least EXPLAIN correctly. +explain (verbose, costs off) +select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1; +select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1; + -- Clean up reset enable_seqscan; reset enable_bitmapscan; diff --git a/test/sql/postgres_regress/groupingsets.sql b/test/sql/postgres_regress/groupingsets.sql index 18ae803e..3f9e3986 100644 --- a/test/sql/postgres_regress/groupingsets.sql +++ b/test/sql/postgres_regress/groupingsets.sql @@ -188,6 +188,29 @@ select * from ( ) ss where x = 1 and q1 = 123; +-- check handling of pulled-up SubPlan in GROUPING() argument (bug #17479) +explain (verbose, costs off) +select grouping(ss.x) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x; + +select grouping(ss.x) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x; + +explain (verbose, costs off) +select (select grouping(ss.x)) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x; + +select (select grouping(ss.x)) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x; + -- simple rescan tests select a, b, sum(v.x) @@ -529,4 +552,13 @@ set work_mem to default; drop table gs_group_1; drop table gs_hash_1; +-- test handling of outer GroupingFunc within subqueries +explain (costs off) +select (select grouping(v1)) from (values ((select 1))) v(v1) group by cube(v1); +select (select grouping(v1)) from (values ((select 1))) v(v1) group by cube(v1); + +explain (costs off) +select (select grouping(v1)) from (values ((select 1))) v(v1) group by v1; +select (select grouping(v1)) from (values ((select 1))) v(v1) group by v1; + -- end diff --git a/test/sql/postgres_regress/hash_func.sql b/test/sql/postgres_regress/hash_func.sql index b7ce8b21..89c91f72 100644 --- a/test/sql/postgres_regress/hash_func.sql +++ b/test/sql/postgres_regress/hash_func.sql @@ -220,3 +220,12 @@ FROM (VALUES (int4range(10, 20)), (int4range(23, 43)), (int4range(550274, 1550274)), (int4range(1550275, 208112489))) x(v) WHERE hash_range(v)::bit(32) != hash_range_extended(v, 0)::bit(32) OR hash_range(v)::bit(32) = hash_range_extended(v, 1)::bit(32); + +-- +-- Check special cases for specific data types +-- +SELECT hashfloat4('0'::float4) = hashfloat4('-0'::float4) AS t; +SELECT hashfloat4('NaN'::float4) = hashfloat4(-'NaN'::float4) AS t; +SELECT hashfloat8('0'::float8) = hashfloat8('-0'::float8) AS t; +SELECT hashfloat8('NaN'::float8) = hashfloat8(-'NaN'::float8) AS t; +SELECT hashfloat4('NaN'::float4) = hashfloat8('NaN'::float8) AS t; diff --git a/test/sql/postgres_regress/incremental_sort.sql b/test/sql/postgres_regress/incremental_sort.sql index d8768a6b..284a354d 100644 --- a/test/sql/postgres_regress/incremental_sort.sql +++ b/test/sql/postgres_regress/incremental_sort.sql @@ -281,5 +281,3 @@ from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub; explain (costs off) select sub.unique1, stringu1 || random()::text from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub order by 1, 2; --- Disallow pushing down sort when pathkey is an SRF. -explain (costs off) select unique1 from tenk1 order by unnest('{1,2}'::int[]); diff --git a/test/sql/postgres_regress/int2.sql b/test/sql/postgres_regress/int2.sql index 7dbafb6d..23339aee 100644 --- a/test/sql/postgres_regress/int2.sql +++ b/test/sql/postgres_regress/int2.sql @@ -29,6 +29,10 @@ INSERT INTO INT2_TBL(f1) VALUES (''); SELECT '' AS five, * FROM INT2_TBL; +SELECT * FROM INT2_TBL AS f(a, b); + +SELECT * FROM (TABLE int2_tbl) AS s (a, b); + SELECT '' AS four, i.* FROM INT2_TBL i WHERE i.f1 <> int2 '0'; SELECT '' AS four, i.* FROM INT2_TBL i WHERE i.f1 <> int4 '0'; diff --git a/test/sql/postgres_regress/join.sql b/test/sql/postgres_regress/join.sql index 88181848..7a04d67a 100644 --- a/test/sql/postgres_regress/join.sql +++ b/test/sql/postgres_regress/join.sql @@ -509,6 +509,12 @@ select * from t1 left join t2 on (t1.a = t2.a); select t1.x from t1 join t3 on (t1.a = t3.x); +-- Test matching of locking clause with wrong alias + +select t1.*, t2.*, unnamed_join.* from + t1 join t2 on (t1.a = t2.a), t3 as unnamed_join + for update of unnamed_join; + -- -- regression test for 8.1 merge right join bug -- @@ -1099,6 +1105,9 @@ select unique1 from tenk1, f_immutable_int4(1) x where x = unique1; explain (costs off) select unique1 from tenk1, lateral f_immutable_int4(1) x where x = unique1; +explain (costs off) +select unique1 from tenk1, lateral f_immutable_int4(1) x where x in (select 17); + explain (costs off) select unique1, x from tenk1 join f_immutable_int4(1) x on unique1 = x; @@ -1711,6 +1720,22 @@ select i8.*, ss.v, t.unique2 left join tenk1 t on t.unique2 = ss.v where q2 = 456; +-- and check a related issue where we miscompute required relids for +-- a PHV that's been translated to a child rel +create temp table parttbl (a integer primary key) partition by range (a); +create temp table parttbl1 partition of parttbl for values from (1) to (100); +insert into parttbl values (11), (12); +explain (costs off) +select * from + (select *, 12 as phv from parttbl) as ss + right join int4_tbl on true +where ss.a = ss.phv and f1 = 0; + +select * from + (select *, 12 as phv from parttbl) as ss + right join int4_tbl on true +where ss.a = ss.phv and f1 = 0; + -- bug #8444: we've historically allowed duplicate aliases within aliased JOINs select * from @@ -1952,6 +1977,9 @@ select * from (select q1.v) ) as q2; +-- check the number of columns specified +SELECT * FROM (int8_tbl i cross join int4_tbl j) ss(a,b,c,d); + -- check we don't try to do a unique-ified semijoin with LATERAL explain (verbose, costs off) select * from diff --git a/test/sql/postgres_regress/limit.sql b/test/sql/postgres_regress/limit.sql index d2d4ef13..6f0cda98 100644 --- a/test/sql/postgres_regress/limit.sql +++ b/test/sql/postgres_regress/limit.sql @@ -173,6 +173,11 @@ SELECT thousand FROM onek WHERE thousand < 5 ORDER BY thousand FETCH FIRST 2 ROW ONLY; +-- SKIP LOCKED and WITH TIES are incompatible +SELECT thousand + FROM onek WHERE thousand < 5 + ORDER BY thousand FETCH FIRST 1 ROW WITH TIES FOR UPDATE SKIP LOCKED; + -- should fail SELECT ''::text AS two, unique1, unique2, stringu1 FROM onek WHERE unique1 > 50 diff --git a/test/sql/postgres_regress/matview.sql b/test/sql/postgres_regress/matview.sql index d96175aa..1d690254 100644 --- a/test/sql/postgres_regress/matview.sql +++ b/test/sql/postgres_regress/matview.sql @@ -211,7 +211,15 @@ DROP TABLE mvtest_v CASCADE; -- make sure running as superuser works when MV owned by another role (bug #11208) CREATE ROLE regress_user_mvtest; SET ROLE regress_user_mvtest; -CREATE TABLE mvtest_foo_data AS SELECT i, md5(random()::text) +-- this test case also checks for ambiguity in the queries issued by +-- refresh_by_match_merge(), by choosing column names that intentionally +-- duplicate all the aliases used in those queries +CREATE TABLE mvtest_foo_data AS SELECT i, + i+1 AS tid, + md5(random()::text) AS mv, + md5(random()::text) AS newdata, + md5(random()::text) AS newdata2, + md5(random()::text) AS diff FROM generate_series(1, 10) i; CREATE MATERIALIZED VIEW mvtest_mv_foo AS SELECT * FROM mvtest_foo_data; CREATE MATERIALIZED VIEW mvtest_mv_foo AS SELECT * FROM mvtest_foo_data; diff --git a/test/sql/postgres_regress/numeric.sql b/test/sql/postgres_regress/numeric.sql index 6fa8d3fc..34f96d1a 100644 --- a/test/sql/postgres_regress/numeric.sql +++ b/test/sql/postgres_regress/numeric.sql @@ -655,6 +655,20 @@ INSERT INTO fract_only VALUES (8, '0.00017'); SELECT * FROM fract_only; DROP TABLE fract_only; +-- Check conversion to integers +SELECT (-9223372036854775808.5)::int8; -- should fail +SELECT (-9223372036854775808.4)::int8; -- ok +SELECT 9223372036854775807.4::int8; -- ok +SELECT 9223372036854775807.5::int8; -- should fail +SELECT (-2147483648.5)::int4; -- should fail +SELECT (-2147483648.4)::int4; -- ok +SELECT 2147483647.4::int4; -- ok +SELECT 2147483647.5::int4; -- should fail +SELECT (-32768.5)::int2; -- should fail +SELECT (-32768.4)::int2; -- ok +SELECT 32767.4::int2; -- ok +SELECT 32767.5::int2; -- should fail + -- Check inf/nan conversion behavior SELECT 'NaN'::float8::numeric; SELECT 'Infinity'::float8::numeric; @@ -798,6 +812,14 @@ SELECT '' AS to_char_34, to_char('100'::numeric, 'f"\\ool"999'); SELECT '' AS to_char_35, to_char('100'::numeric, 'f"ool\"999'); SELECT '' AS to_char_36, to_char('100'::numeric, 'f"ool\\"999'); +-- Test scientific notation with various exponents +WITH v(exp) AS + (VALUES(-16379),(-16378),(-1234),(-789),(-45),(-5),(-4),(-3),(-2),(-1),(0), + (1),(2),(3),(4),(5),(38),(275),(2345),(45678),(131070),(131071)) +SELECT exp, + to_char(('1.2345e'||exp)::numeric, '9.999EEEE') as numeric +FROM v; + -- TO_NUMBER() -- SET lc_numeric = 'C'; @@ -864,6 +886,8 @@ select 4770999999999999999999999999999999999999999999999999999999999999999999999 select 4769999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999; +select trim_scale((0.1 - 2e-16383) * (0.1 - 3e-16383)); + -- -- Test some corner cases for division -- @@ -910,10 +934,20 @@ select 3.789 ^ 35; select 1.2 ^ 345; select 0.12 ^ (-20); select 1.000000000123 ^ (-2147483648); +select coalesce(nullif(0.9999999999 ^ 23300000000000, 0), 0) as rounds_to_zero; +select round(((1 - 1.500012345678e-1000) ^ 1.45e1003) * 1e1000); -- cases that used to error out select 0.12 ^ (-25); select 0.5678 ^ (-85); +select coalesce(nullif(0.9999999999 ^ 70000000000000, 0), 0) as underflows; + +-- negative base to integer powers +select (-1.0) ^ 2147483646; +select (-1.0) ^ 2147483647; +select (-1.0) ^ 2147483648; +select (-1.0) ^ 1000000000000000; +select (-1.0) ^ 1000000000000001; -- -- Tests for raising to non-integer powers @@ -953,6 +987,8 @@ select 1.234 ^ 5678; select exp(0.0); select exp(1.0); select exp(1.0::numeric(71,70)); +select coalesce(nullif(exp(-5000::numeric), 0), 0) as rounds_to_zero; +select coalesce(nullif(exp(-10000::numeric), 0), 0) as underflows; -- cases that used to generate inaccurate results select exp(32.999); diff --git a/test/sql/postgres_regress/portals.sql b/test/sql/postgres_regress/portals.sql index 52560ac0..e4607fc3 100644 --- a/test/sql/postgres_regress/portals.sql +++ b/test/sql/postgres_regress/portals.sql @@ -217,6 +217,26 @@ SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors; CLOSE foo25; +BEGIN; + +DECLARE foo25ns NO SCROLL CURSOR WITH HOLD FOR SELECT * FROM tenk2; + +FETCH FROM foo25ns; + +FETCH FROM foo25ns; + +COMMIT; + +FETCH FROM foo25ns; + +FETCH ABSOLUTE 4 FROM foo25ns; + +FETCH ABSOLUTE 4 FROM foo25ns; -- fail + +SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors; + +CLOSE foo25ns; + -- -- ROLLBACK should close holdable cursors -- diff --git a/test/sql/postgres_regress/prepared_xacts.sql b/test/sql/postgres_regress/prepared_xacts.sql index d8249a27..2f0bb55b 100644 --- a/test/sql/postgres_regress/prepared_xacts.sql +++ b/test/sql/postgres_regress/prepared_xacts.sql @@ -88,6 +88,12 @@ SELECT gid FROM pg_prepared_xacts; -- Clean up DROP TABLE pxtest1; +-- Test detection of session-level and xact-level locks on same object +BEGIN; +SELECT pg_advisory_lock(1); +SELECT pg_advisory_xact_lock_shared(1); +PREPARE TRANSACTION 'foo6'; -- fails + -- Test subtransactions BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; CREATE TABLE pxtest2 (a int); diff --git a/test/sql/postgres_regress/privileges.sql b/test/sql/postgres_regress/privileges.sql index 80581757..ebfa9d7d 100644 --- a/test/sql/postgres_regress/privileges.sql +++ b/test/sql/postgres_regress/privileges.sql @@ -39,6 +39,12 @@ ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2; -- duplicate ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2; GRANT regress_priv_group2 TO regress_priv_user4 WITH ADMIN OPTION; +-- prepare non-leakproof function for later +CREATE FUNCTION leak(integer,integer) RETURNS boolean + AS 'int4lt' + LANGUAGE internal IMMUTABLE STRICT; -- but deliberately not LEAKPROOF +ALTER FUNCTION leak(integer,integer) OWNER TO regress_priv_user1; + -- test owner privileges SET SESSION AUTHORIZATION regress_priv_user1; @@ -142,9 +148,6 @@ SET default_statistics_target = 10000; VACUUM ANALYZE atest12; RESET default_statistics_target; -CREATE FUNCTION leak(integer,integer) RETURNS boolean - AS $$begin return $1 < $2; end$$ - LANGUAGE plpgsql immutable; CREATE OPERATOR <<< (procedure = leak, leftarg = integer, rightarg = integer, restrict = scalarltsel); @@ -869,6 +872,53 @@ SELECT has_table_privilege('regress_priv_user1', 'atest4', 'SELECT WITH GRANT OP \c - CREATE ROLE regress_sro_user; +-- Check that index expressions and predicates are run as the table's owner + +-- A dummy index function checking current_user +CREATE FUNCTION sro_ifun(int) RETURNS int AS $$ +BEGIN + -- Below we set the table's owner to regress_sro_user + ASSERT current_user = 'regress_sro_user', + format('sro_ifun(%s) called by %s', $1, current_user); + RETURN $1; +END; +$$ LANGUAGE plpgsql IMMUTABLE; +-- Create a table owned by regress_sro_user +CREATE TABLE sro_tab (a int); +ALTER TABLE sro_tab OWNER TO regress_sro_user; +INSERT INTO sro_tab VALUES (1), (2), (3); +-- Create an expression index with a predicate +CREATE INDEX sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))) + WHERE sro_ifun(a + 10) > sro_ifun(10); +DROP INDEX sro_idx; +-- Do the same concurrently +CREATE INDEX CONCURRENTLY sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))) + WHERE sro_ifun(a + 10) > sro_ifun(10); +-- REINDEX +REINDEX TABLE sro_tab; +REINDEX INDEX sro_idx; +REINDEX TABLE CONCURRENTLY sro_tab; +DROP INDEX sro_idx; +-- CLUSTER +CREATE INDEX sro_cluster_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))); +CLUSTER sro_tab USING sro_cluster_idx; +DROP INDEX sro_cluster_idx; +-- BRIN index +CREATE INDEX sro_brin ON sro_tab USING brin ((sro_ifun(a) + sro_ifun(0))); +SELECT brin_desummarize_range('sro_brin', 0); +SELECT brin_summarize_range('sro_brin', 0); +DROP TABLE sro_tab; +-- Check with a partitioned table +CREATE TABLE sro_ptab (a int) PARTITION BY RANGE (a); +ALTER TABLE sro_ptab OWNER TO regress_sro_user; +CREATE TABLE sro_part PARTITION OF sro_ptab FOR VALUES FROM (1) TO (10); +ALTER TABLE sro_part OWNER TO regress_sro_user; +INSERT INTO sro_ptab VALUES (1), (2), (3); +CREATE INDEX sro_pidx ON sro_ptab ((sro_ifun(a) + sro_ifun(0))) + WHERE sro_ifun(a + 10) > sro_ifun(10); +REINDEX TABLE sro_ptab; +REINDEX INDEX CONCURRENTLY sro_pidx; + SET SESSION AUTHORIZATION regress_sro_user; CREATE FUNCTION unwanted_grant() RETURNS void LANGUAGE sql AS 'GRANT regress_priv_group2 TO regress_sro_user'; @@ -895,6 +945,23 @@ REFRESH MATERIALIZED VIEW sro_mv; REFRESH MATERIALIZED VIEW sro_mv; BEGIN; SET CONSTRAINTS ALL IMMEDIATE; REFRESH MATERIALIZED VIEW sro_mv; COMMIT; +-- REFRESH MATERIALIZED VIEW CONCURRENTLY use of eval_const_expressions() +SET SESSION AUTHORIZATION regress_sro_user; +CREATE FUNCTION unwanted_grant_nofail(int) RETURNS int + IMMUTABLE LANGUAGE plpgsql AS $$ +BEGIN + PERFORM unwanted_grant(); + RAISE WARNING 'owned'; + RETURN 1; +EXCEPTION WHEN OTHERS THEN + RETURN 2; +END$$; +CREATE MATERIALIZED VIEW sro_index_mv AS SELECT 1 AS c; +CREATE UNIQUE INDEX ON sro_index_mv (c) WHERE unwanted_grant_nofail(1) > 0; +\c - +REFRESH MATERIALIZED VIEW CONCURRENTLY sro_index_mv; +REFRESH MATERIALIZED VIEW sro_index_mv; + DROP OWNED BY regress_sro_user; DROP ROLE regress_sro_user; diff --git a/test/sql/postgres_regress/publication.sql b/test/sql/postgres_regress/publication.sql index d8440753..4b773839 100644 --- a/test/sql/postgres_regress/publication.sql +++ b/test/sql/postgres_regress/publication.sql @@ -76,10 +76,12 @@ CREATE PUBLICATION testpub_forparted; CREATE PUBLICATION testpub_forparted1; RESET client_min_messages; CREATE TABLE testpub_parted1 (LIKE testpub_parted); +CREATE TABLE testpub_parted2 (LIKE testpub_parted); ALTER PUBLICATION testpub_forparted1 SET (publish='insert'); +ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted1 FOR VALUES IN (1); +ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted2 FOR VALUES IN (2); -- works despite missing REPLICA IDENTITY, because updates are not replicated UPDATE testpub_parted1 SET a = 1; -ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted1 FOR VALUES IN (1); -- only parent is listed as being in publication, not the partition ALTER PUBLICATION testpub_forparted ADD TABLE testpub_parted; \dRp+ testpub_forparted @@ -90,9 +92,32 @@ ALTER TABLE testpub_parted DETACH PARTITION testpub_parted1; UPDATE testpub_parted1 SET a = 1; ALTER PUBLICATION testpub_forparted SET (publish_via_partition_root = true); \dRp+ testpub_forparted -DROP TABLE testpub_parted1; +-- still fail, because parent's publication replicates updates +UPDATE testpub_parted2 SET a = 2; +ALTER PUBLICATION testpub_forparted DROP TABLE testpub_parted; +-- works again, because update is no longer replicated +UPDATE testpub_parted2 SET a = 2; +-- publication includes both the parent table and the child table +ALTER PUBLICATION testpub_forparted ADD TABLE testpub_parted, testpub_parted2; +-- only parent is listed as being in publication, not the partition +SELECT * FROM pg_publication_tables; +DROP TABLE testpub_parted1, testpub_parted2; DROP PUBLICATION testpub_forparted, testpub_forparted1; +-- Test cache invalidation FOR ALL TABLES publication +SET client_min_messages = 'ERROR'; +CREATE TABLE testpub_tbl4(a int); +INSERT INTO testpub_tbl4 values(1); +UPDATE testpub_tbl4 set a = 2; +CREATE PUBLICATION testpub_foralltables FOR ALL TABLES; +RESET client_min_messages; +-- fail missing REPLICA IDENTITY +UPDATE testpub_tbl4 set a = 3; +DROP PUBLICATION testpub_foralltables; +-- should pass after dropping the publication +UPDATE testpub_tbl4 set a = 3; +DROP TABLE testpub_tbl4; + -- fail - view CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_view; SET client_min_messages = 'ERROR'; @@ -124,6 +149,19 @@ ALTER PUBLICATION testpub_default DROP TABLE pub_test.testpub_nopk; \d+ testpub_tbl1 +-- verify relation cache invalidation when a primary key is added using +-- an existing index +CREATE TABLE pub_test.testpub_addpk (id int not null, data int); +ALTER PUBLICATION testpub_default ADD TABLE pub_test.testpub_addpk; +INSERT INTO pub_test.testpub_addpk VALUES(1, 11); +CREATE UNIQUE INDEX testpub_addpk_id_idx ON pub_test.testpub_addpk(id); +-- fail: +UPDATE pub_test.testpub_addpk SET id = 2; +ALTER TABLE pub_test.testpub_addpk ADD PRIMARY KEY USING INDEX testpub_addpk_id_idx; +-- now it should work: +UPDATE pub_test.testpub_addpk SET id = 2; +DROP TABLE pub_test.testpub_addpk; + -- permissions SET ROLE regress_publication_user2; CREATE PUBLICATION testpub2; -- fail diff --git a/test/sql/postgres_regress/rangefuncs.sql b/test/sql/postgres_regress/rangefuncs.sql index 98d27c63..f6acb888 100644 --- a/test/sql/postgres_regress/rangefuncs.sql +++ b/test/sql/postgres_regress/rangefuncs.sql @@ -762,3 +762,18 @@ select *, row_to_json(u) from unnest(array[null::rngfunc2, (1,'foo')::rngfunc2, select *, row_to_json(u) from unnest(array[]::rngfunc2[]) u; drop type rngfunc2; + +-- check handling of functions pulled up into function RTEs (bug #17227) + +explain (verbose, costs off) +select * from + (select jsonb_path_query_array(module->'lectures', '$[*]') as lecture + from unnest(array['{"lectures": [{"id": "1"}]}'::jsonb]) + as unnested_modules(module)) as ss, + jsonb_to_recordset(ss.lecture) as j (id text); + +select * from + (select jsonb_path_query_array(module->'lectures', '$[*]') as lecture + from unnest(array['{"lectures": [{"id": "1"}]}'::jsonb]) + as unnested_modules(module)) as ss, + jsonb_to_recordset(ss.lecture) as j (id text); diff --git a/test/sql/postgres_regress/regex.sql b/test/sql/postgres_regress/regex.sql index a1742240..758de44d 100644 --- a/test/sql/postgres_regress/regex.sql +++ b/test/sql/postgres_regress/regex.sql @@ -135,6 +135,15 @@ select 'a' ~ '.. ()|\1'; select 'a' ~ '()*\1'; select 'a' ~ '()+\1'; +-- Test incorrect removal of capture groups within {0} +select 'xxx' ~ '(.){0}(\1)' as f; +select 'xxx' ~ '((.)){0}(\2)' as f; +select 'xyz' ~ '((.)){0}(\2){0}' as t; + +-- Test ancient oversight in when to apply zaptreesubs +select 'abcdef' ~ '^(.)\1|\1.' as f; +select 'abadef' ~ '^((.)\2|..)\2' as f; + -- Error conditions select 'xyz' ~ 'x(\w)(?=\1)'; -- no backrefs in LACONs select 'xyz' ~ 'x(\w)(?=(\1))'; diff --git a/test/sql/postgres_regress/reloptions.sql b/test/sql/postgres_regress/reloptions.sql index 95f7ab41..4252b020 100644 --- a/test/sql/postgres_regress/reloptions.sql +++ b/test/sql/postgres_regress/reloptions.sql @@ -55,14 +55,14 @@ ALTER TABLE reloptions_test RESET (fillfactor=12); -- Test vacuum_truncate option DROP TABLE reloptions_test; -CREATE TABLE reloptions_test(i INT NOT NULL, j text) +CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) WITH (vacuum_truncate=false, toast.vacuum_truncate=false, autovacuum_enabled=false); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); -- Do an aggressive vacuum to prevent page-skipping. -VACUUM FREEZE reloptions_test; +VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') > 0; SELECT reloptions FROM pg_class WHERE oid = @@ -73,7 +73,7 @@ ALTER TABLE reloptions_test RESET (vacuum_truncate); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); -- Do an aggressive vacuum to prevent page-skipping. -VACUUM FREEZE reloptions_test; +VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; SELECT pg_relation_size('reloptions_test') = 0; -- Test toast.* options diff --git a/test/sql/postgres_regress/replica_identity.sql b/test/sql/postgres_regress/replica_identity.sql index a5ac8f55..33da8297 100644 --- a/test/sql/postgres_regress/replica_identity.sql +++ b/test/sql/postgres_regress/replica_identity.sql @@ -94,6 +94,10 @@ ALTER TABLE test_replica_identity3 REPLICA IDENTITY USING INDEX test_replica_ide ALTER TABLE test_replica_identity3 ALTER COLUMN id TYPE bigint; \d test_replica_identity3 +-- ALTER TABLE DROP NOT NULL is not allowed for columns part of an index +-- used as replica identity. +ALTER TABLE test_replica_identity3 ALTER COLUMN id DROP NOT NULL; + DROP TABLE test_replica_identity; DROP TABLE test_replica_identity2; DROP TABLE test_replica_identity3; diff --git a/test/sql/postgres_regress/rowsecurity.sql b/test/sql/postgres_regress/rowsecurity.sql index d7a5a36c..178eeb03 100644 --- a/test/sql/postgres_regress/rowsecurity.sql +++ b/test/sql/postgres_regress/rowsecurity.sql @@ -1757,6 +1757,16 @@ CREATE POLICY p1 ON dob_t1 TO regress_rls_dob_role1,regress_rls_dob_role2 USING DROP OWNED BY regress_rls_dob_role1; DROP POLICY p1 ON dob_t1; -- should succeed +-- same cases with duplicate polroles entries +CREATE POLICY p1 ON dob_t1 TO regress_rls_dob_role1,regress_rls_dob_role1 USING (true); +DROP OWNED BY regress_rls_dob_role1; +DROP POLICY p1 ON dob_t1; -- should fail, already gone + +CREATE POLICY p1 ON dob_t1 TO regress_rls_dob_role1,regress_rls_dob_role1,regress_rls_dob_role2 USING (true); +DROP OWNED BY regress_rls_dob_role1; +DROP POLICY p1 ON dob_t1; -- should succeed + +-- partitioned target CREATE POLICY p1 ON dob_t2 TO regress_rls_dob_role1,regress_rls_dob_role2 USING (true); DROP OWNED BY regress_rls_dob_role1; DROP POLICY p1 ON dob_t2; -- should succeed diff --git a/test/sql/postgres_regress/rowtypes.sql b/test/sql/postgres_regress/rowtypes.sql index 83cf4a1e..3c83727f 100644 --- a/test/sql/postgres_regress/rowtypes.sql +++ b/test/sql/postgres_regress/rowtypes.sql @@ -413,12 +413,10 @@ select longname(f) from fullname f; -- select row_to_json(i) from int8_tbl i; +-- since "i" is of type "int8_tbl", attaching aliases doesn't change anything: select row_to_json(i) from int8_tbl i(x,y); -create temp view vv1 as select * from int8_tbl; -select row_to_json(i) from vv1 i; -select row_to_json(i) from vv1 i(x,y); - +-- in these examples, we'll report the exposed column names of the subselect: select row_to_json(ss) from (select q1, q2 from int8_tbl) as ss; select row_to_json(ss) from diff --git a/test/sql/postgres_regress/rules.sql b/test/sql/postgres_regress/rules.sql index 6ec37c43..b732833e 100644 --- a/test/sql/postgres_regress/rules.sql +++ b/test/sql/postgres_regress/rules.sql @@ -992,6 +992,20 @@ select * from only t1_2; reset constraint_exclusion; +-- test FOR UPDATE in rules + +create table rules_base(f1 int, f2 int); +insert into rules_base values(1,2), (11,12); +create rule r1 as on update to rules_base do instead + select * from rules_base where f1 = 1 for update; +update rules_base set f2 = f2 + 1; +create or replace rule r1 as on update to rules_base do instead + select * from rules_base where f1 = 11 for update of rules_base; +update rules_base set f2 = f2 + 1; +create or replace rule r1 as on update to rules_base do instead + select * from rules_base where f1 = 11 for update of old; -- error +drop table rules_base; + -- test various flavors of pg_get_viewdef() select pg_get_viewdef('shoe'::regclass) as unpretty; diff --git a/test/sql/postgres_regress/select.sql b/test/sql/postgres_regress/select.sql index b5929b2e..d6f42aa0 100644 --- a/test/sql/postgres_regress/select.sql +++ b/test/sql/postgres_regress/select.sql @@ -148,6 +148,11 @@ SELECT 2+2, 57 UNION ALL TABLE int8_tbl; +-- corner case: VALUES with no columns +CREATE TEMP TABLE nocols(); +INSERT INTO nocols DEFAULT VALUES; +SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v; + -- -- Test ORDER BY options -- diff --git a/test/sql/postgres_regress/select_parallel.sql b/test/sql/postgres_regress/select_parallel.sql index 5a01a98b..43adb05b 100644 --- a/test/sql/postgres_regress/select_parallel.sql +++ b/test/sql/postgres_regress/select_parallel.sql @@ -431,6 +431,16 @@ ORDER BY 1; SELECT * FROM information_schema.foreign_data_wrapper_options ORDER BY 1, 2, 3; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT generate_series(1, two), array(select generate_series(1, two)) + FROM tenk1 ORDER BY tenthous; + +-- must disallow pushing sort below gather when pathkey contains an SRF +EXPLAIN (VERBOSE, COSTS OFF) +SELECT unnest(ARRAY[]::integer[]) + 1 AS pathkey + FROM tenk1 t1 JOIN tenk1 t2 ON TRUE + ORDER BY pathkey; + -- test passing expanded-value representations to workers CREATE FUNCTION make_some_array(int,int) returns int[] as $$declare x int[]; diff --git a/test/sql/postgres_regress/stats_ext.sql b/test/sql/postgres_regress/stats_ext.sql index 906503bd..d628ea43 100644 --- a/test/sql/postgres_regress/stats_ext.sql +++ b/test/sql/postgres_regress/stats_ext.sql @@ -43,6 +43,15 @@ DROP TABLE ext_stats_test; -- Ensure stats are dropped sanely, and test IF NOT EXISTS while at it CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER); CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1; +COMMENT ON STATISTICS ab1_a_b_stats IS 'new comment'; +CREATE ROLE regress_stats_ext; +SET SESSION AUTHORIZATION regress_stats_ext; +COMMENT ON STATISTICS ab1_a_b_stats IS 'changed comment'; +DROP STATISTICS ab1_a_b_stats; +ALTER STATISTICS ab1_a_b_stats RENAME TO ab1_a_b_stats_new; +RESET SESSION AUTHORIZATION; +DROP ROLE regress_stats_ext; + CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1; DROP STATISTICS ab1_a_b_stats; @@ -97,6 +106,38 @@ CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1; ANALYZE ab1; DROP TABLE ab1 CASCADE; +-- Tests for stats with inheritance +CREATE TABLE stxdinh(a int, b int); +CREATE TABLE stxdinh1() INHERITS(stxdinh); +CREATE TABLE stxdinh2() INHERITS(stxdinh); +INSERT INTO stxdinh SELECT mod(a,50), mod(a,100) FROM generate_series(0, 1999) a; +INSERT INTO stxdinh1 SELECT mod(a,100), mod(a,100) FROM generate_series(0, 999) a; +INSERT INTO stxdinh2 SELECT mod(a,100), mod(a,100) FROM generate_series(0, 999) a; +VACUUM ANALYZE stxdinh, stxdinh1, stxdinh2; +-- Ensure non-inherited stats are not applied to inherited query +-- Without stats object, it looks like this +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* GROUP BY 1, 2'); +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* WHERE a = 0 AND b = 0'); +CREATE STATISTICS stxdinh ON a, b FROM stxdinh; +VACUUM ANALYZE stxdinh, stxdinh1, stxdinh2; +-- Since the stats object does not include inherited stats, it should not +-- affect the estimates +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* GROUP BY 1, 2'); +-- Dependencies are applied at individual relations (within append), so +-- this estimate changes a bit because we improve estimates for the parent +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* WHERE a = 0 AND b = 0'); +DROP TABLE stxdinh, stxdinh1, stxdinh2; + +-- Ensure inherited stats ARE applied to inherited query in partitioned table +CREATE TABLE stxdinp(i int, a int, b int) PARTITION BY RANGE (i); +CREATE TABLE stxdinp1 PARTITION OF stxdinp FOR VALUES FROM (1) TO (100); +INSERT INTO stxdinp SELECT 1, a/100, a/100 FROM generate_series(1, 999) a; +CREATE STATISTICS stxdinp ON a, b FROM stxdinp; +VACUUM ANALYZE stxdinp; -- partitions are processed recursively +SELECT 1 FROM pg_statistic_ext WHERE stxrelid = 'stxdinp'::regclass; +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinp GROUP BY 1, 2'); +DROP TABLE stxdinp; + -- Verify supported object types for extended statistics CREATE schema tststats; @@ -456,7 +497,8 @@ CREATE TABLE mcv_lists ( b VARCHAR, filler3 DATE, c INT, - d TEXT + d TEXT, + ia INT[] ) WITH (autovacuum_enabled = off); @@ -483,8 +525,9 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = TRUNCATE mcv_lists; DROP STATISTICS mcv_lists_stats; -INSERT INTO mcv_lists (a, b, c, filler1) - SELECT mod(i,100), mod(i,50), mod(i,25), i FROM generate_series(1,5000) s(i); +INSERT INTO mcv_lists (a, b, c, ia, filler1) + SELECT mod(i,100), mod(i,50), mod(i,25), array[mod(i,25)], i + FROM generate_series(1,5000) s(i); ANALYZE mcv_lists; @@ -534,8 +577,10 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', NULL, ''3'') AND c > ANY (ARRAY[1, 2, NULL, 3])'); +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[4,5]) AND 4 = ANY(ia)'); + -- create statistics -CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists; +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c, ia FROM mcv_lists; ANALYZE mcv_lists; @@ -586,6 +631,8 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY -- we can't use the statistic for OR clauses that are not fully covered (missing 'd' attribute) SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL'); +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[4,5]) AND 4 = ANY(ia)'); + -- check change of unrelated column type does not reset the MCV statistics ALTER TABLE mcv_lists ALTER COLUMN d TYPE VARCHAR(64); diff --git a/test/sql/postgres_regress/subscription.sql b/test/sql/postgres_regress/subscription.sql index 1bc58887..277b9290 100644 --- a/test/sql/postgres_regress/subscription.sql +++ b/test/sql/postgres_regress/subscription.sql @@ -65,6 +65,9 @@ ALTER SUBSCRIPTION regress_testsub SET PUBLICATION testpub2, testpub3 WITH (refr ALTER SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist2'; ALTER SUBSCRIPTION regress_testsub SET (slot_name = 'newname'); +-- fail +ALTER SUBSCRIPTION regress_testsub SET (slot_name = ''); + -- fail ALTER SUBSCRIPTION regress_doesnotexist CONNECTION 'dbname=regress_doesnotexist2'; ALTER SUBSCRIPTION regress_testsub SET (create_slot = false); diff --git a/test/sql/postgres_regress/sysviews.sql b/test/sql/postgres_regress/sysviews.sql index 5eb111d3..e0ddb114 100644 --- a/test/sql/postgres_regress/sysviews.sql +++ b/test/sql/postgres_regress/sysviews.sql @@ -32,6 +32,9 @@ select count(*) = 0 as ok from pg_prepared_statements; -- See also prepared_xacts.sql select count(*) >= 0 as ok from pg_prepared_xacts; +-- There will surely be at least one SLRU cache +select count(*) > 0 as ok from pg_stat_slru; + -- We expect no walreceiver running in this test select count(*) = 0 as ok from pg_stat_wal_receiver; diff --git a/test/sql/postgres_regress/timestamp.sql b/test/sql/postgres_regress/timestamp.sql index 4f014dad..5436b794 100644 --- a/test/sql/postgres_regress/timestamp.sql +++ b/test/sql/postgres_regress/timestamp.sql @@ -247,3 +247,17 @@ SELECT i, -- timestamp numeric fields constructor SELECT make_timestamp(2014,12,28,6,30,45.887); + +-- generate_series for timestamp +select * from generate_series('2020-01-01 00:00'::timestamp, + '2020-01-02 03:00'::timestamp, + '1 hour'::interval); +-- the LIMIT should allow this to terminate in a reasonable amount of time +-- (but that unfortunately doesn't work yet for SELECT * FROM ...) +select generate_series('2022-01-01 00:00'::timestamp, + 'infinity'::timestamp, + '1 month'::interval) limit 10; +-- errors +select * from generate_series('2020-01-01 00:00'::timestamp, + '2020-01-02 03:00'::timestamp, + '0 hour'::interval); diff --git a/test/sql/postgres_regress/timestamptz.sql b/test/sql/postgres_regress/timestamptz.sql index 300302da..8e7d624e 100644 --- a/test/sql/postgres_regress/timestamptz.sql +++ b/test/sql/postgres_regress/timestamptz.sql @@ -342,6 +342,20 @@ SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'PST8PDT'); RESET TimeZone; +-- generate_series for timestamptz +select * from generate_series('2020-01-01 00:00'::timestamptz, + '2020-01-02 03:00'::timestamptz, + '1 hour'::interval); +-- the LIMIT should allow this to terminate in a reasonable amount of time +-- (but that unfortunately doesn't work yet for SELECT * FROM ...) +select generate_series('2022-01-01 00:00'::timestamptz, + 'infinity'::timestamptz, + '1 month'::interval) limit 10; +-- errors +select * from generate_series('2020-01-01 00:00'::timestamptz, + '2020-01-02 03:00'::timestamptz, + '0 hour'::interval); + -- -- Test behavior with a dynamic (time-varying) timezone abbreviation. -- These tests rely on the knowledge that MSK (Europe/Moscow standard time) diff --git a/test/sql/postgres_regress/triggers.sql b/test/sql/postgres_regress/triggers.sql index 1fb3ecf3..c57f4171 100644 --- a/test/sql/postgres_regress/triggers.sql +++ b/test/sql/postgres_regress/triggers.sql @@ -1428,6 +1428,11 @@ create trigger trg1 after insert on trigpart3 for each row execute procedure tri alter table trigpart attach partition trigpart3 FOR VALUES FROM (2000) to (3000); -- fail drop table trigpart3; +-- check display of unrelated triggers +create trigger samename after delete on trigpart execute function trigger_nothing(); +create trigger samename after delete on trigpart1 execute function trigger_nothing(); +\d trigpart1 + drop table trigpart; drop function trigger_nothing(); @@ -1827,15 +1832,56 @@ create table parent (a int) partition by list (a); create table child1 partition of parent for values in (1); create trigger tg after insert on parent for each row execute procedure trig_nothing(); +create trigger tg_stmt after insert on parent + for statement execute procedure trig_nothing(); select tgrelid::regclass, tgname, tgenabled from pg_trigger where tgrelid in ('parent'::regclass, 'child1'::regclass) - order by tgrelid::regclass::text; -alter table only parent enable always trigger tg; + order by tgrelid::regclass::text, tgname; +alter table only parent enable always trigger tg; -- no recursion because ONLY +alter table parent enable always trigger tg_stmt; -- no recursion because statement trigger select tgrelid::regclass, tgname, tgenabled from pg_trigger where tgrelid in ('parent'::regclass, 'child1'::regclass) - order by tgrelid::regclass::text; + order by tgrelid::regclass::text, tgname; +-- The following is a no-op for the parent trigger but not so +-- for the child trigger, so recursion should be applied. +alter table parent enable always trigger tg; +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname; drop table parent, child1; +-- Verify that firing state propagates correctly on creation, too +CREATE TABLE trgfire (i int) PARTITION BY RANGE (i); +CREATE TABLE trgfire1 PARTITION OF trgfire FOR VALUES FROM (1) TO (10); +CREATE OR REPLACE FUNCTION tgf() RETURNS trigger LANGUAGE plpgsql + AS $$ begin raise exception 'except'; end $$; +CREATE TRIGGER tg AFTER INSERT ON trgfire FOR EACH ROW EXECUTE FUNCTION tgf(); +INSERT INTO trgfire VALUES (1); +ALTER TABLE trgfire DISABLE TRIGGER tg; +INSERT INTO trgfire VALUES (1); +CREATE TABLE trgfire2 PARTITION OF trgfire FOR VALUES FROM (10) TO (20); +INSERT INTO trgfire VALUES (11); +CREATE TABLE trgfire3 (LIKE trgfire); +ALTER TABLE trgfire ATTACH PARTITION trgfire3 FOR VALUES FROM (20) TO (30); +INSERT INTO trgfire VALUES (21); +CREATE TABLE trgfire4 PARTITION OF trgfire FOR VALUES FROM (30) TO (40) PARTITION BY LIST (i); +CREATE TABLE trgfire4_30 PARTITION OF trgfire4 FOR VALUES IN (30); +INSERT INTO trgfire VALUES (30); +CREATE TABLE trgfire5 (LIKE trgfire) PARTITION BY LIST (i); +CREATE TABLE trgfire5_40 PARTITION OF trgfire5 FOR VALUES IN (40); +ALTER TABLE trgfire ATTACH PARTITION trgfire5 FOR VALUES FROM (40) TO (50); +INSERT INTO trgfire VALUES (40); +SELECT tgrelid::regclass, tgenabled FROM pg_trigger + WHERE tgrelid::regclass IN (SELECT oid from pg_class where relname LIKE 'trgfire%') + ORDER BY tgrelid::regclass::text; +ALTER TABLE trgfire ENABLE TRIGGER tg; +INSERT INTO trgfire VALUES (1); +INSERT INTO trgfire VALUES (11); +INSERT INTO trgfire VALUES (21); +INSERT INTO trgfire VALUES (30); +INSERT INTO trgfire VALUES (40); +DROP TABLE trgfire; +DROP FUNCTION tgf(); -- -- Test the interaction between transition tables and both kinds of @@ -2383,6 +2429,11 @@ create trigger aft_row after insert or update on trigger_parted create table trigger_parted_p1 partition of trigger_parted for values in (1) partition by list (a); create table trigger_parted_p1_1 partition of trigger_parted_p1 for values in (1); +create table trigger_parted_p2 partition of trigger_parted for values in (2) + partition by list (a); +create table trigger_parted_p2_2 partition of trigger_parted_p2 for values in (2); +alter table only trigger_parted_p2 disable trigger aft_row; +alter table trigger_parted_p2_2 enable always trigger aft_row; -- verify transition table conversion slot's lifetime -- https://postgr.es/m/39a71864-b120-5a5c-8cc5-c632b6f16761@amazon.com diff --git a/test/sql/postgres_regress/type_sanity.sql b/test/sql/postgres_regress/type_sanity.sql index 4b492ce0..0c6a0a4f 100644 --- a/test/sql/postgres_regress/type_sanity.sql +++ b/test/sql/postgres_regress/type_sanity.sql @@ -467,3 +467,98 @@ FROM pg_range p1 JOIN pg_proc p ON p.oid = p1.rngsubdiff WHERE pronargs != 2 OR proargtypes[0] != rngsubtype OR proargtypes[1] != rngsubtype OR prorettype != 'pg_catalog.float8'::regtype; + +-- Create a table that holds all the known in-core data types and leave it +-- around so as pg_upgrade is able to test their binary compatibility. +CREATE TABLE tab_core_types AS SELECT + '(11,12)'::point, + '(1,1),(2,2)'::line, + '((11,11),(12,12))'::lseg, + '((11,11),(13,13))'::box, + '((11,12),(13,13),(14,14))'::path AS openedpath, + '[(11,12),(13,13),(14,14)]'::path AS closedpath, + '((11,12),(13,13),(14,14))'::polygon, + '1,1,1'::circle, + 'today'::date, + 'now'::time, + 'now'::timestamp, + 'now'::timetz, + 'now'::timestamptz, + '12 seconds'::interval, + '{"reason":"because"}'::json, + '{"when":"now"}'::jsonb, + '$.a[*] ? (@ > 2)'::jsonpath, + '127.0.0.1'::inet, + '127.0.0.0/8'::cidr, + '00:01:03:86:1c:ba'::macaddr8, + '00:01:03:86:1c:ba'::macaddr, + 2::int2, 4::int4, 8::int8, + 4::float4, '8'::float8, pi()::numeric, + 'foo'::"char", + 'c'::bpchar, + 'abc'::varchar, + 'name'::name, + 'txt'::text, + true::bool, + E'\\xDEADBEEF'::bytea, + B'10001'::bit, + B'10001'::varbit AS varbit, + '12.34'::money, + 'abc'::refcursor, + '1 2'::int2vector, + '1 2'::oidvector, + format('%I=UC/%I', USER, USER)::aclitem AS aclitem, + 'a fat cat sat on a mat and ate a fat rat'::tsvector, + 'fat & rat'::tsquery, + 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, + '11'::xid8, + 'pg_class'::regclass, + 'regtype'::regtype, + 'pg_monitor'::regrole, + 'pg_class'::regclass::oid, + '(1,1)'::tid, '2'::xid, '3'::cid, + '10:20:10,14,15'::txid_snapshot, + '10:20:10,14,15'::pg_snapshot, + '16/B374D848'::pg_lsn, + 1::information_schema.cardinal_number, + 'l'::information_schema.character_data, + 'n'::information_schema.sql_identifier, + 'now'::information_schema.time_stamp, + 'YES'::information_schema.yes_or_no, + 'venus'::planets, + 'i16'::insenum, + '(1,2)'::int4range, + '(3,4)'::int8range, + '(1,2)'::float8range, + '(3,4)'::numrange, + '(a,b)'::textrange, + '(12.34, 56.78)'::cashrange, + '(2020-01-02, 2021-02-03)'::daterange, + '(2020-01-02 03:04:05, 2021-02-03 06:07:08)'::tsrange, + '(2020-01-02 03:04:05, 2021-02-03 06:07:08)'::tstzrange, + arrayrange(ARRAY[1,2], ARRAY[2,1]); + +-- Sanity check on the previous table, checking that all core types are +-- included in this table. +SELECT oid, typname, typtype, typelem, typarray, typarray + FROM pg_type t + WHERE typtype NOT IN ('p', 'c') AND + -- reg* types cannot be pg_upgraded, so discard them. + oid != ALL(ARRAY['regproc', 'regprocedure', 'regoper', + 'regoperator', 'regconfig', 'regdictionary', + 'regnamespace', 'regcollation']::regtype[]) AND + -- Discard types that do not accept input values as these cannot be + -- tested easily. + -- Note: XML might be disabled at compile-time. + oid != ALL(ARRAY['gtsvector', 'pg_node_tree', + 'pg_ndistinct', 'pg_dependencies', 'pg_mcv_list', + 'xml']::regtype[]) AND + -- Discard arrays. + NOT EXISTS (SELECT 1 FROM pg_type u WHERE u.typarray = t.oid) + -- Exclude everything from the table created above. This checks + -- that no in-core types are missing in tab_core_types. + AND NOT EXISTS (SELECT 1 + FROM pg_attribute a + WHERE a.atttypid=t.oid AND + a.attnum > 0 AND + a.attrelid='tab_core_types'::regclass); diff --git a/test/sql/postgres_regress/unicode.sql b/test/sql/postgres_regress/unicode.sql index ccfc6fa7..63cd523f 100644 --- a/test/sql/postgres_regress/unicode.sql +++ b/test/sql/postgres_regress/unicode.sql @@ -5,6 +5,7 @@ SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset SELECT U&'\0061\0308bc' <> U&'\00E4bc' COLLATE "C" AS sanity_check; +SELECT normalize(''); SELECT normalize(U&'\0061\0308\24D1c') = U&'\00E4\24D1c' COLLATE "C" AS test_default; SELECT normalize(U&'\0061\0308\24D1c', NFC) = U&'\00E4\24D1c' COLLATE "C" AS test_nfc; SELECT normalize(U&'\00E4bc', NFC) = U&'\00E4bc' COLLATE "C" AS test_nfc_idem; @@ -26,7 +27,8 @@ FROM (VALUES (1, U&'\00E4bc'), (2, U&'\0061\0308bc'), (3, U&'\00E4\24D1c'), - (4, U&'\0061\0308\24D1c')) vals (num, val) + (4, U&'\0061\0308\24D1c'), + (5, '')) vals (num, val) ORDER BY num; SELECT is_normalized('abc', 'def'); -- run-time error diff --git a/test/sql/postgres_regress/vacuum.sql b/test/sql/postgres_regress/vacuum.sql index c7b5f96f..abb375ad 100644 --- a/test/sql/postgres_regress/vacuum.sql +++ b/test/sql/postgres_regress/vacuum.sql @@ -145,12 +145,12 @@ VACUUM (INDEX_CLEANUP FALSE) vactst; -- index cleanup option is ignored if no in VACUUM (INDEX_CLEANUP FALSE, FREEZE TRUE) vaccluster; -- TRUNCATE option -CREATE TABLE vac_truncate_test(i INT NOT NULL, j text) +CREATE TEMP TABLE vac_truncate_test(i INT NOT NULL, j text) WITH (vacuum_truncate=true, autovacuum_enabled=false); INSERT INTO vac_truncate_test VALUES (1, NULL), (NULL, NULL); -VACUUM (TRUNCATE FALSE) vac_truncate_test; +VACUUM (TRUNCATE FALSE, DISABLE_PAGE_SKIPPING) vac_truncate_test; SELECT pg_relation_size('vac_truncate_test') > 0; -VACUUM vac_truncate_test; +VACUUM (DISABLE_PAGE_SKIPPING) vac_truncate_test; SELECT pg_relation_size('vac_truncate_test') = 0; VACUUM (TRUNCATE FALSE, FULL TRUE) vac_truncate_test; DROP TABLE vac_truncate_test; diff --git a/test/sql/postgres_regress/with.sql b/test/sql/postgres_regress/with.sql index 43cd2e10..5b899333 100644 --- a/test/sql/postgres_regress/with.sql +++ b/test/sql/postgres_regress/with.sql @@ -454,6 +454,9 @@ DROP TABLE y; -- error cases -- +WITH x(n, b) AS (SELECT 1) +SELECT * FROM x; + -- INTERSECT WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x) SELECT * FROM x; @@ -809,7 +812,7 @@ CREATE TEMP TABLE bug6051_2 (i int); CREATE RULE bug6051_ins AS ON INSERT TO bug6051 DO INSTEAD INSERT INTO bug6051_2 - SELECT NEW.i; + VALUES(NEW.i); WITH t1 AS ( DELETE FROM bug6051 RETURNING * ) INSERT INTO bug6051 SELECT * FROM t1; @@ -817,6 +820,62 @@ INSERT INTO bug6051 SELECT * FROM t1; SELECT * FROM bug6051; SELECT * FROM bug6051_2; +-- check INSERT...SELECT rule actions are disallowed on commands +-- that have modifyingCTEs +CREATE OR REPLACE RULE bug6051_ins AS ON INSERT TO bug6051 DO INSTEAD + INSERT INTO bug6051_2 + SELECT NEW.i; + +WITH t1 AS ( DELETE FROM bug6051 RETURNING * ) +INSERT INTO bug6051 SELECT * FROM t1; + +-- silly example to verify that hasModifyingCTE flag is propagated +CREATE TEMP TABLE bug6051_3 AS + SELECT a FROM generate_series(11,13) AS a; + +CREATE RULE bug6051_3_ins AS ON INSERT TO bug6051_3 DO INSTEAD + SELECT i FROM bug6051_2; + +BEGIN; SET LOCAL force_parallel_mode = on; + +WITH t1 AS ( DELETE FROM bug6051_3 RETURNING * ) + INSERT INTO bug6051_3 SELECT * FROM t1; + +COMMIT; + +SELECT * FROM bug6051_3; + +-- check case where CTE reference is removed due to optimization +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q1 FROM +( + WITH t_cte AS (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss; + +SELECT q1 FROM +( + WITH t_cte AS (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q1 FROM +( + WITH t_cte AS MATERIALIZED (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss; + +SELECT q1 FROM +( + WITH t_cte AS MATERIALIZED (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss; + -- a truly recursive CTE in the same list WITH RECURSIVE t(a) AS ( SELECT 0 @@ -1066,6 +1125,27 @@ WITH t AS ( INSERT INTO y VALUES(0) ) VALUES(FALSE); +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTHING; +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE); +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTIFY foo; +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE); +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO ALSO NOTIFY foo; +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE); +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y + DO INSTEAD (NOTIFY foo; NOTIFY bar); +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE); DROP RULE y_rule ON y; -- check that parser lookahead for WITH doesn't cause any odd behavior @@ -1074,12 +1154,12 @@ create table foo (with ordinality); -- fail, WITH is a reserved word with ordinality as (select 1 as x) select * from ordinality; -- check sane response to attempt to modify CTE relation -WITH test AS (SELECT 42) INSERT INTO test VALUES (1); +WITH with_test AS (SELECT 42) INSERT INTO with_test VALUES (1); -- check response to attempt to modify table with same name as a CTE (perhaps -- surprisingly it works, because CTEs don't hide tables from data-modifying -- statements) -create temp table test (i int); -with test as (select 42) insert into test select * from test; -select * from test; -drop table test; +create temp table with_test (i int); +with with_test as (select 42) insert into with_test select * from with_test; +select * from with_test; +drop table with_test; diff --git a/test/sql/postgres_regress/xml.sql b/test/sql/postgres_regress/xml.sql index f3f83c78..e3f90db4 100644 --- a/test/sql/postgres_regress/xml.sql +++ b/test/sql/postgres_regress/xml.sql @@ -384,6 +384,9 @@ SELECT * FROM xmltableview1; EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1; EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1; +-- errors +SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp) AS f (v1, v2); + -- XMLNAMESPACES tests SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), '/zz:rows/zz:row' diff --git a/test/sql/postgres_regress/xmlmap.sql b/test/sql/postgres_regress/xmlmap.sql index fde1b9eb..16582bf6 100644 --- a/test/sql/postgres_regress/xmlmap.sql +++ b/test/sql/postgres_regress/xmlmap.sql @@ -3,9 +3,15 @@ CREATE SCHEMA testxmlschema; CREATE TABLE testxmlschema.test1 (a int, b text); INSERT INTO testxmlschema.test1 VALUES (1, 'one'), (2, 'two'), (-1, null); CREATE DOMAIN testxmldomain AS varchar; -CREATE TABLE testxmlschema.test2 (z int, y varchar(500), x char(6), w numeric(9,2), v smallint, u bigint, t real, s time, r timestamp, q date, p xml, o testxmldomain, n bool, m bytea, aaa text); +CREATE TABLE testxmlschema.test2 (z int, y varchar(500), x char(6), + w numeric(9,2), v smallint, u bigint, t real, + s time, stz timetz, r timestamp, rtz timestamptz, q date, + p xml, o testxmldomain, n bool, m bytea, aaa text); ALTER TABLE testxmlschema.test2 DROP COLUMN aaa; -INSERT INTO testxmlschema.test2 VALUES (55, 'abc', 'def', 98.6, 2, 999, 0, '21:07', '2009-06-08 21:07:30', '2009-06-08', NULL, 'ABC', true, 'XYZ'); +INSERT INTO testxmlschema.test2 VALUES (55, 'abc', 'def', + 98.6, 2, 999, 0, + '21:07', '21:11 +05', '2009-06-08 21:07:30', '2009-06-08 21:07:30 -07', '2009-06-08', + NULL, 'ABC', true, 'XYZ'); SELECT table_to_xml('testxmlschema.test1', false, false, ''); SELECT table_to_xml('testxmlschema.test1', true, false, 'foo');