From e4032fc422e3211ff8e96e79b48bc7e78a1c5697 Mon Sep 17 00:00:00 2001 From: Vignesh C Date: Wed, 4 Mar 2026 16:28:32 +0530 Subject: [PATCH v58 1/2] Support SET EXCEPT TABLE in ALTER PUBLICATION Extend ALTER PUBLICATION to support SET EXCEPT TABLE for publications defined with FOR ALL TABLES. ALTER PUBLICATION ... SET EXCEPT TABLE is supported to handle cases where a table listed in a publication's EXCEPT clause needs to be attached as a partition. Since partitions cannot appear in the EXCEPT clause, the user must first modify the publication using ALTER PUBLICATION ... SET EXCEPT TABLE before attaching the partition. --- 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 | 8 +++-- src/include/catalog/pg_publication.h | 3 +- src/test/regress/expected/publication.out | 28 +++++++++++++++ src/test/regress/sql/publication.sql | 19 ++++++++++ src/test/subscription/t/037_except.pl | 38 ++++++++++++++++++-- 10 files changed, 186 insertions(+), 35 deletions(-) diff --git a/doc/src/sgml/ref/alter_publication.sgml b/doc/src/sgml/ref/alter_publication.sgml index 028770f2149..d13e128f21e 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: + + TABLE table_and_columns [, ... ] + EXCEPT TABLE [ ONLY ] ( table_name [, ... ] ) + 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 + tables/except tables/schemas in the publication with the specified list; the + existing tables/except 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..ab77f11d7a4 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.")); } 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..411e4d0cb7f 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -2318,9 +2318,13 @@ 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 TABLE (", "TABLES IN SCHEMA", "TABLE"); + else if (Matches("ALTER", "PUBLICATION", MatchAny, "SET", "EXCEPT")) + COMPLETE_WITH("TABLE ("); + else if (Matches("ALTER", "PUBLICATION", MatchAny, "SET", "EXCEPT", "TABLE")) + COMPLETE_WITH("("); 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..a50d66a2bd5 100644 --- a/src/test/regress/expected/publication.out +++ b/src/test/regress/expected/publication.out @@ -126,6 +126,10 @@ ALTER PUBLICATION testpub_fortable SET TABLES IN SCHEMA pub_test; Tables from schemas: "pub_test" +-- 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 +217,10 @@ Not-null constraints: regress_publication_user | t | f | t | t | f | f | none | f | (1 row) +-- 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 +262,25 @@ Except Publications: "testpub_foralltables_excepttable" "testpub_foralltables_excepttable1" +-- Fail: EXCEPT TABLE is only allowed with FOR ALL TABLES publications. +CREATE PUBLICATION test_pub_forexcepttable FOR EXCEPT TABLE (testpub_tbl1); +ERROR: EXCEPT TABLE clause allowed only for ALL TABLES PUBLICATION +-- 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 +388,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. 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..ce0ece4abc0 100644 --- a/src/test/regress/sql/publication.sql +++ b/src/test/regress/sql/publication.sql @@ -74,6 +74,9 @@ 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 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 +108,9 @@ SELECT pubname, puballtables FROM pg_publication WHERE pubname = 'testpub_forall \d+ testpub_tbl2 \dRp+ testpub_foralltables +-- 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 +125,19 @@ CREATE PUBLICATION testpub_foralltables_excepttable1 FOR ALL TABLES EXCEPT TABLE -- in the EXCEPT TABLE clause \d testpub_tbl1 +-- Fail: EXCEPT TABLE is only allowed with FOR ALL TABLES publications. +CREATE PUBLICATION test_pub_forexcepttable FOR EXCEPT TABLE (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