v38-0002-Restrict-EXCEPT-TABLE-to-root-partitioned-tables-apporach-3.patch
text/x-patch
Filename: v38-0002-Restrict-EXCEPT-TABLE-to-root-partitioned-tables-apporach-3.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v38-0002
Subject: Restrict EXCEPT TABLE to root partitioned tables
| File | + | − |
|---|---|---|
| doc/src/sgml/ref/create_publication.sgml | 5 | 10 |
| src/backend/catalog/pg_publication.c | 7 | 19 |
| src/backend/commands/tablecmds.c | 9 | 0 |
| src/backend/replication/pgoutput/pgoutput.c | 15 | 24 |
| src/backend/utils/cache/relcache.c | 8 | 5 |
| src/test/subscription/t/037_rep_changes_except_table.pl | 96 | 81 |
From d81ed92c169a86753f426a1049f68198823c34c9 Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Wed, 28 Jan 2026 10:58:56 +0530
Subject: [PATCH v38] Restrict EXCEPT TABLE to root partitioned tables
Only root partitioned tables can be specified in the EXCEPT TABLE clause.
Specifying a root partitioned table excludes all partitions belonging to
that partition hierarchy from publication, irrespective of the option
publish_via_partition_root.
This is based on approach 3 discussed at:
https://www.postgresql.org/message-id/CAJpy0uD81HRrMYr7S-6AV4W2PtbGKM-nf2D89zsoMHJ9jZssUg@mail.gmail.com
This patch is a topup patch on top of 0001 patch.
---
doc/src/sgml/ref/create_publication.sgml | 15 +-
src/backend/catalog/pg_publication.c | 26 +--
src/backend/commands/tablecmds.c | 9 +
src/backend/replication/pgoutput/pgoutput.c | 39 ++--
src/backend/utils/cache/relcache.c | 13 +-
.../t/037_rep_changes_except_table.pl | 177 ++++++++++--------
6 files changed, 140 insertions(+), 139 deletions(-)
diff --git a/doc/src/sgml/ref/create_publication.sgml b/doc/src/sgml/ref/create_publication.sgml
index 1e091bb3c6d..61974f41fd9 100644
--- a/doc/src/sgml/ref/create_publication.sgml
+++ b/doc/src/sgml/ref/create_publication.sgml
@@ -205,16 +205,11 @@ CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
tables are excluded.
</para>
<para>
- For partitioned tables, when <literal>publish_via_partition_root</literal>
- is set to <literal>true</literal>, specifying a root partitioned table in
- <literal>EXCEPT TABLE</literal> excludes it and all its partitions from
- replication. Specifying a leaf partition has no effect, as its changes are
- still replicated via the root partitioned table. When
- <literal>publish_via_partition_root</literal> is set to
- <literal>false</literal>, specifying a root partitioned table has no
- effect, as changes are replicated via the leaf partitions. Specifying a
- leaf partition excludes only that partition from replication. The optional
- <literal>*</literal> has no meaning for partitioned tables.
+ For partitioned tables, only the root partitioned table may be specified
+ in <literal>EXCEPT TABLE</literal>. Doing so excludes the root table and
+ all of its partitions from replication, regardless of the value of
+ <literal>publish_via_partition_root</literal>. The optional
+ <literal>*</literal> has no effect for partitioned tables.
</para>
</listitem>
</varlistentry>
diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index 09c69005122..0fdddd96704 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -469,24 +469,12 @@ publication_add_relation(Oid pubid, PublicationRelInfo *pri,
}
/*
- * Handle the case where a partition is excluded by EXCEPT TABLE while
- * publish_via_partition_root = true.
+ * Handle the case where a partition is excluded by EXCEPT TABLE
*/
- if (pub->alltables && pub->pubviaroot && pri->except &&
- targetrel->rd_rel->relispartition)
- ereport(WARNING,
- (errmsg("partition \"%s\" might be replicated as publish_via_partition_root is \"%s\"",
- RelationGetRelationName(targetrel), "true")));
-
- /*
- * Handle the case where a partitioned table is excluded by EXCEPT TABLE
- * while publish_via_partition_root = false.
- */
- if (pub->alltables && !pub->pubviaroot && pri->except &&
- targetrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(WARNING,
- (errmsg("partitioned table \"%s\" might be replicated as publish_via_partition_root is \"%s\"",
- RelationGetRelationName(targetrel), "false")));
+ if (pub->alltables && pri->except && targetrel->rd_rel->relispartition)
+ ereport(ERROR,
+ (errmsg("partition \"%s\" cannot be excluded using EXCEPT TABLE",
+ RelationGetRelationName(targetrel))));
check_publication_add_relation(targetrel);
@@ -960,8 +948,8 @@ GetAllPublicationRelations(Publication *pub, char relkind)
if (relkind == RELKIND_RELATION)
exceptlist = GetAllPublicationExcludedTables(pubid, pubviaroot ?
- PUBLICATION_PART_ALL :
- PUBLICATION_PART_ROOT);
+ PUBLICATION_PART_ROOT :
+ PUBLICATION_PART_LEAF);
classRel = table_open(RelationRelationId, AccessShareLock);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index a5351fc59c6..395b8c0c2a1 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -20325,6 +20325,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd,
const char *trigger_name;
Oid defaultPartOid;
List *partBoundConstraint;
+ List *except_pubids = NIL;
ParseState *pstate = make_parsestate(NULL);
pstate->p_sourcetext = context->queryString;
@@ -20449,6 +20450,14 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot attach temporary relation of another session as partition")));
+ /* Check if the partiton is part of EXCEPT list of any publication */
+ GetRelationPublications(RelationGetRelid(attachrel), NULL, &except_pubids);
+ if (except_pubids != NIL)
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("cannot attach relation \"%s\" as partition because it is part of EXCEPT list in publication",
+ RelationGetRelationName(attachrel))));
+
/*
* Check if attachrel has any identity columns or any columns that aren't
* in the parent.
diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index 05802482c10..48dcf0fedc4 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -2206,16 +2206,11 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
* root and set the ancestor level accordingly.
*
* If this is a FOR ALL TABLES publication and it has an EXCEPT
- * TABLE list:
- *
- * 1. If pubviaroot is set and the relation is a partition, check
- * whether the partition root is included in the EXCEPT TABLE
- * list. If so, do not publish the change.
- *
- * 2. If pubviaroot is not set, check whether the relation itself
- * is included in the EXCEPT TABLE list. If so, do not publish the
- * change.
- *
+ * TABLE list
+ * 1. For a normal table or a partitioned table, if it is part of
+ * the EXCEPT TABLE list, we don't publish it.
+ * 2. For a partition, if the topmost ancestor is part of
+ * the EXCEPT TABLE list, we don't publish it.
* This is achieved by keeping the variable "publish" set to
* false. And eventually, entry->pubactions will remain all false
* for this publication.
@@ -2223,27 +2218,23 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
if (pub->alltables)
{
List *exceptpubids = NIL;
+ List *ancestors = get_partition_ancestors(relid);
+ Oid root_relid = relid;
- if (pub->pubviaroot && am_partition)
+ if (am_partition)
{
- List *ancestors = get_partition_ancestors(relid);
+ root_relid = llast_oid(ancestors);
+ GetRelationPublications(root_relid, NULL, &exceptpubids);
- pub_relid = llast_oid(ancestors);
- ancestor_level = list_length(ancestors);
+ if (pub->pubviaroot)
+ {
+ pub_relid = root_relid;
+ ancestor_level = list_length(ancestors);
+ }
}
- GetRelationPublications(pub_relid, NULL, &exceptpubids);
-
if (!list_member_oid(exceptpubids, pub->oid))
publish = true;
- else
- {
- /* Sanity check */
- Assert(entry->pubactions.pubinsert == false &&
- entry->pubactions.pubupdate == false &&
- entry->pubactions.pubdelete == false &&
- entry->pubactions.pubtruncate == false);
- }
list_free(exceptpubids);
}
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index dc021dbb6cd..ec7f82fbcdc 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -5837,21 +5837,24 @@ RelationBuildPublicationDesc(Relation relation, PublicationDesc *pubdesc)
/* Add publications that the ancestors are in too. */
ancestors = get_partition_ancestors(relid);
+ /*
+ * Only the topmost ancestor of a partitioned table can be specified
+ * in EXCEPT TABLES clause of a FOR ALL TABLES publication. So fetch
+ * the publications excluding the topmost ancestor only.
+ */
+ GetRelationPublications(llast_oid(ancestors), NULL, &exceptpuboids);
+
foreach(lc, ancestors)
{
Oid ancestor = lfirst_oid(lc);
List *ancestor_puboids = NIL;
- List *ancestor_exceptpuboids = NIL;
- GetRelationPublications(ancestor, &ancestor_puboids,
- &ancestor_exceptpuboids);
+ GetRelationPublications(ancestor, &ancestor_puboids, NULL);
puboids = list_concat_unique_oid(puboids, ancestor_puboids);
schemaid = get_rel_namespace(ancestor);
puboids = list_concat_unique_oid(puboids,
GetSchemaPublications(schemaid));
- exceptpuboids = list_concat_unique_oid(exceptpuboids,
- ancestor_exceptpuboids);
}
}
diff --git a/src/test/subscription/t/037_rep_changes_except_table.pl b/src/test/subscription/t/037_rep_changes_except_table.pl
index 95904ddd005..4c3c81462a5 100644
--- a/src/test/subscription/t/037_rep_changes_except_table.pl
+++ b/src/test/subscription/t/037_rep_changes_except_table.pl
@@ -88,8 +88,11 @@ $node_subscriber->safe_psql('postgres', "DROP SUBSCRIPTION tap_sub_schema");
$node_publisher->safe_psql(
'postgres', qq(
CREATE TABLE sch1.t1(a int) PARTITION BY RANGE(a);
- CREATE TABLE sch1.part1 PARTITION OF sch1.t1 FOR VALUES FROM (0) TO (5);
- CREATE TABLE sch1.part2 PARTITION OF sch1.t1 FOR VALUES FROM (6) TO (10);
+ CREATE TABLE sch1.part1 PARTITION OF sch1.t1 FOR VALUES FROM (0) TO (100);
+ CREATE TABLE sch1.part2(a int) PARTITION BY RANGE(a);
+ CREATE TABLE sch1.part2_1 PARTITION OF sch1.part2 FOR VALUES FROM (101) TO (150);
+ CREATE TABLE sch1.part2_2 PARTITION OF sch1.part2 FOR VALUES FROM (151) TO (200);
+ ALTER TABLE sch1.t1 ATTACH PARTITION sch1.part2 FOR VALUES FROM (101) TO (200);
));
$node_subscriber->safe_psql(
@@ -97,140 +100,152 @@ $node_subscriber->safe_psql(
CREATE TABLE sch1.t1(a int);
CREATE TABLE sch1.part1(a int);
CREATE TABLE sch1.part2(a int);
+ CREATE TABLE sch1.part2_1(a int);
+ CREATE TABLE sch1.part2_2(a int);
));
-# EXCEPT TABLE (sch1.part1) with publish_via_partition_root = false
-# Excluding a partition while publish_via_partition_root = false prevents
-# replication of rows inserted into the partitioned table for that particular
-# partition.
-$node_publisher->safe_psql(
+# Partititions cannot be excluded using EXCEPT TABLE
+my ($stdout, $stderr);
+($result, $stdout, $stderr) = $node_publisher->psql(
'postgres', qq(
- CREATE PUBLICATION tap_pub_part FOR ALL TABLES EXCEPT TABLE (sch1.part1) WITH (publish_via_partition_root = false);
- INSERT INTO sch1.t1 VALUES (1), (6);
+ CREATE PUBLICATION tap_pub_part FOR ALL TABLES EXCEPT TABLE (sch1.part2) WITH (publish_via_partition_root = false);
));
-$node_subscriber->safe_psql('postgres',
- "CREATE SUBSCRIPTION tap_sub_part CONNECTION '$publisher_connstr' PUBLICATION tap_pub_part"
-);
-$node_subscriber->wait_for_subscription_sync($node_publisher, 'tap_sub_part');
-$node_publisher->safe_psql('postgres',
- "INSERT INTO sch1.t1 VALUES (2), (7);");
-$node_publisher->wait_for_catchup('tap_sub_part');
-
-$result = $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.t1");
-is($result, qq(), 'check rows on partitioned table');
+like(
+ $stderr,
+ qr/partition "part2" cannot be excluded using EXCEPT TABLE/,
+ 'partition "part2" cannot be excluded using EXCEPT TABLE');
-$result = $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.part1");
-is($result, qq(), 'check rows on excluded partition');
+($result, $stdout, $stderr) = $node_publisher->psql(
+ 'postgres', qq(
+ CREATE PUBLICATION tap_pub_part FOR ALL TABLES EXCEPT TABLE (sch1.part2) WITH (publish_via_partition_root = true);
+));
+like(
+ $stderr,
+ qr/partition "part2" cannot be excluded using EXCEPT TABLE/,
+ 'partition "part2" cannot be excluded using EXCEPT TABLE');
-$result = $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.part2");
-is( $result, qq(6
-7), 'check rows on other partition');
+($result, $stdout, $stderr) = $node_publisher->psql(
+ 'postgres', qq(
+ CREATE PUBLICATION tap_pub_part FOR ALL TABLES EXCEPT TABLE (sch1.part2_1) WITH (publish_via_partition_root = false);
+));
+like(
+ $stderr,
+ qr/partition "part2_1" cannot be excluded using EXCEPT TABLE/,
+ 'partition "part2_1" cannot be excluded using EXCEPT TABLE');
-$node_publisher->safe_psql('postgres', "TRUNCATE sch1.t1");
-$node_publisher->wait_for_catchup('tap_sub_part');
-$node_subscriber->safe_psql('postgres', "DROP SUBSCRIPTION tap_sub_part");
-$node_publisher->safe_psql('postgres', "DROP PUBLICATION tap_pub_part;");
+($result, $stdout, $stderr) = $node_publisher->psql(
+ 'postgres', qq(
+ CREATE PUBLICATION tap_pub_part FOR ALL TABLES EXCEPT TABLE (sch1.part2_1) WITH (publish_via_partition_root = true);
+));
+like(
+ $stderr,
+ qr/partition "part2_1" cannot be excluded using EXCEPT TABLE/,
+ 'partition "part2_1" cannot be excluded using EXCEPT TABLE');
-# EXCEPT TABLE (sch1.t1) with publish_via_partition_root = false
-# Excluding the partitioned table still allows rows inserted into the
-# partitioned table to be replicated via its partitions.
+# Excluding the root partitioned table excludes all its partitions as well when
+# publish_via_partition_root = false.
$node_publisher->safe_psql(
'postgres', qq(
CREATE PUBLICATION tap_pub_part FOR ALL TABLES EXCEPT TABLE (sch1.t1) WITH (publish_via_partition_root = false);
- INSERT INTO sch1.t1 VALUES (1), (6);
+ INSERT INTO sch1.t1 VALUES (1), (101), (151);
));
$node_subscriber->safe_psql('postgres',
"CREATE SUBSCRIPTION tap_sub_part CONNECTION '$publisher_connstr' PUBLICATION tap_pub_part"
);
$node_subscriber->wait_for_subscription_sync($node_publisher, 'tap_sub_part');
$node_publisher->safe_psql('postgres',
- "INSERT INTO sch1.t1 VALUES (2), (7);");
+ "SELECT slot_name FROM pg_replication_slot_advance('test_slot', pg_current_wal_lsn());"
+);
+$node_publisher->safe_psql('postgres',
+ "INSERT INTO sch1.t1 VALUES (2), (102), (152)");
+
+# Verify that data inserted to the partitioned table is not published when it is
+# excluded with publish_via_partition_root = true.
+$result = $node_publisher->safe_psql('postgres',
+ "SELECT count(*) = 0 FROM pg_logical_slot_get_binary_changes('test_slot', NULL, NULL, 'proto_version', '1', 'publication_names', 'tap_pub_part')"
+);
$node_publisher->wait_for_catchup('tap_sub_part');
+# Check that no rows are replicated to subscriber
$result = $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.t1");
-is($result, qq(), 'check rows on partitioned table');
+is($result, qq(), 'check rows on root table');
$result = $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.part1");
-is( $result, qq(1
-2), 'check rows on first partition');
+is($result, qq(), 'check rows on table sch1.part1');
$result = $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.part2");
-is( $result, qq(6
-7), 'check rows on second partition');
+is($result, qq(), 'check rows on table sch1.part2');
+
+$result =
+ $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.part2_1");
+is($result, qq(), 'check rows on table sch1.part2_1');
+
+$result =
+ $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.part2_2");
+is($result, qq(), 'check rows on table sch1.part2_2');
-$node_publisher->safe_psql('postgres', "TRUNCATE sch1.t1");
-$node_publisher->wait_for_catchup('tap_sub_part');
$node_subscriber->safe_psql('postgres', "DROP SUBSCRIPTION tap_sub_part");
$node_publisher->safe_psql('postgres', "DROP PUBLICATION tap_pub_part;");
-$node_publisher->safe_psql('postgres',
- "SELECT slot_name FROM pg_replication_slot_advance('test_slot', pg_current_wal_lsn());"
-);
-# EXCEPT TABLE (sch1.t1) with publish_via_partition_root = true
-# When the partitioned table is excluded and publish_via_partition_root is true,
-# no rows from the table or its partitions are replicated.
+# Excluding the root partitioned table excludes all its partitions as well when
+# publish_via_partition_root = true.
$node_publisher->safe_psql(
'postgres', qq(
- CREATE PUBLICATION tap_pub_part FOR ALL TABLES EXCEPT TABLE (sch1.t1) WITH (publish_via_partition_root);
- INSERT INTO sch1.t1 VALUES (1), (6);
+ CREATE PUBLICATION tap_pub_part FOR ALL TABLES EXCEPT TABLE (sch1.t1) WITH (publish_via_partition_root = true);
));
$node_subscriber->safe_psql('postgres',
"CREATE SUBSCRIPTION tap_sub_part CONNECTION '$publisher_connstr' PUBLICATION tap_pub_part"
);
$node_subscriber->wait_for_subscription_sync($node_publisher, 'tap_sub_part');
$node_publisher->safe_psql('postgres',
- "INSERT INTO sch1.t1 VALUES (2), (7);");
-$node_publisher->wait_for_catchup('tap_sub_part');
+ "SELECT slot_name FROM pg_replication_slot_advance('test_slot', pg_current_wal_lsn());"
+);
+$node_publisher->safe_psql('postgres',
+ "INSERT INTO sch1.t1 VALUES (3), (103), (153);");
# Verify that data inserted to the partitioned table is not published when it is
# excluded with publish_via_partition_root = true.
$result = $node_publisher->safe_psql('postgres',
"SELECT count(*) = 0 FROM pg_logical_slot_get_binary_changes('test_slot', NULL, NULL, 'proto_version', '1', 'publication_names', 'tap_pub_part')"
);
-is($result, qq(t), 'check no changes for excluded table in replication slot');
+$node_publisher->wait_for_catchup('tap_sub_part');
+# Check that no rows are replicated to subscriber
$result = $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.t1");
-is($result, qq(), 'check rows on partitioned table');
+is($result, qq(), 'check rows on root table');
$result = $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.part1");
-is($result, qq(), 'check rows on first partition');
+is($result, qq(), 'check rows on table sch1.part1');
$result = $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.part2");
-is($result, qq(), 'check rows on second partition');
+is($result, qq(), 'check rows on table sch1.part2');
+
+$result =
+ $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.part2_1");
+is($result, qq(), 'check rows on table sch1.part2_1');
+
+$result =
+ $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.part2_2");
+is($result, qq(), 'check rows on table sch1.part2_2');
-$node_publisher->safe_psql('postgres', "TRUNCATE sch1.t1");
-$node_publisher->wait_for_catchup('tap_sub_part');
$node_subscriber->safe_psql('postgres', "DROP SUBSCRIPTION tap_sub_part");
$node_publisher->safe_psql('postgres', "DROP PUBLICATION tap_pub_part;");
-# EXCEPT TABLE (sch1.part1) with publish_via_partition_root = true
-# When a partition is excluded but publish_via_partition_root is true,
-# rows published through the partitioned table can still be replicated.
-$node_publisher->safe_psql(
+# Cannot attach partition that is part of EXCEPT list in publication
+$node_publisher->safe_psql('postgres',
+ "ALTER TABLE sch1.t1 DETACH PARTITION sch1.part2");
+$node_publisher->safe_psql('postgres',
+ "CREATE PUBLICATION tap_pub_part FOR ALL TABLES EXCEPT TABLE (sch1.part2) WITH (publish_via_partition_root = true)"
+);
+($result, $stdout, $stderr) = $node_publisher->psql(
'postgres', qq(
- CREATE PUBLICATION tap_pub_part FOR ALL TABLES EXCEPT TABLE (sch1.part1) WITH (publish_via_partition_root);
- INSERT INTO sch1.t1 VALUES (1), (6)
+ ALTER TABLE sch1.t1 ATTACH PARTITION sch1.part2 FOR VALUES FROM (101) TO (200);
));
-$node_subscriber->safe_psql('postgres',
- "CREATE SUBSCRIPTION tap_sub_part CONNECTION '$publisher_connstr' PUBLICATION tap_pub_part"
+like(
+ $stderr,
+ qr/cannot attach relation "part2" as partition because it is part of EXCEPT list in publication/,
+ 'cannot attach relation "part2" as partition because it is part of EXCEPT list in publication'
);
-$node_subscriber->wait_for_subscription_sync($node_publisher, 'tap_sub_part');
-$node_publisher->safe_psql('postgres',
- "INSERT INTO sch1.t1 VALUES (2), (7);");
-$node_publisher->wait_for_catchup('tap_sub_part');
-
-$result =
- $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.t1 ORDER BY a");
-is( $result, qq(1
-2
-6
-7), 'check rows on partitioned table');
-
-$result = $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.part1");
-is($result, qq(), 'check rows on excluded partition');
-
-$result = $node_subscriber->safe_psql('postgres', "SELECT * FROM sch1.part2");
-is($result, qq(), 'check rows on other partition');
$node_subscriber->stop('fast');
$node_publisher->stop('fast');
--
2.43.0