From 33d0cb5ed12bf5ebdd6f8fe3cd8bd28fc2706bc1 Mon Sep 17 00:00:00 2001 From: Vignesh C Date: Wed, 4 Mar 2026 16:28:32 +0530 Subject: [PATCH v57 1/2] Support SET EXCEPT TABLE in ALTER PUBLICATION Extend ALTER PUBLICATION to support SET EXCEPT TABLE for publications defined with FOR ALL TABLES. --- doc/src/sgml/ref/alter_publication.sgml | 29 ++++++++++----- src/backend/catalog/pg_publication.c | 10 +++--- src/backend/commands/publicationcmds.c | 39 ++++++++++++++------ src/backend/commands/tablecmds.c | 3 +- src/backend/parser/gram.y | 44 +++++++++++++++++++---- src/bin/psql/tab-complete.in.c | 6 ++-- src/include/catalog/pg_publication.h | 3 +- src/test/regress/expected/publication.out | 37 +++++++++++++++++++ src/test/regress/sql/publication.sql | 24 +++++++++++++ src/test/subscription/t/037_except.pl | 38 ++++++++++++++++++-- 10 files changed, 198 insertions(+), 35 deletions(-) diff --git a/doc/src/sgml/ref/alter_publication.sgml b/doc/src/sgml/ref/alter_publication.sgml index 028770f2149..579dd4bfba4 100644 --- a/doc/src/sgml/ref/alter_publication.sgml +++ b/doc/src/sgml/ref/alter_publication.sgml @@ -21,18 +21,24 @@ PostgreSQL documentation -ALTER PUBLICATION name ADD publication_object [, ...] -ALTER PUBLICATION name SET publication_object [, ...] +ALTER PUBLICATION name ADD publication_add_object [, ...] +ALTER PUBLICATION name SET publication_set_object [, ...] ALTER PUBLICATION name DROP publication_drop_object [, ...] ALTER PUBLICATION name SET ( publication_parameter [= value] [, ... ] ) ALTER PUBLICATION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER PUBLICATION name RENAME TO new_name -where publication_object is one of: +where publication_add_object is one of: TABLE table_and_columns [, ... ] TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] +where publication_set_object is one of: + + EXCEPT TABLE [ ONLY ] ( table_name [, ... ] ) + TABLE table_and_columns [, ... ] + TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] + and publication_drop_object is one of: TABLE [ ONLY ] table_name [ * ] [, ... ] @@ -55,11 +61,12 @@ ALTER PUBLICATION name RENAME TO The first three variants change which tables/schemas are part of the publication. The SET clause will replace the list of - tables/schemas in the publication with the specified list; the existing - tables/schemas that were present in the publication will be removed. The - ADD and DROP clauses will add and - remove one or more tables/schemas from the publication. Note that adding - tables/schemas to a publication that is already subscribed to will require an + except tables/tables/schemas in the publication with the specified list; the + existing except tables/tables/schemas that were present in the publication + will be removed. The ADD and DROP + clauses will add and remove one or more tables/schemas from the publication. + Note that adding tables/schemas to a publication that is already subscribed + to will require an ALTER SUBSCRIPTION ... REFRESH PUBLICATION action on the subscribing side in order to become effective. Note also that @@ -222,6 +229,12 @@ ALTER PUBLICATION mypublication ADD TABLE users (user_id, firstname), department Change the set of columns published for a table: ALTER PUBLICATION mypublication SET TABLE users (user_id, firstname, lastname), TABLE departments; + + + + Replace the publication's EXCEPT table list: + +ALTER PUBLICATION mypublication SET EXCEPT TABLE (users, departments); diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index aadc7c202c6..facccbe74ea 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -440,7 +440,7 @@ attnumstoint2vector(Bitmapset *attrs) */ ObjectAddress publication_add_relation(Oid pubid, PublicationRelInfo *pri, - bool if_not_exists) + bool if_not_exists, bool is_alter) { Relation rel; HeapTuple tup; @@ -544,10 +544,12 @@ publication_add_relation(Oid pubid, PublicationRelInfo *pri, /* * Relations excluded via the EXCEPT clause do not need explicit - * invalidation as CreatePublication() function invalidates all relations - * as part of defining a FOR ALL TABLES publication. + * invalidation during CREATE PUBLICATION, as CreatePublication() function + * invalidates all relations as part of defining a FOR ALL TABLES + * publication. For ALTER PUBLICATION, explicit invalidation is still + * required. */ - if (!pri->except) + if (!pri->except || is_alter) { /* * Invalidate relcache so that publication info is rebuilt. diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index 6a3ca4751fa..166fe3b0c3d 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -1272,15 +1272,24 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup, PublicationDropTables(pubid, rels, false); else /* AP_SetObjects */ { - List *oldrelids = GetIncludedPublicationRelations(pubid, - PUBLICATION_PART_ROOT); + bool isexcept = pubform->puballtables; + List *oldrelids; List *delrels = NIL; ListCell *oldlc; - TransformPubWhereClauses(rels, queryString, pubform->pubviaroot); + if (isexcept) + oldrelids = GetExcludedPublicationTables(pubid, + PUBLICATION_PART_ROOT); + else + { + oldrelids = GetIncludedPublicationRelations(pubid, + PUBLICATION_PART_ROOT); - CheckPubRelationColumnList(stmt->pubname, rels, publish_schema, - pubform->pubviaroot); + TransformPubWhereClauses(rels, queryString, pubform->pubviaroot); + + CheckPubRelationColumnList(stmt->pubname, rels, publish_schema, + pubform->pubviaroot); + } /* * To recreate the relation list for the publication, look for @@ -1488,7 +1497,7 @@ AlterPublicationSchemas(AlterPublicationStmt *stmt, */ static void CheckAlterPublication(AlterPublicationStmt *stmt, HeapTuple tup, - List *tables, List *schemaidlist) + List *tables, List *excepttables, List *schemaidlist) { Form_pg_publication pubform = (Form_pg_publication) GETSTRUCT(tup); @@ -1546,6 +1555,14 @@ CheckAlterPublication(AlterPublicationStmt *stmt, HeapTuple tup, NameStr(pubform->pubname)), errdetail("Tables or sequences cannot be added to or dropped from FOR ALL SEQUENCES publications.")); } + + /* Check that user is allowed to manipulate the publication tables. */ + if (excepttables && !pubform->puballtables) + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("publication \"%s\" is not defined as FOR ALL TABLES", + NameStr(pubform->pubname)), + errdetail("EXCEPT Tables cannot be added to publications that are not defined as FOR ALL TABLES.")); } /* @@ -1591,10 +1608,8 @@ AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt) ObjectsInPublicationToOids(stmt->pubobjects, pstate, &relations, &exceptrelations, &schemaidlist); - /* EXCEPT clause is not supported with ALTER PUBLICATION */ - Assert(exceptrelations == NIL); - - CheckAlterPublication(stmt, tup, relations, schemaidlist); + CheckAlterPublication(stmt, tup, relations, exceptrelations, + schemaidlist); heap_freetuple(tup); @@ -1615,6 +1630,7 @@ AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt) errmsg("publication \"%s\" does not exist", stmt->pubname)); + relations = list_concat(relations, exceptrelations); AlterPublicationTables(stmt, tup, relations, pstate->p_sourcetext, schemaidlist != NIL); AlterPublicationSchemas(stmt, tup, schemaidlist); @@ -1953,7 +1969,8 @@ PublicationAddTables(Oid pubid, List *rels, bool if_not_exists, aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(rel->rd_rel->relkind), RelationGetRelationName(rel)); - obj = publication_add_relation(pubid, pub_rel, if_not_exists); + obj = publication_add_relation(pubid, pub_rel, if_not_exists, + (stmt != NULL)); if (stmt) { EventTriggerCollectSimpleCommand(obj, InvalidObjectAddress, diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 85242dcc245..104b2d74d1d 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -20400,7 +20400,8 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd, list_length(exceptpuboids), RelationGetRelationName(attachrel), pubnames.data), - errdetail("The publication EXCEPT clause cannot contain tables that are partitions.")); + errdetail("The publication EXCEPT clause cannot contain tables that are partitions."), + errhint("Modify the publication's EXCEPT clause using ALTER PUBLICATION ... SET EXCEPT TABLE before attaching the table.")); } list_free(exceptpuboids); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 3c3e24324a8..7e99824b8b1 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -207,7 +207,7 @@ static void preprocess_pub_all_objtype_list(List *all_objects_list, bool *all_tables, bool *all_sequences, core_yyscan_t yyscanner); -static void preprocess_pubobj_list(List *pubobjspec_list, +static bool preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner); static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); @@ -10830,12 +10830,19 @@ CreatePublicationStmt: } | CREATE PUBLICATION name FOR pub_obj_list opt_definition { + bool has_except_table; CreatePublicationStmt *n = makeNode(CreatePublicationStmt); n->pubname = $3; n->options = $6; n->pubobjects = (List *) $5; - preprocess_pubobj_list(n->pubobjects, yyscanner); + has_except_table = preprocess_pubobj_list(n->pubobjects, + yyscanner); + if (has_except_table) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("EXCEPT TABLE clause allowed only for ALL TABLES PUBLICATION")); + $$ = (Node *) n; } ; @@ -10933,8 +10940,12 @@ PublicationObjSpec: pub_obj_list: PublicationObjSpec { $$ = list_make1($1); } + | EXCEPT TABLE '(' pub_except_obj_list ')' + { $$ = $4; } | pub_obj_list ',' PublicationObjSpec { $$ = lappend($1, $3); } + | pub_obj_list ',' EXCEPT TABLE '(' pub_except_obj_list ')' + { $$ = list_concat($1,$6); } ; opt_pub_except_clause: @@ -11010,11 +11021,18 @@ AlterPublicationStmt: } | ALTER PUBLICATION name ADD_P pub_obj_list { + bool has_except_table = false; AlterPublicationStmt *n = makeNode(AlterPublicationStmt); n->pubname = $3; n->pubobjects = $5; - preprocess_pubobj_list(n->pubobjects, yyscanner); + has_except_table = preprocess_pubobj_list(n->pubobjects, + yyscanner); + if (has_except_table) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("EXCEPT TABLE clause allowed only for SET clause")); + n->action = AP_AddObjects; $$ = (Node *) n; } @@ -11030,11 +11048,18 @@ AlterPublicationStmt: } | ALTER PUBLICATION name DROP pub_obj_list { + bool has_except_table = false; AlterPublicationStmt *n = makeNode(AlterPublicationStmt); n->pubname = $3; n->pubobjects = $5; - preprocess_pubobj_list(n->pubobjects, yyscanner); + has_except_table = preprocess_pubobj_list(n->pubobjects, + yyscanner); + if (has_except_table) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("EXCEPT TABLE clause allowed only for SET clause")); + n->action = AP_DropObjects; $$ = (Node *) n; } @@ -19880,16 +19905,19 @@ preprocess_pub_all_objtype_list(List *all_objects_list, List **pubobjects, /* * Process pubobjspec_list to check for errors in any of the objects and * convert PUBLICATIONOBJ_CONTINUATION into appropriate PublicationObjSpecType. + * + * Return true if an EXCEPT table is found. */ -static void +static bool preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner) { ListCell *cell; PublicationObjSpec *pubobj; PublicationObjSpecType prevobjtype = PUBLICATIONOBJ_CONTINUATION; + bool foundexcepttable = false; if (!pubobjspec_list) - return; + return false; pubobj = (PublicationObjSpec *) linitial(pubobjspec_list); if (pubobj->pubobjtype == PUBLICATIONOBJ_CONTINUATION) @@ -19926,6 +19954,8 @@ preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner) pubobj->name = NULL; } } + else if (pubobj->pubobjtype == PUBLICATIONOBJ_EXCEPT_TABLE) + foundexcepttable = true; else if (pubobj->pubobjtype == PUBLICATIONOBJ_TABLES_IN_SCHEMA || pubobj->pubobjtype == PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA) { @@ -19960,6 +19990,8 @@ preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner) prevobjtype = pubobj->pubobjtype; } + + return foundexcepttable; } /*---------- diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index f8c0865ca89..b0710a55422 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -2318,9 +2318,11 @@ match_previous_words(int pattern_id, /* ALTER PUBLICATION DROP */ else if (Matches("ALTER", "PUBLICATION", MatchAny, "DROP")) COMPLETE_WITH("TABLES IN SCHEMA", "TABLE"); - /* ALTER PUBLICATION SET */ + /* ALTER PUBLICATION SET */ else if (Matches("ALTER", "PUBLICATION", MatchAny, "SET")) - COMPLETE_WITH("(", "TABLES IN SCHEMA", "TABLE"); + COMPLETE_WITH("(", "EXCEPT", "TABLES IN SCHEMA", "TABLE"); + else if (Matches("ALTER", "PUBLICATION", MatchAny, "SET", "EXCEPT")) + COMPLETE_WITH("TABLE"); else if (Matches("ALTER", "PUBLICATION", MatchAny, "ADD|DROP|SET", "TABLES", "IN", "SCHEMA")) COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_schemas " AND nspname NOT LIKE E'pg\\\\_%%'", diff --git a/src/include/catalog/pg_publication.h b/src/include/catalog/pg_publication.h index e25228713e7..f40c0fe2f95 100644 --- a/src/include/catalog/pg_publication.h +++ b/src/include/catalog/pg_publication.h @@ -198,7 +198,8 @@ extern bool is_schema_publication(Oid pubid); extern bool check_and_fetch_column_list(Publication *pub, Oid relid, MemoryContext mcxt, Bitmapset **cols); extern ObjectAddress publication_add_relation(Oid pubid, PublicationRelInfo *pri, - bool if_not_exists); + bool if_not_exists, + bool is_alter); extern Bitmapset *pub_collist_validate(Relation targetrel, List *columns); extern ObjectAddress publication_add_schema(Oid pubid, Oid schemaid, bool if_not_exists); diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out index 681d2564ed5..72480eecf71 100644 --- a/src/test/regress/expected/publication.out +++ b/src/test/regress/expected/publication.out @@ -126,6 +126,16 @@ ALTER PUBLICATION testpub_fortable SET TABLES IN SCHEMA pub_test; Tables from schemas: "pub_test" +-- fail - can't add an EXCEPT TABLE to 'FOR TABLE' publication +ALTER PUBLICATION testpub_fortable ADD EXCEPT TABLE (testpub_tbl1); +ERROR: EXCEPT TABLE clause allowed only for SET clause +-- fail - can't drop an EXCEPT TABLE from 'FOR TABLE' publication +ALTER PUBLICATION testpub_fortable DROP EXCEPT TABLE (testpub_tbl1); +ERROR: EXCEPT TABLE clause allowed only for SET clause +-- fail - can't set an EXCEPT TABLE to 'FOR TABLE' publication +ALTER PUBLICATION testpub_fortable SET EXCEPT TABLE (testpub_tbl1); +ERROR: publication "testpub_fortable" is not defined as FOR ALL TABLES +DETAIL: EXCEPT Tables cannot be added to publications that are not defined as FOR ALL TABLES. SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA pub_test; -- should be able to create publication with schema and table of the same @@ -213,6 +223,16 @@ Not-null constraints: regress_publication_user | t | f | t | t | f | f | none | f | (1 row) +-- fail - can't add an EXCEPT TABLE to schema publication +ALTER PUBLICATION testpub_forschema ADD EXCEPT TABLE (pub_test.testpub_nopk); +ERROR: EXCEPT TABLE clause allowed only for SET clause +-- fail - can't drop an EXCEPT TABLE from schema publication +ALTER PUBLICATION testpub_forschema DROP EXCEPT TABLE (pub_test.testpub_nopk); +ERROR: EXCEPT TABLE clause allowed only for SET clause +-- fail - can't set an EXCEPT TABLE to schema publication +ALTER PUBLICATION testpub_forschema SET EXCEPT TABLE (pub_test.testpub_nopk); +ERROR: publication "testpub_forschema" is not defined as FOR ALL TABLES +DETAIL: EXCEPT Tables cannot be added to publications that are not defined as FOR ALL TABLES. --------------------------------------------- -- EXCEPT TABLE tests for normal tables --------------------------------------------- @@ -254,6 +274,22 @@ Except Publications: "testpub_foralltables_excepttable" "testpub_foralltables_excepttable1" +-- Replace the publication EXCEPT table list with a specific EXCEPT table. +ALTER PUBLICATION testpub_foralltables_excepttable SET EXCEPT TABLE (testpub_tbl1); +\dRp+ testpub_foralltables_excepttable + Publication testpub_foralltables_excepttable + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Generated columns | Via root | Description +--------------------------+------------+---------------+---------+---------+---------+-----------+-------------------+----------+------------- + regress_publication_user | t | f | t | t | t | t | none | f | +Except tables: + "public.testpub_tbl1" + +-- fail - Dropping EXCEPT table is not supported. +ALTER PUBLICATION testpub_foralltables_excepttable DROP EXCEPT TABLE (testpub_tbl1); +ERROR: EXCEPT TABLE clause allowed only for SET clause +-- fail - Adding EXCEPT table is not supported. +ALTER PUBLICATION testpub_foralltables_excepttable ADD EXCEPT TABLE (testpub_tbl1); +ERROR: EXCEPT TABLE clause allowed only for SET clause RESET client_min_messages; DROP TABLE testpub_tbl2; DROP PUBLICATION testpub_foralltables, testpub_fortable, testpub_forschema, testpub_for_tbl_schema, testpub_foralltables_excepttable, testpub_foralltables_excepttable1; @@ -361,6 +397,7 @@ CREATE TABLE tab_main (a int) PARTITION BY RANGE(a); ALTER TABLE tab_main ATTACH PARTITION testpub_root FOR VALUES FROM (0) TO (200); ERROR: cannot attach table "testpub_root" as partition because it is referenced in publication "testpub8" EXCEPT clause DETAIL: The publication EXCEPT clause cannot contain tables that are partitions. +HINT: Modify the publication's EXCEPT clause using ALTER PUBLICATION ... SET EXCEPT TABLE before attaching the table. RESET client_min_messages; DROP TABLE testpub_root, testpub_part1, tab_main; DROP PUBLICATION testpub8; diff --git a/src/test/regress/sql/publication.sql b/src/test/regress/sql/publication.sql index 405579dad52..3fa86987a34 100644 --- a/src/test/regress/sql/publication.sql +++ b/src/test/regress/sql/publication.sql @@ -74,6 +74,13 @@ ALTER PUBLICATION testpub_fortable DROP TABLES IN SCHEMA pub_test; ALTER PUBLICATION testpub_fortable SET TABLES IN SCHEMA pub_test; \dRp+ testpub_fortable +-- fail - can't add an EXCEPT TABLE to 'FOR TABLE' publication +ALTER PUBLICATION testpub_fortable ADD EXCEPT TABLE (testpub_tbl1); +-- fail - can't drop an EXCEPT TABLE from 'FOR TABLE' publication +ALTER PUBLICATION testpub_fortable DROP EXCEPT TABLE (testpub_tbl1); +-- fail - can't set an EXCEPT TABLE to 'FOR TABLE' publication +ALTER PUBLICATION testpub_fortable SET EXCEPT TABLE (testpub_tbl1); + SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA pub_test; -- should be able to create publication with schema and table of the same @@ -105,6 +112,13 @@ SELECT pubname, puballtables FROM pg_publication WHERE pubname = 'testpub_forall \d+ testpub_tbl2 \dRp+ testpub_foralltables +-- fail - can't add an EXCEPT TABLE to schema publication +ALTER PUBLICATION testpub_forschema ADD EXCEPT TABLE (pub_test.testpub_nopk); +-- fail - can't drop an EXCEPT TABLE from schema publication +ALTER PUBLICATION testpub_forschema DROP EXCEPT TABLE (pub_test.testpub_nopk); +-- fail - can't set an EXCEPT TABLE to schema publication +ALTER PUBLICATION testpub_forschema SET EXCEPT TABLE (pub_test.testpub_nopk); + --------------------------------------------- -- EXCEPT TABLE tests for normal tables --------------------------------------------- @@ -119,6 +133,16 @@ CREATE PUBLICATION testpub_foralltables_excepttable1 FOR ALL TABLES EXCEPT TABLE -- in the EXCEPT TABLE clause \d testpub_tbl1 +-- Replace the publication EXCEPT table list with a specific EXCEPT table. +ALTER PUBLICATION testpub_foralltables_excepttable SET EXCEPT TABLE (testpub_tbl1); +\dRp+ testpub_foralltables_excepttable + +-- fail - Dropping EXCEPT table is not supported. +ALTER PUBLICATION testpub_foralltables_excepttable DROP EXCEPT TABLE (testpub_tbl1); + +-- fail - Adding EXCEPT table is not supported. +ALTER PUBLICATION testpub_foralltables_excepttable ADD EXCEPT TABLE (testpub_tbl1); + RESET client_min_messages; DROP TABLE testpub_tbl2; DROP PUBLICATION testpub_foralltables, testpub_fortable, testpub_forschema, testpub_for_tbl_schema, testpub_foralltables_excepttable, testpub_foralltables_excepttable1; diff --git a/src/test/subscription/t/037_except.pl b/src/test/subscription/t/037_except.pl index 2729df4d5c0..647ae8433ad 100644 --- a/src/test/subscription/t/037_except.pl +++ b/src/test/subscription/t/037_except.pl @@ -152,18 +152,52 @@ $result = $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM child1"); is($result, qq(10), 'check replicated inserts on subscriber'); +$node_publisher->safe_psql('postgres', + "CREATE TABLE tab2 AS SELECT generate_series(1,10) AS a" +); +$node_subscriber->safe_psql('postgres', + "CREATE TABLE tab2 (a int)" +); + +# Replace the EXCEPT TABLE list so that only tab2 is excluded. +$node_publisher->safe_psql('postgres', + "ALTER PUBLICATION tab_pub SET EXCEPT TABLE (tab2)"); + +# Refresh the subscription so the subscriber picks up the updated +# publication definition and initiates table synchronization. +$node_subscriber->safe_psql('postgres', + "ALTER SUBSCRIPTION tab_sub REFRESH PUBLICATION"); + +# Wait for initial table sync to finish +$node_subscriber->wait_for_subscription_sync($node_publisher, + 'tab_sub'); + +# Verify that initial table synchronization does not occur for tables +# listed in the EXCEPT TABLE clause. +$result = + $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM tab2"); +is($result, qq(0), + 'check there is no initial data copied for the tables specified in the EXCEPT TABLE clause'); + +# Verify that table synchronization occurs once tab1 is removed from the +# EXCEPT TABLE clause via SET EXCEPT TABLE. +$result = + $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM tab1"); +is($result, qq(20), + 'check that the data is copied as the tab1 is removed from EXCEPT TABLE clause'); + # cleanup $node_subscriber->safe_psql( 'postgres', qq( DROP SUBSCRIPTION tab_sub; TRUNCATE TABLE tab1; - DROP TABLE parent, parent1, child, child1; + DROP TABLE parent, parent1, child, child1, tab2; )); $node_publisher->safe_psql( 'postgres', qq( DROP PUBLICATION tab_pub; TRUNCATE TABLE tab1; - DROP TABLE parent, parent1, child, child1; + DROP TABLE parent, parent1, child, child1, tab2; )); # ============================================ -- 2.43.0