[PATCH] Skip unpublishable child tables when adding parent to publication
Hi,
I would like to propose a patch that improves the handling of table
inheritance
hierarchies when adding tables to publications for logical replication.
Problem:
Currently, when attempting to add a parent table to a publication using,
the operation fails
with an error if any of the inherited child tables are foreign tables,
temporary tables, or unlogged tables. This makes it difficult to work with
inheritance hierarchies in logical
replication scenarios, as users must manually manage which specific tables
to
include or exclude.
Proposed Solution:
This patch modifies the behavior to automatically skip child tables that
cannot
be replicated, rather than failing the entire operation. When unpublishable
children are encountered, a NOTICE message is issued following the same
format
used by VACUUM and ANALYZE commands:
NOTICE: skipping "table_name" --- cannot add relation to publication
DETAIL: Foreign tables cannot be replicated.
The parent table and any publishable children are successfully added to the
publication.
I've attached the patch for review. Any feedback or suggestions for
improvement
would be greatly appreciated.
Best regards,
Arun
Attachments:
0001-Skip-unpublishable-child-tables-when-adding-parent-t.patchapplication/octet-stream; name=0001-Skip-unpublishable-child-tables-when-adding-parent-t.patchDownload
From 0a6a7201a2cbb396089ded5af33c51a57930824b Mon Sep 17 00:00:00 2001
From: Arunprasad Rajkumar <ar.arunprasad@gmail.com>
Date: Fri, 12 Dec 2025 19:43:38 +0530
Subject: [PATCH] Skip unpublishable child tables when adding parent to
publication
When adding a parent table with INHERITS children to a publication,
automatically skip child tables that cannot be replicated (foreign
tables, temporary tables, and unlogged tables) instead of failing
with an error.
Previously, attempting to add a parent table to a publication would
fail if any of its inherited children were foreign tables, temporary
tables, or unlogged tables, since these relation types cannot be
replicated. This required users to manually manage which tables to
include, making inheritance hierarchies difficult to work with in
logical replication scenarios.
This change modifies OpenTableList() to check each child relation's
publishability using is_publishable_relation() before adding it to
the publication. Unpublishable children are skipped with a NOTICE
message indicating the relation type and reason, while the parent
and any publishable children are successfully added.
The NOTICE messages follow the same format as VACUUM and ANALYZE
commands, with a main message and detailed explanation:
NOTICE: skipping "table_name" --- cannot add relation to publication
DETAIL: Foreign tables cannot be replicated.
This is a backward-compatible change that relaxes restrictions.
Operations that previously failed will now succeed with appropriate
user notifications via NOTICE messages.
---
src/backend/commands/publicationcmds.c | 38 ++++++++++++++++++++
src/test/regress/expected/publication.out | 43 +++++++++++++++++++++++
src/test/regress/sql/publication.sql | 28 +++++++++++++++
3 files changed, 109 insertions(+)
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index a1983508950..a3fac492d25 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -1826,6 +1826,44 @@ OpenTableList(List *tables)
/* find_all_inheritors already got lock */
rel = table_open(childrelid, NoLock);
+
+ /*
+ * Skip child relations that cannot be replicated. When adding
+ * a parent table with INHERITS children to a publication, we
+ * want to include only regular tables and partitioned tables.
+ * Foreign tables and temporary/unlogged tables cannot be
+ * replicated.
+ *
+ * Note: Views, materialized views, and sequences cannot use
+ * INHERITS, so find_all_inheritors() will only return tables
+ * and foreign tables.
+ */
+ if (!is_publishable_relation(rel))
+ {
+ if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ ereport(NOTICE,
+ (errmsg("skipping \"%s\" --- cannot add relation to publication",
+ RelationGetRelationName(rel)),
+ errdetail("Foreign tables cannot be replicated.")));
+ else if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
+ ereport(NOTICE,
+ (errmsg("skipping \"%s\" --- cannot add relation to publication",
+ RelationGetRelationName(rel)),
+ errdetail("Temporary tables cannot be replicated.")));
+ else if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
+ ereport(NOTICE,
+ (errmsg("skipping \"%s\" --- cannot add relation to publication",
+ RelationGetRelationName(rel)),
+ errdetail("Unlogged tables cannot be replicated.")));
+ else
+ ereport(NOTICE,
+ (errmsg("skipping \"%s\" --- cannot add relation to publication",
+ RelationGetRelationName(rel))));
+
+ table_close(rel, NoLock);
+ continue;
+ }
+
pub_rel = palloc_object(PublicationRelInfo);
pub_rel->relation = rel;
/* child inherits WHERE clause from parent */
diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out
index e72d1308967..b34f936f360 100644
--- a/src/test/regress/expected/publication.out
+++ b/src/test/regress/expected/publication.out
@@ -240,6 +240,49 @@ Tables:
DROP TABLE testpub_tbl3, testpub_tbl3a;
DROP PUBLICATION testpub3, testpub4;
+-- Test skipping unpublishable child tables (foreign, temp, unlogged)
+CREATE FOREIGN DATA WRAPPER dummy_fdw;
+CREATE SERVER dummy_server FOREIGN DATA WRAPPER dummy_fdw;
+CREATE TABLE testpub_parent_skip (a int);
+CREATE TABLE testpub_child_regular (a int) INHERITS (testpub_parent_skip);
+NOTICE: merging column "a" with inherited definition
+CREATE FOREIGN TABLE testpub_child_foreign (a int) INHERITS (testpub_parent_skip)
+ SERVER dummy_server;
+NOTICE: merging column "a" with inherited definition
+CREATE TEMP TABLE testpub_child_temp (a int) INHERITS (testpub_parent_skip);
+NOTICE: merging column "a" with inherited definition
+CREATE UNLOGGED TABLE testpub_child_unlogged (a int) INHERITS (testpub_parent_skip);
+NOTICE: merging column "a" with inherited definition
+-- Should skip foreign, temp, and unlogged children with NOTICE
+SET client_min_messages = 'NOTICE';
+CREATE PUBLICATION testpub_skip_child_pub FOR TABLE testpub_parent_skip;
+NOTICE: skipping "testpub_child_foreign" --- cannot add relation to publication
+DETAIL: Foreign tables cannot be replicated.
+NOTICE: skipping "testpub_child_temp" --- cannot add relation to publication
+DETAIL: Temporary tables cannot be replicated.
+NOTICE: skipping "testpub_child_unlogged" --- cannot add relation to publication
+DETAIL: Unlogged tables cannot be replicated.
+WARNING: "wal_level" is insufficient to publish logical changes
+HINT: Set "wal_level" to "logical" before creating subscriptions.
+RESET client_min_messages;
+-- Verify only parent and regular child are in publication
+SELECT * FROM pg_publication_tables
+WHERE pubname = 'testpub_skip_child_pub'
+ORDER BY tablename;
+ pubname | schemaname | tablename | attnames | rowfilter
+------------------------+------------+-----------------------+----------+-----------
+ testpub_skip_child_pub | public | testpub_child_regular | {a} |
+ testpub_skip_child_pub | public | testpub_parent_skip | {a} |
+(2 rows)
+
+DROP PUBLICATION testpub_skip_child_pub;
+DROP TABLE testpub_child_unlogged;
+DROP FOREIGN TABLE testpub_child_foreign;
+DROP TABLE testpub_child_regular;
+DROP TABLE testpub_parent_skip CASCADE;
+NOTICE: drop cascades to table testpub_child_temp
+DROP SERVER dummy_server;
+DROP FOREIGN DATA WRAPPER dummy_fdw;
--- Tests for publications with SEQUENCES
CREATE SEQUENCE regress_pub_seq0;
CREATE SEQUENCE pub_test.regress_pub_seq1;
diff --git a/src/test/regress/sql/publication.sql b/src/test/regress/sql/publication.sql
index 00390aecd47..c0fc2b687b6 100644
--- a/src/test/regress/sql/publication.sql
+++ b/src/test/regress/sql/publication.sql
@@ -120,6 +120,34 @@ RESET client_min_messages;
DROP TABLE testpub_tbl3, testpub_tbl3a;
DROP PUBLICATION testpub3, testpub4;
+-- Test skipping unpublishable child tables (foreign, temp, unlogged)
+CREATE FOREIGN DATA WRAPPER dummy_fdw;
+CREATE SERVER dummy_server FOREIGN DATA WRAPPER dummy_fdw;
+CREATE TABLE testpub_parent_skip (a int);
+CREATE TABLE testpub_child_regular (a int) INHERITS (testpub_parent_skip);
+CREATE FOREIGN TABLE testpub_child_foreign (a int) INHERITS (testpub_parent_skip)
+ SERVER dummy_server;
+CREATE TEMP TABLE testpub_child_temp (a int) INHERITS (testpub_parent_skip);
+CREATE UNLOGGED TABLE testpub_child_unlogged (a int) INHERITS (testpub_parent_skip);
+
+-- Should skip foreign, temp, and unlogged children with NOTICE
+SET client_min_messages = 'NOTICE';
+CREATE PUBLICATION testpub_skip_child_pub FOR TABLE testpub_parent_skip;
+RESET client_min_messages;
+
+-- Verify only parent and regular child are in publication
+SELECT * FROM pg_publication_tables
+WHERE pubname = 'testpub_skip_child_pub'
+ORDER BY tablename;
+
+DROP PUBLICATION testpub_skip_child_pub;
+DROP TABLE testpub_child_unlogged;
+DROP FOREIGN TABLE testpub_child_foreign;
+DROP TABLE testpub_child_regular;
+DROP TABLE testpub_parent_skip CASCADE;
+DROP SERVER dummy_server;
+DROP FOREIGN DATA WRAPPER dummy_fdw;
+
--- Tests for publications with SEQUENCES
CREATE SEQUENCE regress_pub_seq0;
CREATE SEQUENCE pub_test.regress_pub_seq1;
--
2.39.5 (Apple Git-154)
On Fri, Dec 12, 2025 at 7:56 PM Arunprasad Rajkumar
<ar.arunprasad@gmail.com> wrote:
I would like to propose a patch that improves the handling of table inheritance
hierarchies when adding tables to publications for logical replication.Problem:
Currently, when attempting to add a parent table to a publication using, the operation fails
with an error if any of the inherited child tables are foreign tables, temporary tables, or unlogged tables. This makes it difficult to work with inheritance hierarchies in logical
replication scenarios, as users must manually manage which specific tables to
include or exclude.Proposed Solution:
This patch modifies the behavior to automatically skip child tables that cannot
be replicated, rather than failing the entire operation. When unpublishable
children are encountered, a NOTICE message is issued following the same format
used by VACUUM and ANALYZE commands:NOTICE: skipping "table_name" --- cannot add relation to publication
DETAIL: Foreign tables cannot be replicated.
BTW, did you try the similar cases for partitioned tables. For
example, below case for unlogged partition table works for me:
postgres=# CREATE TABLE testpub_parent_skip_1 (a int) PARTITION BY RANGE (a);
CREATE TABLE
postgres=# CREATE TABLE testpub_child_regular_1 PARTITION OF
testpub_parent_skip FOR VALUES FROM (1) TO (10);
ERROR: "testpub_parent_skip" is not partitioned
postgres=# CREATE TABLE testpub_child_regular_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (1) TO (10);
CREATE TABLE
postgres=# CREATE unlogged TABLE testpub_child_temp_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (11) TO (20);
CREATE TABLE
postgres=# CREATE PUBLICATION testpub_skip_child_pub_1 FOR TABLE
testpub_parent_skip_1;
CREATE PUBLICATION
I think the unlogged table is afterwards silently ignored during
replication. You can once check this and foreign table variant.
BTW, for a somewhat related case, we use WARNING, see below:
if (!indexRelation->rd_index->indisvalid)
ereport(WARNING,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("skipping reindex of invalid index \"%s.%s\"",
So, shall we consider raising a WARNING instead of NOTICE?
--
With Regards,
Amit Kapila.
Hello Amit,
Thank you for reviewing the patch and sharing your valuable feedback.
I did not try with a partitioned table.
After your feedback, I tried with temp, unlogged and foreign tables a
partition. See below snippets,
postgres=# CREATE TABLE testpub_parent_skip_1 (a int) PARTITION BY RANGE
(a);
CREATE TABLE
postgres=# CREATE TABLE testpub_child_regular_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (1) TO (10);
CREATE TABLE
postgres=# CREATE temp TABLE testpub_child_temp_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (11) TO (20);
ERROR: cannot create a temporary relation as partition of permanent
relation "testpub_parent_skip_1"
postgres=# CREATE unlogged TABLE testpub_child_unlogged_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (11) TO (20);
CREATE TABLE
postgres=# CREATE EXTENSION IF NOT EXISTS postgres_fdw;
CREATE EXTENSION
postgres=# CREATE SERVER local_server FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'localhost', port '5433', dbname 'postgres');
CREATE SERVER
postgres=# CREATE USER MAPPING FOR CURRENT_USER SERVER local_server OPTIONS
(user 'arajkumar');
postgres=# CREATE TABLE actual_data_table (
a int
);
CREATE TABLE
postgres=# CREATE FOREIGN TABLE testpub_child_foreign_1 (
a int
) SERVER local_server
OPTIONS (schema_name 'public', table_name 'actual_data_table');
CREATE FOREIGN TABLE
postgres=# ALTER TABLE testpub_parent_skip_1 ATTACH PARTITION
testpub_child_foreign_1 FOR VALUES FROM (21) TO (30);
ALTER TABLE
postgres=# CREATE PUBLICATION testpub_skip_child_pub_1 FOR TABLE
testpub_parent_skip_1;
CREATE PUBLICATION
postgres=# SELECT * FROM pg_publication_tables ;
pubname | schemaname | tablename |
attnames | rowfilter
--------------------------+------------+--------------------------+----------+-----------
testpub_skip_child_pub_1 | public | testpub_child_regular_1 | {a}
|
testpub_skip_child_pub_1 | public | testpub_child_unlogged_1 | {a}
|
testpub_skip_child_pub_1 | public | testpub_child_foreign_1 | {a}
|
(3 rows)
I could see FOREIGN TABLE is being added into the publication very similar
to UNLOGGED table.
With the same table setup on publication, I tried creating a SUBSCRIPTION.
It fails with an error,
postgres=# CREATE SUBSCRIPTION my_subscription CONNECTION 'host=localhost
port=5433 dbname=postgres user=arajkumar'
PUBLICATION testpub_skip_child_pub_1;
ERROR: cannot use relation "public.testpub_child_foreign_1" as logical
replication target
DETAIL: This operation is not supported for foreign tables.
However, I could create a SUBSCRIPTION when I change the publication to
PUBLISH_VIA_ROOT_PARITION=true.
On source,
postgres=# ALTER PUBLICATION testpub_skip_child_pub_1
SET(PUBLISH_VIA_PARTITION_ROOT=true);
ALTER PUBLICATION
On Target,
postgres=# CREATE SUBSCRIPTION my_subscription
CONNECTION 'host=localhost port=5433 dbname=postgres user=arajkumar'
PUBLICATION testpub_skip_child_pub_1;
NOTICE: created replication slot "my_subscription" on publisher
CREATE SUBSCRIPTION
But, the table sync worker fails with the following log,
2025-12-15 13:53:28.093 IST [81904] LOG: logical replication table
synchronization worker for subscription "my_subscription", table
"testpub_parent_skip_1" has started
2025-12-15 13:53:28.120 IST [81904] ERROR: could not start initial
contents copy for table "public.testpub_parent_skip_1": ERROR: cannot copy
from foreign table "testpub_child_foreign_1"
DETAIL: Partition "testpub_child_foreign_1" is a foreign table in
partitioned table "testpub_parent_skip_1"
HINT: Try the COPY (SELECT ...) TO variant.
2025-12-15 13:53:28.120 IST [46273] LOG: background worker "logical
replication tablesync worker" (PID 81904) exited with exit code 1
My Observation:
1) Postgres partition with unlogged table as child partition:
- Added into the publication
- Could create subscription and completes initial data sync, but
replication won't work obviously because it is an UNLOGGED table.
2) Postgres partition with foreign table as child partition:
- Added into the publication when PUBLISH_VIA_PARTITION_ROOT=true,
- Could create subscription, but initial data sync fails.
- Probably this could be fixed to work very similar to an UNLOGGED table?
If so, should we allow adding foreign tables into publication in
inheritance as well?
Thanks,
Arun
On Mon, 15 Dec 2025 at 12:27, Amit Kapila <amit.kapila16@gmail.com> wrote:
Show quoted text
On Fri, Dec 12, 2025 at 7:56 PM Arunprasad Rajkumar
<ar.arunprasad@gmail.com> wrote:I would like to propose a patch that improves the handling of table
inheritance
hierarchies when adding tables to publications for logical replication.
Problem:
Currently, when attempting to add a parent table to a publication using,the operation fails
with an error if any of the inherited child tables are foreign tables,
temporary tables, or unlogged tables. This makes it difficult to work with
inheritance hierarchies in logicalreplication scenarios, as users must manually manage which specific
tables to
include or exclude.
Proposed Solution:
This patch modifies the behavior to automatically skip child tables thatcannot
be replicated, rather than failing the entire operation. When
unpublishable
children are encountered, a NOTICE message is issued following the same
format
used by VACUUM and ANALYZE commands:
NOTICE: skipping "table_name" --- cannot add relation to publication
DETAIL: Foreign tables cannot be replicated.BTW, did you try the similar cases for partitioned tables. For
example, below case for unlogged partition table works for me:
postgres=# CREATE TABLE testpub_parent_skip_1 (a int) PARTITION BY RANGE
(a);
CREATE TABLE
postgres=# CREATE TABLE testpub_child_regular_1 PARTITION OF
testpub_parent_skip FOR VALUES FROM (1) TO (10);
ERROR: "testpub_parent_skip" is not partitioned
postgres=# CREATE TABLE testpub_child_regular_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (1) TO (10);
CREATE TABLE
postgres=# CREATE unlogged TABLE testpub_child_temp_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (11) TO (20);
CREATE TABLE
postgres=# CREATE PUBLICATION testpub_skip_child_pub_1 FOR TABLE
testpub_parent_skip_1;
CREATE PUBLICATIONI think the unlogged table is afterwards silently ignored during
replication. You can once check this and foreign table variant.BTW, for a somewhat related case, we use WARNING, see below:
if (!indexRelation->rd_index->indisvalid)
ereport(WARNING,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("skipping reindex of invalid index \"%s.%s\"",So, shall we consider raising a WARNING instead of NOTICE?
--
With Regards,
Amit Kapila.
Hi Amit,
I’ve given some more thought to how the behavior should be with UNLOGGED
and FOREIGN tables.
IMHO, we *should not* allow adding UNLOGGED and FOREIGN tables in either
inheritance or partitioning scenarios to the publication.
Since these table types cannot be replicated, it doesn’t make sense to keep
them as part of a publication — that breaks user expectations.
What are your thoughts?
Thanks,
Arun
On Mon, 15 Dec 2025 at 14:11, Arunprasad Rajkumar <ar.arunprasad@gmail.com>
wrote:
Show quoted text
Hello Amit,
Thank you for reviewing the patch and sharing your valuable feedback.
I did not try with a partitioned table.
After your feedback, I tried with temp, unlogged and foreign tables a
partition. See below snippets,postgres=# CREATE TABLE testpub_parent_skip_1 (a int) PARTITION BY RANGE
(a);
CREATE TABLE
postgres=# CREATE TABLE testpub_child_regular_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (1) TO (10);
CREATE TABLE
postgres=# CREATE temp TABLE testpub_child_temp_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (11) TO (20);
ERROR: cannot create a temporary relation as partition of permanent
relation "testpub_parent_skip_1"
postgres=# CREATE unlogged TABLE testpub_child_unlogged_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (11) TO (20);
CREATE TABLEpostgres=# CREATE EXTENSION IF NOT EXISTS postgres_fdw;
CREATE EXTENSION
postgres=# CREATE SERVER local_server FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'localhost', port '5433', dbname 'postgres');
CREATE SERVER
postgres=# CREATE USER MAPPING FOR CURRENT_USER SERVER local_server OPTIONS
(user 'arajkumar');
postgres=# CREATE TABLE actual_data_table (
a int
);
CREATE TABLE
postgres=# CREATE FOREIGN TABLE testpub_child_foreign_1 (
a int
) SERVER local_server
OPTIONS (schema_name 'public', table_name 'actual_data_table');
CREATE FOREIGN TABLE
postgres=# ALTER TABLE testpub_parent_skip_1 ATTACH PARTITION
testpub_child_foreign_1 FOR VALUES FROM (21) TO (30);
ALTER TABLE
postgres=# CREATE PUBLICATION testpub_skip_child_pub_1 FOR TABLE
testpub_parent_skip_1;
CREATE PUBLICATION
postgres=# SELECT * FROM pg_publication_tables ;
pubname | schemaname | tablename |
attnames | rowfilter--------------------------+------------+--------------------------+----------+-----------
testpub_skip_child_pub_1 | public | testpub_child_regular_1 | {a}
|
testpub_skip_child_pub_1 | public | testpub_child_unlogged_1 | {a}
|
testpub_skip_child_pub_1 | public | testpub_child_foreign_1 | {a}
|
(3 rows)I could see FOREIGN TABLE is being added into the publication very similar
to UNLOGGED table.With the same table setup on publication, I tried creating a SUBSCRIPTION.
It fails with an error,postgres=# CREATE SUBSCRIPTION my_subscription CONNECTION 'host=localhost
port=5433 dbname=postgres user=arajkumar'
PUBLICATION testpub_skip_child_pub_1;
ERROR: cannot use relation "public.testpub_child_foreign_1" as logical
replication target
DETAIL: This operation is not supported for foreign tables.However, I could create a SUBSCRIPTION when I change the publication to
PUBLISH_VIA_ROOT_PARITION=true.
On source,
postgres=# ALTER PUBLICATION testpub_skip_child_pub_1
SET(PUBLISH_VIA_PARTITION_ROOT=true);
ALTER PUBLICATIONOn Target,
postgres=# CREATE SUBSCRIPTION my_subscription
CONNECTION 'host=localhost port=5433 dbname=postgres user=arajkumar'
PUBLICATION testpub_skip_child_pub_1;
NOTICE: created replication slot "my_subscription" on publisher
CREATE SUBSCRIPTIONBut, the table sync worker fails with the following log,
2025-12-15 13:53:28.093 IST [81904] LOG: logical replication table
synchronization worker for subscription "my_subscription", table
"testpub_parent_skip_1" has started
2025-12-15 13:53:28.120 IST [81904] ERROR: could not start initial
contents copy for table "public.testpub_parent_skip_1": ERROR: cannot copy
from foreign table "testpub_child_foreign_1"
DETAIL: Partition "testpub_child_foreign_1" is a foreign table in
partitioned table "testpub_parent_skip_1"
HINT: Try the COPY (SELECT ...) TO variant.
2025-12-15 13:53:28.120 IST [46273] LOG: background worker "logical
replication tablesync worker" (PID 81904) exited with exit code 1My Observation:
1) Postgres partition with unlogged table as child partition:
- Added into the publication
- Could create subscription and completes initial data sync, but
replication won't work obviously because it is an UNLOGGED table.2) Postgres partition with foreign table as child partition:
- Added into the publication when PUBLISH_VIA_PARTITION_ROOT=true,
- Could create subscription, but initial data sync fails.
- Probably this could be fixed to work very similar to an UNLOGGED
table? If so, should we allow adding foreign tables into publication in
inheritance as well?Thanks,
ArunOn Mon, 15 Dec 2025 at 12:27, Amit Kapila <amit.kapila16@gmail.com> wrote:
On Fri, Dec 12, 2025 at 7:56 PM Arunprasad Rajkumar
<ar.arunprasad@gmail.com> wrote:I would like to propose a patch that improves the handling of table
inheritance
hierarchies when adding tables to publications for logical replication.
Problem:
Currently, when attempting to add a parent table to a publicationusing, the operation fails
with an error if any of the inherited child tables are foreign tables,
temporary tables, or unlogged tables. This makes it difficult to work with
inheritance hierarchies in logicalreplication scenarios, as users must manually manage which specific
tables to
include or exclude.
Proposed Solution:
This patch modifies the behavior to automatically skip child tablesthat cannot
be replicated, rather than failing the entire operation. When
unpublishable
children are encountered, a NOTICE message is issued following the same
format
used by VACUUM and ANALYZE commands:
NOTICE: skipping "table_name" --- cannot add relation to publication
DETAIL: Foreign tables cannot be replicated.BTW, did you try the similar cases for partitioned tables. For
example, below case for unlogged partition table works for me:
postgres=# CREATE TABLE testpub_parent_skip_1 (a int) PARTITION BY RANGE
(a);
CREATE TABLE
postgres=# CREATE TABLE testpub_child_regular_1 PARTITION OF
testpub_parent_skip FOR VALUES FROM (1) TO (10);
ERROR: "testpub_parent_skip" is not partitioned
postgres=# CREATE TABLE testpub_child_regular_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (1) TO (10);
CREATE TABLE
postgres=# CREATE unlogged TABLE testpub_child_temp_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (11) TO (20);
CREATE TABLE
postgres=# CREATE PUBLICATION testpub_skip_child_pub_1 FOR TABLE
testpub_parent_skip_1;
CREATE PUBLICATIONI think the unlogged table is afterwards silently ignored during
replication. You can once check this and foreign table variant.BTW, for a somewhat related case, we use WARNING, see below:
if (!indexRelation->rd_index->indisvalid)
ereport(WARNING,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("skipping reindex of invalid index \"%s.%s\"",So, shall we consider raising a WARNING instead of NOTICE?
--
With Regards,
Amit Kapila.
Hello Amit,
I’d be happy to fix the behavior for partitioned tables with UNLOGGED or
FOREIGN descendant tables in a follow-up patch.
In the meantime, I’ve updated the current patch based on your
suggestion(s/NOTICE/WARNING).
Thanks & regards,
Arun
On Mon, 15 Dec 2025 at 15:18, Arunprasad Rajkumar <ar.arunprasad@gmail.com>
wrote:
Show quoted text
Hi Amit,
I’ve given some more thought to how the behavior should be with UNLOGGED
and FOREIGN tables.IMHO, we *should not* allow adding UNLOGGED and FOREIGN tables in either
inheritance or partitioning scenarios to the publication.
Since these table types cannot be replicated, it doesn’t make sense to
keep them as part of a publication — that breaks user expectations.What are your thoughts?
Thanks,
ArunOn Mon, 15 Dec 2025 at 14:11, Arunprasad Rajkumar <ar.arunprasad@gmail.com>
wrote:Hello Amit,
Thank you for reviewing the patch and sharing your valuable feedback.
I did not try with a partitioned table.
After your feedback, I tried with temp, unlogged and foreign tables a
partition. See below snippets,postgres=# CREATE TABLE testpub_parent_skip_1 (a int) PARTITION BY RANGE
(a);
CREATE TABLE
postgres=# CREATE TABLE testpub_child_regular_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (1) TO (10);
CREATE TABLE
postgres=# CREATE temp TABLE testpub_child_temp_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (11) TO (20);
ERROR: cannot create a temporary relation as partition of permanent
relation "testpub_parent_skip_1"
postgres=# CREATE unlogged TABLE testpub_child_unlogged_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (11) TO (20);
CREATE TABLEpostgres=# CREATE EXTENSION IF NOT EXISTS postgres_fdw;
CREATE EXTENSION
postgres=# CREATE SERVER local_server FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'localhost', port '5433', dbname 'postgres');
CREATE SERVER
postgres=# CREATE USER MAPPING FOR CURRENT_USER SERVER local_server OPTIONS
(user 'arajkumar');
postgres=# CREATE TABLE actual_data_table (
a int
);
CREATE TABLE
postgres=# CREATE FOREIGN TABLE testpub_child_foreign_1 (
a int
) SERVER local_server
OPTIONS (schema_name 'public', table_name 'actual_data_table');
CREATE FOREIGN TABLE
postgres=# ALTER TABLE testpub_parent_skip_1 ATTACH PARTITION
testpub_child_foreign_1 FOR VALUES FROM (21) TO (30);
ALTER TABLE
postgres=# CREATE PUBLICATION testpub_skip_child_pub_1 FOR TABLE
testpub_parent_skip_1;
CREATE PUBLICATION
postgres=# SELECT * FROM pg_publication_tables ;
pubname | schemaname | tablename |
attnames | rowfilter--------------------------+------------+--------------------------+----------+-----------
testpub_skip_child_pub_1 | public | testpub_child_regular_1 | {a}
|
testpub_skip_child_pub_1 | public | testpub_child_unlogged_1 | {a}
|
testpub_skip_child_pub_1 | public | testpub_child_foreign_1 | {a}
|
(3 rows)I could see FOREIGN TABLE is being added into the publication very
similar to UNLOGGED table.With the same table setup on publication, I tried creating a
SUBSCRIPTION. It fails with an error,postgres=# CREATE SUBSCRIPTION my_subscription CONNECTION 'host=localhost
port=5433 dbname=postgres user=arajkumar'
PUBLICATION testpub_skip_child_pub_1;
ERROR: cannot use relation "public.testpub_child_foreign_1" as logical
replication target
DETAIL: This operation is not supported for foreign tables.However, I could create a SUBSCRIPTION when I change the publication to
PUBLISH_VIA_ROOT_PARITION=true.
On source,
postgres=# ALTER PUBLICATION testpub_skip_child_pub_1
SET(PUBLISH_VIA_PARTITION_ROOT=true);
ALTER PUBLICATIONOn Target,
postgres=# CREATE SUBSCRIPTION my_subscription
CONNECTION 'host=localhost port=5433 dbname=postgres user=arajkumar'
PUBLICATION testpub_skip_child_pub_1;
NOTICE: created replication slot "my_subscription" on publisher
CREATE SUBSCRIPTIONBut, the table sync worker fails with the following log,
2025-12-15 13:53:28.093 IST [81904] LOG: logical replication table
synchronization worker for subscription "my_subscription", table
"testpub_parent_skip_1" has started
2025-12-15 13:53:28.120 IST [81904] ERROR: could not start initial
contents copy for table "public.testpub_parent_skip_1": ERROR: cannot copy
from foreign table "testpub_child_foreign_1"
DETAIL: Partition "testpub_child_foreign_1" is a foreign table
in partitioned table "testpub_parent_skip_1"
HINT: Try the COPY (SELECT ...) TO variant.
2025-12-15 13:53:28.120 IST [46273] LOG: background worker "logical
replication tablesync worker" (PID 81904) exited with exit code 1My Observation:
1) Postgres partition with unlogged table as child partition:
- Added into the publication
- Could create subscription and completes initial data sync, but
replication won't work obviously because it is an UNLOGGED table.2) Postgres partition with foreign table as child partition:
- Added into the publication when PUBLISH_VIA_PARTITION_ROOT=true,
- Could create subscription, but initial data sync fails.
- Probably this could be fixed to work very similar to an UNLOGGED
table? If so, should we allow adding foreign tables into publication in
inheritance as well?Thanks,
ArunOn Mon, 15 Dec 2025 at 12:27, Amit Kapila <amit.kapila16@gmail.com>
wrote:On Fri, Dec 12, 2025 at 7:56 PM Arunprasad Rajkumar
<ar.arunprasad@gmail.com> wrote:I would like to propose a patch that improves the handling of table
inheritance
hierarchies when adding tables to publications for logical replication.
Problem:
Currently, when attempting to add a parent table to a publicationusing, the operation fails
with an error if any of the inherited child tables are foreign tables,
temporary tables, or unlogged tables. This makes it difficult to work with
inheritance hierarchies in logicalreplication scenarios, as users must manually manage which specific
tables to
include or exclude.
Proposed Solution:
This patch modifies the behavior to automatically skip child tablesthat cannot
be replicated, rather than failing the entire operation. When
unpublishable
children are encountered, a NOTICE message is issued following the
same format
used by VACUUM and ANALYZE commands:
NOTICE: skipping "table_name" --- cannot add relation to publication
DETAIL: Foreign tables cannot be replicated.BTW, did you try the similar cases for partitioned tables. For
example, below case for unlogged partition table works for me:
postgres=# CREATE TABLE testpub_parent_skip_1 (a int) PARTITION BY RANGE
(a);
CREATE TABLE
postgres=# CREATE TABLE testpub_child_regular_1 PARTITION OF
testpub_parent_skip FOR VALUES FROM (1) TO (10);
ERROR: "testpub_parent_skip" is not partitioned
postgres=# CREATE TABLE testpub_child_regular_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (1) TO (10);
CREATE TABLE
postgres=# CREATE unlogged TABLE testpub_child_temp_1 PARTITION OF
testpub_parent_skip_1 FOR VALUES FROM (11) TO (20);
CREATE TABLE
postgres=# CREATE PUBLICATION testpub_skip_child_pub_1 FOR TABLE
testpub_parent_skip_1;
CREATE PUBLICATIONI think the unlogged table is afterwards silently ignored during
replication. You can once check this and foreign table variant.BTW, for a somewhat related case, we use WARNING, see below:
if (!indexRelation->rd_index->indisvalid)
ereport(WARNING,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("skipping reindex of invalid index \"%s.%s\"",So, shall we consider raising a WARNING instead of NOTICE?
--
With Regards,
Amit Kapila.
Attachments:
v2-0001-Skip-unpublishable-descendant-tables-when-adding-.patchapplication/octet-stream; name=v2-0001-Skip-unpublishable-descendant-tables-when-adding-.patchDownload
From 4d6978ba7b7c059508abbd56e027011de6250ea2 Mon Sep 17 00:00:00 2001
From: Arunprasad Rajkumar <ar.arunprasad@gmail.com>
Date: Mon, 15 Dec 2025 12:22:13 +0530
Subject: [PATCH v2] Skip unpublishable descendant tables when adding parent to
publication
When adding a parent table to a publication using CREATE PUBLICATION or
ALTER PUBLICATION ... ADD TABLE, PostgreSQL automatically includes all
descendant tables in the inheritance hierarchy (via find_all_inheritors()).
However, if any descendant is unpublishable (foreign table, temporary table,
or unlogged table), the operation fails with an error.
This commit changes the behavior to skip unpublishable descendants instead
of failing. A WARNING message is issued for each skipped descendant to inform
the user why it was excluded.
Note that this only affects traditional inheritance (INHERITS). Partition
hierarchies use a different code path and are unaffected.
Signed-off-by: Arunprasad Rajkumar <ar.arunprasad@gmail.com>
---
doc/src/sgml/ref/alter_publication.sgml | 3 ++
doc/src/sgml/ref/create_publication.sgml | 8 ++--
src/backend/commands/publicationcmds.c | 38 ++++++++++++++++
src/test/regress/expected/publication.out | 54 +++++++++++++++++++++++
src/test/regress/sql/publication.sql | 37 ++++++++++++++++
5 files changed, 137 insertions(+), 3 deletions(-)
diff --git a/doc/src/sgml/ref/alter_publication.sgml b/doc/src/sgml/ref/alter_publication.sgml
index 028770f2149..c9fc9401866 100644
--- a/doc/src/sgml/ref/alter_publication.sgml
+++ b/doc/src/sgml/ref/alter_publication.sgml
@@ -125,6 +125,9 @@ ALTER PUBLICATION <replaceable class="parameter">name</replaceable> RENAME TO <r
specified, the table and all its descendant tables (if any) are
affected. Optionally, <literal>*</literal> can be specified after the table
name to explicitly indicate that descendant tables are included.
+ Descendant tables that cannot be replicated (foreign tables, temporary
+ tables, or unlogged tables) are automatically skipped with a warning
+ message.
</para>
<para>
diff --git a/doc/src/sgml/ref/create_publication.sgml b/doc/src/sgml/ref/create_publication.sgml
index 75a508bebfa..8262d0194cb 100644
--- a/doc/src/sgml/ref/create_publication.sgml
+++ b/doc/src/sgml/ref/create_publication.sgml
@@ -81,9 +81,11 @@ CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
specified, the table and all its descendant tables (if any) are added.
Optionally, <literal>*</literal> can be specified after the table name to
explicitly indicate that descendant tables are included.
- This does not apply to a partitioned table, however. The partitions of
- a partitioned table are always implicitly considered part of the
- publication, so they are never explicitly added to the publication.
+ Descendant tables that cannot be replicated (foreign tables, temporary
+ tables, or unlogged tables) are automatically skipped with a warning
+ message. This does not apply to a partitioned table, however. The
+ partitions of a partitioned table are always implicitly considered part
+ of the publication, so they are never explicitly added to the publication.
</para>
<para>
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index a1983508950..32cc6fc8b45 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -1826,6 +1826,44 @@ OpenTableList(List *tables)
/* find_all_inheritors already got lock */
rel = table_open(childrelid, NoLock);
+
+ /*
+ * Skip descendant relations that cannot be replicated. When
+ * adding a parent table with INHERITS descendants to a
+ * publication, we want to include only regular tables and
+ * partitioned tables. Foreign tables and temporary/unlogged
+ * tables cannot be replicated.
+ *
+ * Note: Views, materialized views, and sequences cannot use
+ * INHERITS, so find_all_inheritors() will only return tables
+ * and foreign tables.
+ */
+ if (!is_publishable_relation(rel))
+ {
+ if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ ereport(WARNING,
+ (errmsg("skipping \"%s\" --- cannot add relation to publication",
+ RelationGetRelationName(rel)),
+ errdetail("Foreign tables cannot be replicated.")));
+ else if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
+ ereport(WARNING,
+ (errmsg("skipping \"%s\" --- cannot add relation to publication",
+ RelationGetRelationName(rel)),
+ errdetail("Temporary tables cannot be replicated.")));
+ else if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
+ ereport(WARNING,
+ (errmsg("skipping \"%s\" --- cannot add relation to publication",
+ RelationGetRelationName(rel)),
+ errdetail("Unlogged tables cannot be replicated.")));
+ else
+ ereport(WARNING,
+ (errmsg("skipping \"%s\" --- cannot add relation to publication",
+ RelationGetRelationName(rel))));
+
+ table_close(rel, NoLock);
+ continue;
+ }
+
pub_rel = palloc_object(PublicationRelInfo);
pub_rel->relation = rel;
/* child inherits WHERE clause from parent */
diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out
index e72d1308967..c7c0dad82b9 100644
--- a/src/test/regress/expected/publication.out
+++ b/src/test/regress/expected/publication.out
@@ -240,6 +240,60 @@ Tables:
DROP TABLE testpub_tbl3, testpub_tbl3a;
DROP PUBLICATION testpub3, testpub4;
+-- Test skipping unpublishable descendant tables (foreign, temp, unlogged)
+-- with nested inheritance hierarchy
+CREATE FOREIGN DATA WRAPPER dummy_fdw;
+CREATE SERVER dummy_server FOREIGN DATA WRAPPER dummy_fdw;
+CREATE TABLE testpub_parent_skip (a int);
+CREATE TABLE testpub_child_regular (a int) INHERITS (testpub_parent_skip);
+NOTICE: merging column "a" with inherited definition
+CREATE FOREIGN TABLE testpub_child_foreign (a int) INHERITS (testpub_parent_skip)
+ SERVER dummy_server;
+NOTICE: merging column "a" with inherited definition
+-- Regular table inheriting from foreign table should still be added
+CREATE TABLE testpub_child_foreign_child (b int) INHERITS (testpub_child_foreign);
+CREATE TEMP TABLE testpub_child_temp (a int) INHERITS (testpub_parent_skip);
+NOTICE: merging column "a" with inherited definition
+-- Regular table inheriting from temp table is not allowed.
+-- CREATE TABLE testpub_child_temp_child (c int) INHERITS (testpub_child_temp);
+CREATE UNLOGGED TABLE testpub_child_unlogged (a int) INHERITS (testpub_parent_skip);
+NOTICE: merging column "a" with inherited definition
+-- Regular table inheriting from unlogged table should still be added
+CREATE TABLE testpub_child_unlogged_child (d int) INHERITS (testpub_child_unlogged);
+-- Should skip foreign, temp, and unlogged descendants with WARNING
+SET client_min_messages = 'NOTICE';
+CREATE PUBLICATION testpub_skip_unpublishable_child FOR TABLE testpub_parent_skip;
+WARNING: skipping "testpub_child_foreign" --- cannot add relation to publication
+DETAIL: Foreign tables cannot be replicated.
+WARNING: skipping "testpub_child_temp" --- cannot add relation to publication
+DETAIL: Temporary tables cannot be replicated.
+WARNING: skipping "testpub_child_unlogged" --- cannot add relation to publication
+DETAIL: Unlogged tables cannot be replicated.
+WARNING: "wal_level" is insufficient to publish logical changes
+HINT: Set "wal_level" to "logical" before creating subscriptions.
+RESET client_min_messages;
+-- Verify only parent and regular descendants are in publication
+SELECT * FROM pg_publication_tables
+WHERE pubname = 'testpub_skip_unpublishable_child'
+ORDER BY tablename;
+ pubname | schemaname | tablename | attnames | rowfilter
+----------------------------------+------------+------------------------------+----------+-----------
+ testpub_skip_unpublishable_child | public | testpub_child_foreign_child | {a,b} |
+ testpub_skip_unpublishable_child | public | testpub_child_regular | {a} |
+ testpub_skip_unpublishable_child | public | testpub_child_unlogged_child | {a,d} |
+ testpub_skip_unpublishable_child | public | testpub_parent_skip | {a} |
+(4 rows)
+
+DROP PUBLICATION testpub_skip_unpublishable_child;
+DROP TABLE testpub_child_unlogged_child;
+DROP TABLE testpub_child_unlogged;
+DROP TABLE testpub_child_foreign_child;
+DROP FOREIGN TABLE testpub_child_foreign;
+DROP TABLE testpub_child_regular;
+DROP TABLE testpub_parent_skip CASCADE;
+NOTICE: drop cascades to table testpub_child_temp
+DROP SERVER dummy_server;
+DROP FOREIGN DATA WRAPPER dummy_fdw;
--- Tests for publications with SEQUENCES
CREATE SEQUENCE regress_pub_seq0;
CREATE SEQUENCE pub_test.regress_pub_seq1;
diff --git a/src/test/regress/sql/publication.sql b/src/test/regress/sql/publication.sql
index 00390aecd47..06f12f97cca 100644
--- a/src/test/regress/sql/publication.sql
+++ b/src/test/regress/sql/publication.sql
@@ -120,6 +120,43 @@ RESET client_min_messages;
DROP TABLE testpub_tbl3, testpub_tbl3a;
DROP PUBLICATION testpub3, testpub4;
+-- Test skipping unpublishable descendant tables (foreign, temp, unlogged)
+-- with nested inheritance hierarchy
+CREATE FOREIGN DATA WRAPPER dummy_fdw;
+CREATE SERVER dummy_server FOREIGN DATA WRAPPER dummy_fdw;
+CREATE TABLE testpub_parent_skip (a int);
+CREATE TABLE testpub_child_regular (a int) INHERITS (testpub_parent_skip);
+CREATE FOREIGN TABLE testpub_child_foreign (a int) INHERITS (testpub_parent_skip)
+ SERVER dummy_server;
+-- Regular table inheriting from foreign table should still be added
+CREATE TABLE testpub_child_foreign_child (b int) INHERITS (testpub_child_foreign);
+CREATE TEMP TABLE testpub_child_temp (a int) INHERITS (testpub_parent_skip);
+-- Regular table inheriting from temp table is not allowed.
+-- CREATE TABLE testpub_child_temp_child (c int) INHERITS (testpub_child_temp);
+CREATE UNLOGGED TABLE testpub_child_unlogged (a int) INHERITS (testpub_parent_skip);
+-- Regular table inheriting from unlogged table should still be added
+CREATE TABLE testpub_child_unlogged_child (d int) INHERITS (testpub_child_unlogged);
+
+-- Should skip foreign, temp, and unlogged descendants with WARNING
+SET client_min_messages = 'NOTICE';
+CREATE PUBLICATION testpub_skip_unpublishable_child FOR TABLE testpub_parent_skip;
+RESET client_min_messages;
+
+-- Verify only parent and regular descendants are in publication
+SELECT * FROM pg_publication_tables
+WHERE pubname = 'testpub_skip_unpublishable_child'
+ORDER BY tablename;
+
+DROP PUBLICATION testpub_skip_unpublishable_child;
+DROP TABLE testpub_child_unlogged_child;
+DROP TABLE testpub_child_unlogged;
+DROP TABLE testpub_child_foreign_child;
+DROP FOREIGN TABLE testpub_child_foreign;
+DROP TABLE testpub_child_regular;
+DROP TABLE testpub_parent_skip CASCADE;
+DROP SERVER dummy_server;
+DROP FOREIGN DATA WRAPPER dummy_fdw;
+
--- Tests for publications with SEQUENCES
CREATE SEQUENCE regress_pub_seq0;
CREATE SEQUENCE pub_test.regress_pub_seq1;
--
2.39.5 (Apple Git-154)
On Mon, Dec 15, 2025, at 3:57 AM, Amit Kapila wrote:
I think the unlogged table is afterwards silently ignored during
replication.
Is it an acceptable behavior? I'm not sure. Even if you are using an allowed
object (partitioned table), the replication happens using a partition (that can
or cannot be a supported relation kind). Hence, if this partition is a
temporary or unlogged table, the publication could not be created or modified.
Adding a WARNING is not sufficient. If you run an automated script, it is
easily ignored by the user. The strict behavior should be disallow relations
that are not supported for logical replication. It also includes changing the
relation kind (ALTER TABLE ... SET LOGGED|UNLOGGED). It guarantees that every
data in the tables for that publication is replicated. It means no surprises like
# publisher
cat << EOF | psql -f - -p 5432 -d postgres
CREATE TABLE test_parted (a integer primary key, b integer) PARTITION BY RANGE (a);
CREATE TABLE test_parted_100 (LIKE test_parted);
CREATE TABLE test_parted_200 (LIKE test_parted);
CREATE UNLOGGED TABLE test_parted_300 (LIKE test_parted);
ALTER TABLE test_parted ATTACH PARTITION test_parted_100 FOR VALUES FROM (0) TO (101);
ALTER TABLE test_parted ATTACH PARTITION test_parted_200 FOR VALUES FROM (101) TO (201);
ALTER TABLE test_parted ATTACH PARTITION test_parted_300 FOR VALUES FROM (201) TO (301);
CREATE PUBLICATION pub_parted FOR TABLE test_parted WITH (publish_via_partition_root = true);
EOF
# subscriber
psql -X -c "CREATE TABLE test_parted (a integer primary key, b integer)" -p 9876 -d postgres
psql -X -c "CREATE SUBSCRIPTION sub_parted CONNECTION 'port=5432 dbname=postgres' PUBLICATION pub_parted" -p 9876 -d postgres
# publisher
psql -X -c "INSERT INTO test_parted (a, b) VALUES(50, 1)" -p 5432 -d postgres
psql -X -c "INSERT INTO test_parted (a, b) VALUES(150, 1)" -p 5432 -d postgres
psql -X -c "INSERT INTO test_parted (a, b) VALUES(250, 1)" -p 5432 -d postgres
psql -X -c "SELECT * FROM test_parted" -p 5432 -d postgres
a | b
-----+---
50 | 1
150 | 1
250 | 1
(3 rows)
# subscriber
psql -X -c 'SELECT * FROM test_parted' -p 9876 -d postgres
a | b
-----+---
50 | 1
150 | 1
(2 rows)
Ugh. Where is the missing row? After some investigation, that partition is
unlogged. (Although I used publish_via_partition_root in this example, it also
happens without it.)
What is the implication for prohibiting publication to be created in this
partitioned table case? The only scenario I have in mind is an ETL routine to
load data using unlogged tables. Even if you consider this scenario, you can
adjust the commands to attach the partition *after* loading and setting the
table from unlogged to logged.
There is also the FOR ALL TABLES case. The manual says
Marks the publication as one that replicates changes for all tables in the
database, including tables created in the future.
It says nothing about relation kind. This is an oversight. FOR TABLE and FOR
TABLES IN SCHEMA mention about the unsupported relations. One suggestion is to
avoid repeating the same sentence in each clause and add it to the command
description. Maybe using a <note>...</note>.
Regarding the FOR ALL TABLES behavior, should it prohibit creating/attaching a
partition for an unsupported relation? Different from the FOR TABLE clause that
you have a specified relation, in this case you don't one. It means you could
have an error for regular commands (CREATE TABLE or ALTER TABLE ... SET
UNLOGGED) if you simply have a publication with FOR ALL TABLES. This change
might break routines that are working today and I think that is a bad idea. A
reasonable solution is to ignore the unsupported objects. It means a
partitioned table that has a single unlogged table as a partition will be
ignored. It changes the current behavior to have "all or nothing" instead of
"some". IMO it is easier to detect an issue if the partitioned table is empty
then if there is just partial data in it.
In summary, I think we should prohibit adding a partitioned table to a
publication if there is any unsupported relation that is a partition of it. The
FOR ALL TABLES ignores the partitioned table if there is any unsupported
relation. Opinions?
--
Euler Taveira
EDB https://www.enterprisedb.com/
On Tuesday, December 16, 2025 7:28 AM Euler Taveira <euler@eulerto.com> wrote:
On Mon, Dec 15, 2025, at 3:57 AM, Amit Kapila wrote:
I think the unlogged table is afterwards silently ignored during
replication.There is also the FOR ALL TABLES case. The manual says
Marks the publication as one that replicates changes for all tables in the
database, including tables created in the future.It says nothing about relation kind. This is an oversight. FOR TABLE and FOR
TABLES IN SCHEMA mention about the unsupported relations. One suggestion
is to
avoid repeating the same sentence in each clause and add it to the command
description. Maybe using a <note>...</note>.Regarding the FOR ALL TABLES behavior, should it prohibit creating/attaching
a
partition for an unsupported relation? Different from the FOR TABLE clause
that
you have a specified relation, in this case you don't one. It means you could
have an error for regular commands (CREATE TABLE or ALTER TABLE ... SET
UNLOGGED) if you simply have a publication with FOR ALL TABLES. This
change
might break routines that are working today and I think that is a bad idea. A
reasonable solution is to ignore the unsupported objects. It means a
partitioned table that has a single unlogged table as a partition will be
ignored. It changes the current behavior to have "all or nothing" instead of
"some". IMO it is easier to detect an issue if the partitioned table is empty
then if there is just partial data in it.In summary, I think we should prohibit adding a partitioned table to a
publication if there is any unsupported relation that is a partition of it. The
FOR ALL TABLES ignores the partitioned table if there is any unsupported
relation. Opinions?
I thought about implementing a rule within publication DDLs to prevent adding
partitioned tables with unsupported partitions to a publication. However, users
can still create problematic partitioned tables later using commands like ATTACH
PARTITION, CREATE PARTITION OF, or ALTER TABLE SET UNLOGGED. These commands are
similar to those that you identified in the FOR ALL TABLES scenario. This raises
uncertainty about how we should address these commands in the FOR single TABLE
scenario. Should we permit these user commands but restrict only adding
unsupported relation to publication, or should we apply restrictions across all
such commands? The former might lead to inconsistency with the FOR ALL TABLES
setting, where unsupported relations are silently ignored.
Best Regards,
Hou zj
Thank you, Zhijie and Euler, for your thoughts.
I’d like to compare the behavior of UNLOGGED, TEMP, and FOREIGN tables with
PostgreSQL streaming (physical) replication. PostgreSQL sets a clear
expectation there: these relations are not made available on the replica.
I think we could follow a similar approach for logical replication. Instead
of disallowing users from indirectly adding unsupported relations (for
example, via partitions or FOR ALL TABLES), we could emit a WARNING
wherever possible and remove inconsistent behavior (e.g., performing an
initial table sync for UNLOGGED tables) [1]/messages/by-id/CACDxuFxLfruvV5w6Zbr9Yy4dg1nhwgO97-tCYQtyyh+T3oDRkg@mail.gmail.com.
IMHO, disallowing users from adding an UNLOGGED or FOREIGN table to an
existing partitioned table that is already part of a publication may break
their business goals. In contrast, excluding such relations from
replication—with clear warnings and documentation—would be less disruptive
while still setting correct expectations.
BTW, trying to access a partitioned table with UNLOGGED table on read
replica throws the following error!
tsdb=> SELECT * FROM test_parted;
ERROR: cannot access temporary or unlogged relations during recovery
Regards,
Arun
[1]: /messages/by-id/CACDxuFxLfruvV5w6Zbr9Yy4dg1nhwgO97-tCYQtyyh+T3oDRkg@mail.gmail.com
/messages/by-id/CACDxuFxLfruvV5w6Zbr9Yy4dg1nhwgO97-tCYQtyyh+T3oDRkg@mail.gmail.com
On Tue, 16 Dec 2025 at 09:21, Zhijie Hou (Fujitsu) <houzj.fnst@fujitsu.com>
wrote:
Show quoted text
On Tuesday, December 16, 2025 7:28 AM Euler Taveira <euler@eulerto.com>
wrote:On Mon, Dec 15, 2025, at 3:57 AM, Amit Kapila wrote:
I think the unlogged table is afterwards silently ignored during
replication.There is also the FOR ALL TABLES case. The manual says
Marks the publication as one that replicates changes for all tables in
the
database, including tables created in the future.
It says nothing about relation kind. This is an oversight. FOR TABLE and
FOR
TABLES IN SCHEMA mention about the unsupported relations. One suggestion
is to
avoid repeating the same sentence in each clause and add it to thecommand
description. Maybe using a <note>...</note>.
Regarding the FOR ALL TABLES behavior, should it prohibit
creating/attaching
a
partition for an unsupported relation? Different from the FOR TABLEclause
that
you have a specified relation, in this case you don't one. It means youcould
have an error for regular commands (CREATE TABLE or ALTER TABLE ... SET
UNLOGGED) if you simply have a publication with FOR ALL TABLES. This
change
might break routines that are working today and I think that is a badidea. A
reasonable solution is to ignore the unsupported objects. It means a
partitioned table that has a single unlogged table as a partition will be
ignored. It changes the current behavior to have "all or nothing"instead of
"some". IMO it is easier to detect an issue if the partitioned table is
empty
then if there is just partial data in it.
In summary, I think we should prohibit adding a partitioned table to a
publication if there is any unsupported relation that is a partition ofit. The
FOR ALL TABLES ignores the partitioned table if there is any unsupported
relation. Opinions?I thought about implementing a rule within publication DDLs to prevent
adding
partitioned tables with unsupported partitions to a publication. However,
users
can still create problematic partitioned tables later using commands like
ATTACH
PARTITION, CREATE PARTITION OF, or ALTER TABLE SET UNLOGGED. These
commands are
similar to those that you identified in the FOR ALL TABLES scenario. This
raises
uncertainty about how we should address these commands in the FOR single
TABLE
scenario. Should we permit these user commands but restrict only adding
unsupported relation to publication, or should we apply restrictions
across all
such commands? The former might lead to inconsistency with the FOR ALL
TABLES
setting, where unsupported relations are silently ignored.Best Regards,
Hou zj
On Tue, Dec 16, 2025 at 9:21 AM Zhijie Hou (Fujitsu)
<houzj.fnst@fujitsu.com> wrote:
On Tuesday, December 16, 2025 7:28 AM Euler Taveira <euler@eulerto.com> wrote:
On Mon, Dec 15, 2025, at 3:57 AM, Amit Kapila wrote:
I think the unlogged table is afterwards silently ignored during
replication.There is also the FOR ALL TABLES case. The manual says
Marks the publication as one that replicates changes for all tables in the
database, including tables created in the future.It says nothing about relation kind. This is an oversight. FOR TABLE and FOR
TABLES IN SCHEMA mention about the unsupported relations. One suggestion
is to
avoid repeating the same sentence in each clause and add it to the command
description. Maybe using a <note>...</note>.Regarding the FOR ALL TABLES behavior, should it prohibit creating/attaching
a
partition for an unsupported relation? Different from the FOR TABLE clause
that
you have a specified relation, in this case you don't one. It means you could
have an error for regular commands (CREATE TABLE or ALTER TABLE ... SET
UNLOGGED) if you simply have a publication with FOR ALL TABLES. This
change
might break routines that are working today and I think that is a bad idea. A
reasonable solution is to ignore the unsupported objects. It means a
partitioned table that has a single unlogged table as a partition will be
ignored. It changes the current behavior to have "all or nothing" instead of
"some". IMO it is easier to detect an issue if the partitioned table is empty
then if there is just partial data in it.In summary, I think we should prohibit adding a partitioned table to a
publication if there is any unsupported relation that is a partition of it. The
FOR ALL TABLES ignores the partitioned table if there is any unsupported
relation. Opinions?I thought about implementing a rule within publication DDLs to prevent adding
partitioned tables with unsupported partitions to a publication. However, users
can still create problematic partitioned tables later using commands like ATTACH
PARTITION, CREATE PARTITION OF, or ALTER TABLE SET UNLOGGED. These commands are
similar to those that you identified in the FOR ALL TABLES scenario. This raises
uncertainty about how we should address these commands in the FOR single TABLE
scenario. Should we permit these user commands but restrict only adding
unsupported relation to publication, or should we apply restrictions across all
such commands? The former might lead to inconsistency with the FOR ALL TABLES
setting, where unsupported relations are silently ignored.
Prohibiting all commands sounds too restrictive in all cases (FOR ALL
TABLES, FOR TABLE, etc.). It would be better if we can disallow
creating a publication when the user explicitly adds such a relation
in a FOR TABLE publication, otherwise raise a WARNING and don't make
it part of publication. The behavior should be the same for both
partition and inherited tables.
--
With Regards,
Amit Kapila.
Hello Amit,
Yes, That's my understanding as well.
The behavior should be the same for both partition and inherited tables.
I'm planning to tackle partition tables in the follow-up patch. What do you
think?
Thanks,
Arun
On Tue, 16 Dec 2025 at 15:04, Amit Kapila <amit.kapila16@gmail.com> wrote:
Show quoted text
On Tue, Dec 16, 2025 at 9:21 AM Zhijie Hou (Fujitsu)
<houzj.fnst@fujitsu.com> wrote:On Tuesday, December 16, 2025 7:28 AM Euler Taveira <euler@eulerto.com>
wrote:
On Mon, Dec 15, 2025, at 3:57 AM, Amit Kapila wrote:
I think the unlogged table is afterwards silently ignored during
replication.There is also the FOR ALL TABLES case. The manual says
Marks the publication as one that replicates changes for all tables
in the
database, including tables created in the future.
It says nothing about relation kind. This is an oversight. FOR TABLE
and FOR
TABLES IN SCHEMA mention about the unsupported relations. One
suggestion
is to
avoid repeating the same sentence in each clause and add it to thecommand
description. Maybe using a <note>...</note>.
Regarding the FOR ALL TABLES behavior, should it prohibit
creating/attaching
a
partition for an unsupported relation? Different from the FOR TABLEclause
that
you have a specified relation, in this case you don't one. It meansyou could
have an error for regular commands (CREATE TABLE or ALTER TABLE ... SET
UNLOGGED) if you simply have a publication with FOR ALL TABLES. This
change
might break routines that are working today and I think that is a badidea. A
reasonable solution is to ignore the unsupported objects. It means a
partitioned table that has a single unlogged table as a partition willbe
ignored. It changes the current behavior to have "all or nothing"
instead of
"some". IMO it is easier to detect an issue if the partitioned table
is empty
then if there is just partial data in it.
In summary, I think we should prohibit adding a partitioned table to a
publication if there is any unsupported relation that is a partitionof it. The
FOR ALL TABLES ignores the partitioned table if there is any
unsupported
relation. Opinions?
I thought about implementing a rule within publication DDLs to prevent
adding
partitioned tables with unsupported partitions to a publication.
However, users
can still create problematic partitioned tables later using commands
like ATTACH
PARTITION, CREATE PARTITION OF, or ALTER TABLE SET UNLOGGED. These
commands are
similar to those that you identified in the FOR ALL TABLES scenario.
This raises
uncertainty about how we should address these commands in the FOR single
TABLE
scenario. Should we permit these user commands but restrict only adding
unsupported relation to publication, or should we apply restrictionsacross all
such commands? The former might lead to inconsistency with the FOR ALL
TABLES
setting, where unsupported relations are silently ignored.
Prohibiting all commands sounds too restrictive in all cases (FOR ALL
TABLES, FOR TABLE, etc.). It would be better if we can disallow
creating a publication when the user explicitly adds such a relation
in a FOR TABLE publication, otherwise raise a WARNING and don't make
it part of publication. The behavior should be the same for both
partition and inherited tables.--
With Regards,
Amit Kapila.
On Tue, Dec 16, 2025, at 6:34 AM, Amit Kapila wrote:
Prohibiting all commands sounds too restrictive in all cases (FOR ALL
TABLES, FOR TABLE, etc.). It would be better if we can disallow
creating a publication when the user explicitly adds such a relation
in a FOR TABLE publication, otherwise raise a WARNING and don't make
it part of publication. The behavior should be the same for both
partition and inherited tables.
WFM. The attached patch checks the partitions too. The behavior is similar to
inherited tables. However, I didn't understand the "otherwise" part. Are you
suggesting to add WARNING in the FOR ALL TABLES and FOR TABLES IN SCHEMA if
there is any unsupported relations?
--
Euler Taveira
EDB https://www.enterprisedb.com/
Attachments:
v1-0001-Fix-unsupported-relations-for-publications.patchtext/x-patch; name="=?UTF-8?Q?v1-0001-Fix-unsupported-relations-for-publications.patch?="Download
From b1bab0a22d811d9d3de457e29ed2d7cae123b108 Mon Sep 17 00:00:00 2001
From: Euler Taveira <euler@eulerto.com>
Date: Tue, 16 Dec 2025 11:30:42 -0300
Subject: [PATCH v1] Fix unsupported relations for publications
Although publication check for unsupported relations for the table list,
it is not checking the partitions of a partitioned table. The
consequence is that data from this partitioned table is not replicated.
Inheritance is already covered because parent and children tables are
included in the publication-relation mapping. There is no test coverage
for this case so add it.
This is not a complete solution. SQL commands that manipulate the
partitioned table (ALTER TABLE ... ATTACH PARTITION, ALTER TABLE ... SET
UNLOGGED, CREATE TABLE ... PARTITION OF) might break this contract.
---
src/backend/catalog/pg_publication.c | 18 +++++++++++---
src/test/regress/expected/publication.out | 29 ++++++++++++++++++++++-
src/test/regress/sql/publication.sql | 24 ++++++++++++++++++-
3 files changed, 66 insertions(+), 5 deletions(-)
diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index 7aa3f179924..306187012fb 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -466,8 +466,23 @@ publication_add_relation(Oid pubid, PublicationRelInfo *pri,
RelationGetRelationName(targetrel), pub->name)));
}
+ /*
+ * Check for supported relation. For partitioned tables, all partitions
+ * should be supported relations too.
+ */
check_publication_add_relation(targetrel);
+ relids = GetPubPartitionOptionRelations(relids, PUBLICATION_PART_ALL,
+ relid);
+ foreach_oid(partoid, relids)
+ {
+ Relation partrel = RelationIdGetRelation(partoid);
+
+ check_publication_add_relation(partrel);
+ RelationClose(partrel);
+ }
+
+
/* Validate and translate column names into a Bitmapset of attnums. */
attnums = pub_collist_validate(pri->relation, pri->columns);
@@ -537,9 +552,6 @@ publication_add_relation(Oid pubid, PublicationRelInfo *pri,
* mentioned in the publication. This is required because we implicitly
* publish the child tables when the parent table is published.
*/
- relids = GetPubPartitionOptionRelations(relids, PUBLICATION_PART_ALL,
- relid);
-
InvalidatePublicationRels(relids);
return myself;
diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out
index e72d1308967..e6638c6e517 100644
--- a/src/test/regress/expected/publication.out
+++ b/src/test/regress/expected/publication.out
@@ -326,6 +326,20 @@ ERROR: invalid publication object list
LINE 1: ...equences_alltables FOR ALL SEQUENCES, ALL TABLES, ALL SEQUEN...
^
DETAIL: ALL SEQUENCES can be specified only once.
+-- Tests for inheritance
+CREATE TABLE testpub_inh (a int);
+CREATE TABLE testpub_inh1 () INHERITS(testpub_inh);
+CREATE TEMPORARY TABLE testpub_inh2 () INHERITS(testpub_inh);
+SET client_min_messages = 'ERROR';
+-- fail - unsupported relation as a child relation
+CREATE PUBLICATION testpub_inh FOR TABLE testpub_inh;
+ERROR: cannot add relation "testpub_inh2" to publication
+DETAIL: This operation is not supported for temporary tables.
+ALTER TABLE testpub_inh2 NO INHERIT testpub_inh;
+CREATE PUBLICATION testpub_inh FOR TABLE testpub_inh;
+RESET client_min_messages;
+DROP TABLE testpub_inh, testpub_inh1, testpub_inh2;
+DROP PUBLICATION testpub_inh;
-- Tests for partitioned tables
SET client_min_messages = 'ERROR';
CREATE PUBLICATION testpub_forparted;
@@ -333,9 +347,22 @@ CREATE PUBLICATION testpub_forparted1;
RESET client_min_messages;
CREATE TABLE testpub_parted1 (LIKE testpub_parted);
CREATE TABLE testpub_parted2 (LIKE testpub_parted);
+CREATE UNLOGGED TABLE testpub_parted3 (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);
+ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted3 FOR VALUES IN (3);
+-- fail - unsupported relation as a partition
+SET client_min_messages = 'ERROR';
+CREATE PUBLICATION testpub_forparted2 FOR TABLE testpub_parted;
+ERROR: cannot add relation "testpub_parted3" to publication
+DETAIL: This operation is not supported for unlogged tables.
+RESET client_min_messages;
+-- fail - unsupported relation as a partition
+ALTER PUBLICATION testpub_forparted ADD TABLE testpub_parted;
+ERROR: cannot add relation "testpub_parted3" to publication
+DETAIL: This operation is not supported for unlogged tables.
+ALTER TABLE testpub_parted DETACH PARTITION testpub_parted3;
-- works despite missing REPLICA IDENTITY, because updates are not replicated
UPDATE testpub_parted1 SET a = 1;
-- only parent is listed as being in publication, not the partition
@@ -373,7 +400,7 @@ HINT: To enable updating the table, set REPLICA IDENTITY using ALTER TABLE.
ALTER PUBLICATION testpub_forparted DROP TABLE testpub_parted;
-- works again, because update is no longer replicated
UPDATE testpub_parted2 SET a = 2;
-DROP TABLE testpub_parted1, testpub_parted2;
+DROP TABLE testpub_parted1, testpub_parted2, testpub_parted3;
DROP PUBLICATION testpub_forparted, testpub_forparted1;
-- Tests for row filters
CREATE TABLE testpub_rf_tbl1 (a integer, b text);
diff --git a/src/test/regress/sql/publication.sql b/src/test/regress/sql/publication.sql
index 00390aecd47..b5a4c291516 100644
--- a/src/test/regress/sql/publication.sql
+++ b/src/test/regress/sql/publication.sql
@@ -166,6 +166,19 @@ CREATE PUBLICATION regress_pub_for_allsequences_alltables FOR ALL SEQUENCES, ALL
-- fail - Specifying ALL SEQUENCES more than once
CREATE PUBLICATION regress_pub_for_allsequences_alltables FOR ALL SEQUENCES, ALL TABLES, ALL SEQUENCES;
+-- Tests for inheritance
+CREATE TABLE testpub_inh (a int);
+CREATE TABLE testpub_inh1 () INHERITS(testpub_inh);
+CREATE TEMPORARY TABLE testpub_inh2 () INHERITS(testpub_inh);
+SET client_min_messages = 'ERROR';
+-- fail - unsupported relation as a child relation
+CREATE PUBLICATION testpub_inh FOR TABLE testpub_inh;
+ALTER TABLE testpub_inh2 NO INHERIT testpub_inh;
+CREATE PUBLICATION testpub_inh FOR TABLE testpub_inh;
+RESET client_min_messages;
+DROP TABLE testpub_inh, testpub_inh1, testpub_inh2;
+DROP PUBLICATION testpub_inh;
+
-- Tests for partitioned tables
SET client_min_messages = 'ERROR';
CREATE PUBLICATION testpub_forparted;
@@ -173,9 +186,18 @@ CREATE PUBLICATION testpub_forparted1;
RESET client_min_messages;
CREATE TABLE testpub_parted1 (LIKE testpub_parted);
CREATE TABLE testpub_parted2 (LIKE testpub_parted);
+CREATE UNLOGGED TABLE testpub_parted3 (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);
+ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted3 FOR VALUES IN (3);
+-- fail - unsupported relation as a partition
+SET client_min_messages = 'ERROR';
+CREATE PUBLICATION testpub_forparted2 FOR TABLE testpub_parted;
+RESET client_min_messages;
+-- fail - unsupported relation as a partition
+ALTER PUBLICATION testpub_forparted ADD TABLE testpub_parted;
+ALTER TABLE testpub_parted DETACH PARTITION testpub_parted3;
-- works despite missing REPLICA IDENTITY, because updates are not replicated
UPDATE testpub_parted1 SET a = 1;
-- only parent is listed as being in publication, not the partition
@@ -195,7 +217,7 @@ 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;
-DROP TABLE testpub_parted1, testpub_parted2;
+DROP TABLE testpub_parted1, testpub_parted2, testpub_parted3;
DROP PUBLICATION testpub_forparted, testpub_forparted1;
-- Tests for row filters
--
2.39.5
Hi Amit,
There seem to be different interpretations of your comment.
I understood it as suggesting that we should show a WARNING when adding a
partition or parent table that has unsupported descendant tables.
I would greatly appreciate some clarification on this point. Thanks a lot.
Regards,
Arun
On Wed, 17 Dec 2025 at 04:43, Euler Taveira <euler@eulerto.com> wrote:
Show quoted text
On Tue, Dec 16, 2025, at 6:34 AM, Amit Kapila wrote:
Prohibiting all commands sounds too restrictive in all cases (FOR ALL
TABLES, FOR TABLE, etc.). It would be better if we can disallow
creating a publication when the user explicitly adds such a relation
in a FOR TABLE publication, otherwise raise a WARNING and don't make
it part of publication. The behavior should be the same for both
partition and inherited tables.WFM. The attached patch checks the partitions too. The behavior is similar
to
inherited tables. However, I didn't understand the "otherwise" part. Are
you
suggesting to add WARNING in the FOR ALL TABLES and FOR TABLES IN SCHEMA if
there is any unsupported relations?--
Euler Taveira
EDB https://www.enterprisedb.com/