ALTER TABLE: warn when actions do not recurse to partitions
Hi Hacker,
This patch is part of a broader effort to make ALTER TABLE actions behave
more consistently with respect to partitioned tables. There has been
ongoing discussion around this area; see [1]/messages/by-id/59FB38EF-FA62-41B7-A082-DDA251B04F9E@gmail.com, which also links to earlier
related threads.
In short, changing ALTER TABLE semantics requires more discussion and
coordination than a single patch can realistically achieve. Before that
larger work happens, I’m following up on [1]/messages/by-id/59FB38EF-FA62-41B7-A082-DDA251B04F9E@gmail.com by trying to clarify the
current behavior, both in documentation and in user-facing feedback.
This patch adds warning messages for sub-commands that appear to recurse
but in fact do not. These currently include:
* SET STATISTICS
* SET/RESET (attribute_option = value)
* ENABLE/DISABLE [ REPLICA | ALWAYS] RULE
* ENABLE/DISABLE ROW LEVEL SECURITY
* NO FORCE / FORCE ROW LEVEL SECURITY
* OWNER TO
* REPLICA IDENTITY
* SET SCHEMA
For example, if a user runs:
```
ALTER TABLE ONLY a_partitioned_table REPLICA IDENTITY FULL;
```
the semantics are clear: only the partitioned table itself is modified.
However, if the user runs the same command without ONLY:
```
ALTER TABLE a_partitioned_table REPLICA IDENTITY FULL;
```
there is potential confusion. From the command syntax alone, it is
reasonable to assume that the change would propagate to child partitions,
but in reality, it does not. Since the ALTER TABLE documentation does not
explicitly spell this out, users often need to test the behavior themselves
to be sure, which is a poor user experience.
With this patch, the command instead emits a warning such as:
```
evantest=# alter table sensor_data replica identity full;
WARNING: REPLICA IDENTITY is only applied to the partitioned table itself
ALTER TABLE
```
This makes the behavior explicit and removes the ambiguity.
For now, I’ve limited the change to REPLICA IDENTITY to see whether there
are objections to this approach. If there are none, I plan to extend the
same warning behavior to the other sub-commands listed above. After that,
users can reasonably assume that an ALTER TABLE partitioned_table
... action will recurse to child partitions unless a warning explicitly
tells them otherwise.
[1]: /messages/by-id/59FB38EF-FA62-41B7-A082-DDA251B04F9E@gmail.com
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
Attachments:
v1-0001-Add-warning-when-ALTER-TABLE-REPLICA-IDENTITY-doe.patchapplication/octet-stream; name=v1-0001-Add-warning-when-ALTER-TABLE-REPLICA-IDENTITY-doe.patchDownload
From 19abb2a52dd778a5c15254f41cb1bae0222747bc Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <lic@highgo.com>
Date: Mon, 12 Jan 2026 16:56:58 +0800
Subject: [PATCH v1] Add warning when ALTER TABLE REPLICA IDENTITY does not
recurse
ALTER TABLE ... REPLICA IDENTITY accepts a recursive form on
partitioned tables, but the change is applied only to the partitioned
table itself and does not propagate to child partitions.
Previously this case was silently accepted, which could mislead users
into assuming that the setting would recurse. Add a warning when
recursion is requested on a partitioned table to make the behavior
explicit and avoid confusion.
This change does not alter semantics; it only provides user-visible
feedback. Similar warnings may be added for other ALTER TABLE
sub-commands with non-recursive behavior in follow-up commits.
Author: Chao Li <lic@highgo.com>
---
src/backend/commands/tablecmds.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index f976c0e5c7e..40a4d308334 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -693,7 +693,7 @@ static void drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid,
DependencyType deptype);
static ObjectAddress ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode);
static void ATExecDropOf(Relation rel, LOCKMODE lockmode);
-static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode);
+static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, bool recurse, LOCKMODE lockmode);
static void ATExecGenericOptions(Relation rel, List *options);
static void ATExecSetRowSecurity(Relation rel, bool rls);
static void ATExecForceNoForceRowSecurity(Relation rel, bool force_rls);
@@ -5227,8 +5227,15 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
ATSimplePermissions(cmd->subtype, rel,
ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_MATVIEW);
pass = AT_PASS_MISC;
- /* This command never recurses */
- /* No command-specific prep needed */
+
+ /*
+ * This command now doesn't recurse, but we want to notify user if
+ * recurse is set
+ *
+ * No command-specific prep needed
+ */
+ if (recurse)
+ cmd->recurse = true;
break;
case AT_EnableTrig: /* ENABLE TRIGGER variants */
case AT_EnableAlwaysTrig:
@@ -5643,7 +5650,8 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab,
ATExecDropOf(rel, lockmode);
break;
case AT_ReplicaIdentity:
- ATExecReplicaIdentity(rel, (ReplicaIdentityStmt *) cmd->def, lockmode);
+ ATExecReplicaIdentity(rel, (ReplicaIdentityStmt *) cmd->def,
+ cmd->recurse, lockmode);
break;
case AT_EnableRowSecurity:
ATExecSetRowSecurity(rel, true);
@@ -18515,12 +18523,16 @@ relation_mark_replica_identity(Relation rel, char ri_type, Oid indexOid,
* ALTER TABLE <name> REPLICA IDENTITY ...
*/
static void
-ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode)
+ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, bool recurse, LOCKMODE lockmode)
{
Oid indexOid;
Relation indexRel;
int key;
+ if (recurse && rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ ereport(WARNING,
+ (errmsg("REPLICA IDENTITY is only applied to the partitioned table itself")));
+
if (stmt->identity_type == REPLICA_IDENTITY_DEFAULT)
{
relation_mark_replica_identity(rel, stmt->identity_type, InvalidOid, true);
--
2.39.5 (Apple Git-154)
On Monday, January 12, 2026, Chao Li <li.evan.chao@gmail.com> wrote:
For now, I’ve limited the change to REPLICA IDENTITY to see whether there
are objections to this approach. If there are none, I plan to extend the
same warning behavior to the other sub-commands listed above. After that,
users can reasonably assume that an ALTER TABLE partitioned_table
... action will recurse to child partitions unless a warning explicitly
tells them otherwise.
It should be a notice, not a warning.
How about indicating how many partitions were affected in the notice and
allowing the absence of such a notice to be the indicator that cascading
did not happen?
David J.
On Mon, Jan 12, 2026 at 9:40 AM David G. Johnston <
david.g.johnston@gmail.com> wrote:
How about indicating how many partitions were affected in the notice and
allowing the absence of such a notice to be the indicator that cascading
did not happen?
I like the idea of number of partitions, but think we need to be more
explicit than people surmising the lack of a notice is significant.
Cheers,
Greg
--
Crunchy Data - https://www.crunchydata.com
Enterprise Postgres Software Products & Tech Support