From 002c9dd97a0c874fd1693a570383e2dd38cd40d5 Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Fri, 25 Mar 2022 14:29:56 +0100 Subject: [PATCH] Handle sequences in preprocess_pubobj_list Commit 75b1521dae added support for logical replication of sequences, including grammar changes, but it did not update preprocess_pubobj_list accordingly. This can cause segfaults with "continuations", i.e. when command specifies a list of objects: CREATE PUBLICATION p FOR SEQUENCE s1, s2; Reported by Amit Kapila, patch by me. Reported-by: Amit Kapila Discussion: https://postgr.es/m/CAA4eK1JxDNKGBSNTyN-Xj2JRjzFo+ziSqJbjH==vuO0YF_CQrg@mail.gmail.com --- src/backend/parser/gram.y | 27 ++++++++++++++++++++++- src/test/regress/expected/publication.out | 18 +++++++++++++++ src/test/regress/sql/publication.sql | 16 ++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index e327bc735fb..f8301541c91 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -17493,7 +17493,8 @@ preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner) if (pubobj->pubobjtype == PUBLICATIONOBJ_CONTINUATION) pubobj->pubobjtype = prevobjtype; - if (pubobj->pubobjtype == PUBLICATIONOBJ_TABLE) + if (pubobj->pubobjtype == PUBLICATIONOBJ_TABLE || + pubobj->pubobjtype == PUBLICATIONOBJ_SEQUENCE) { /* relation name or pubtable must be set for this type of object */ if (!pubobj->name && !pubobj->pubtable) @@ -17537,6 +17538,30 @@ preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner) errmsg("invalid schema name at or near"), parser_errposition(pubobj->location)); } + else if (pubobj->pubobjtype == PUBLICATIONOBJ_SEQUENCES_IN_SCHEMA || + pubobj->pubobjtype == PUBLICATIONOBJ_SEQUENCES_IN_CUR_SCHEMA) + { + /* WHERE clause is not allowed on a schema object */ + if (pubobj->pubtable && pubobj->pubtable->whereClause) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("WHERE clause not allowed for schema"), + parser_errposition(pubobj->location)); + + /* + * We can distinguish between the different type of schema + * objects based on whether name and pubtable is set. + */ + if (pubobj->name) + pubobj->pubobjtype = PUBLICATIONOBJ_SEQUENCES_IN_SCHEMA; + else if (!pubobj->name && !pubobj->pubtable) + pubobj->pubobjtype = PUBLICATIONOBJ_SEQUENCES_IN_CUR_SCHEMA; + else + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid schema name at or near"), + parser_errposition(pubobj->location)); + } prevobjtype = pubobj->pubobjtype; } diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out index 92f6122d409..a5a519d6c87 100644 --- a/src/test/regress/expected/publication.out +++ b/src/test/regress/expected/publication.out @@ -319,6 +319,24 @@ Publications: DROP SEQUENCE testpub_seq0, pub_test.testpub_seq1, testpub_seq2; DROP PUBLICATION testpub_forallsequences, testpub_forsequence, testpub_forschema; +-- publication testing multiple sequences at the same time +CREATE SEQUENCE testpub_seq1; +CREATE SEQUENCE testpub_seq2; +SET client_min_messages = 'ERROR'; +CREATE PUBLICATION testpub_multi FOR SEQUENCE testpub_seq1, testpub_seq2; +RESET client_min_messages; +\dRp+ testpub_multi + Publication testpub_multi + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Sequences | Via root +--------------------------+------------+---------------+---------+---------+---------+-----------+-----------+---------- + regress_publication_user | f | f | t | t | t | t | t | f +Sequences: + "public.testpub_seq1" + "public.testpub_seq2" + +DROP PUBLICATION testpub_multi; +DROP SEQUENCE testpub_seq1; +DROP SEQUENCE testpub_seq2; -- Publication mixing tables and sequences SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_mix; diff --git a/src/test/regress/sql/publication.sql b/src/test/regress/sql/publication.sql index c195e75c6f0..151b8be14ed 100644 --- a/src/test/regress/sql/publication.sql +++ b/src/test/regress/sql/publication.sql @@ -167,6 +167,22 @@ SELECT pubname, puballtables, puballsequences FROM pg_publication WHERE pubname DROP SEQUENCE testpub_seq0, pub_test.testpub_seq1, testpub_seq2; DROP PUBLICATION testpub_forallsequences, testpub_forsequence, testpub_forschema; + +-- publication testing multiple sequences at the same time +CREATE SEQUENCE testpub_seq1; +CREATE SEQUENCE testpub_seq2; + +SET client_min_messages = 'ERROR'; +CREATE PUBLICATION testpub_multi FOR SEQUENCE testpub_seq1, testpub_seq2; +RESET client_min_messages; + +\dRp+ testpub_multi + +DROP PUBLICATION testpub_multi; +DROP SEQUENCE testpub_seq1; +DROP SEQUENCE testpub_seq2; + + -- Publication mixing tables and sequences SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_mix;