v6-0002-tablecmds-reject-INHERIT-NO-INHERIT-for-partition.patch
application/octet-stream
Filename: v6-0002-tablecmds-reject-INHERIT-NO-INHERIT-for-partition.patch
Type: application/octet-stream
Part: 1
Patch
Format: format-patch
Series: patch v6-0002
Subject: tablecmds: reject INHERIT / NO INHERIT for partitioned tables earlier
| File | + | − |
|---|---|---|
| src/backend/commands/tablecmds.c | 16 | 15 |
| src/test/regress/expected/alter_table.out | 12 | 3 |
| src/test/regress/sql/alter_table.sql | 6 | 2 |
From 9599ea3e3e6ee9b5168c5e373168340a39729205 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <lic@highgo.com>
Date: Thu, 22 Jan 2026 16:47:58 +0800
Subject: [PATCH v6 2/2] tablecmds: reject INHERIT / NO INHERIT for partitioned
tables earlier
ALTER TABLE ... INHERIT and NO INHERIT are not supported for partitioned
tables and already fail today, but only via ad-hoc checks in command-
specific preparation code or later at execution time.
Reject these commands earlier via ATSimplePermissions(), matching the
handling of other unsupported ALTER TABLE actions on partitioned tables.
This centralizes relation-kind checks in the common permission framework
and produces the standard, consistent error message.
While doing this, fix two related issues in the preparation logic:
- The header comment of ATPrepAddInherit was a stale copy-paste that
described behavior no longer implemented there.
- NO INHERIT previously didn't use ATPrepAddInherit, causing it to reach
execution-time checks unnecessarily. Consolidate preparation into a
shared helper used by both INHERIT and NO INHERIT, ensuring both are
rejected uniformly and as early as possible.
Author: Chao Li <lic@highgo.com>
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Discussion: https://postgr.es/m/CAEoWx2kggo1N2kDH6OSfXHL_5gKg3DqQ0PdNuL4LH4XSTKJ3-g@mail.gmail.com
---
src/backend/commands/tablecmds.c | 31 ++++++++++++-----------
src/test/regress/expected/alter_table.out | 15 ++++++++---
src/test/regress/sql/alter_table.sql | 8 ++++--
3 files changed, 34 insertions(+), 20 deletions(-)
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 3e9f62e9d37..379f4d4ebaf 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -686,7 +686,7 @@ static void ATExecEnableDisableTrigger(Relation rel, const char *trigname,
LOCKMODE lockmode);
static void ATExecEnableDisableRule(Relation rel, const char *rulename,
char fires_when, LOCKMODE lockmode);
-static void ATPrepAddInherit(Relation child_rel);
+static void ATPrepChangeInherit(Relation child_rel);
static ObjectAddress ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode);
static ObjectAddress ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode);
static void drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid,
@@ -5194,16 +5194,16 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
break;
case AT_AddInherit: /* INHERIT */
ATSimplePermissions(cmd->subtype, rel,
- ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
+ ATT_TABLE | ATT_FOREIGN_TABLE);
/* This command never recurses */
- ATPrepAddInherit(rel);
+ ATPrepChangeInherit(rel);
pass = AT_PASS_MISC;
break;
case AT_DropInherit: /* NO INHERIT */
ATSimplePermissions(cmd->subtype, rel,
- ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
+ ATT_TABLE | ATT_FOREIGN_TABLE);
/* This command never recurses */
- /* No command-specific prep needed */
+ ATPrepChangeInherit(rel);
pass = AT_PASS_MISC;
break;
case AT_AlterConstraint: /* ALTER CONSTRAINT */
@@ -17259,14 +17259,14 @@ ATExecEnableDisableRule(Relation rel, const char *rulename,
}
/*
- * ALTER TABLE INHERIT
+ * Prepare to change inheritance.
*
- * Add a parent to the child's parents. This verifies that all the columns and
- * check constraints of the parent appear in the child and that they have the
- * same data types and expressions.
+ * A child table cannot be a typed table or a partition. We don't need to check
+ * partitioned table here, because it has been blocked by ATSimplePermissions in
+ * ATPrepCmd.
*/
static void
-ATPrepAddInherit(Relation child_rel)
+ATPrepChangeInherit(Relation child_rel)
{
if (child_rel->rd_rel->reloftype)
ereport(ERROR,
@@ -17277,14 +17277,15 @@ ATPrepAddInherit(Relation child_rel)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot change inheritance of a partition")));
-
- if (child_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot change inheritance of partitioned table")));
}
/*
+ * ALTER TABLE INHERIT
+ *
+ * Add a parent to the child's parents. This verifies that all the columns and
+ * check constraints of the parent appear in the child and that they have the
+ * same data types and expressions.
+ *
* Return the address of the new parent relation.
*/
static ObjectAddress
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index ac1a7345d0f..27b3518f94c 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -3997,10 +3997,19 @@ CREATE TABLE nonpartitioned (
a int,
b int
);
-ALTER TABLE partitioned INHERIT nonpartitioned;
-ERROR: cannot change inheritance of partitioned table
-ALTER TABLE nonpartitioned INHERIT partitioned;
+ALTER TABLE partitioned INHERIT nonpartitioned; -- fail
+ERROR: ALTER action INHERIT cannot be performed on relation "partitioned"
+DETAIL: This operation is not supported for partitioned tables.
+ALTER TABLE partitioned NO INHERIT nonpartitioned; -- fail
+ERROR: ALTER action NO INHERIT cannot be performed on relation "partitioned"
+DETAIL: This operation is not supported for partitioned tables.
+ALTER TABLE nonpartitioned INHERIT partitioned; -- fail
ERROR: cannot inherit from partitioned table "partitioned"
+CREATE TABLE partitioned_p1 PARTITION OF partitioned FOR VALUES FROM (0, 0) TO (10, 100);
+ALTER TABLE partitioned_p1 INHERIT nonpartitioned; -- fail
+ERROR: cannot change inheritance of a partition
+ALTER TABLE partitioned_p1 NO INHERIT nonpartitioned; -- fail
+ERROR: cannot change inheritance of a partition
-- cannot add NO INHERIT constraint to partitioned tables
ALTER TABLE partitioned ADD CONSTRAINT chk_a CHECK (a > 0) NO INHERIT;
ERROR: cannot add NO INHERIT constraint to partitioned table "partitioned"
diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql
index 417202430a5..24936ecdd34 100644
--- a/src/test/regress/sql/alter_table.sql
+++ b/src/test/regress/sql/alter_table.sql
@@ -2397,8 +2397,12 @@ CREATE TABLE nonpartitioned (
a int,
b int
);
-ALTER TABLE partitioned INHERIT nonpartitioned;
-ALTER TABLE nonpartitioned INHERIT partitioned;
+ALTER TABLE partitioned INHERIT nonpartitioned; -- fail
+ALTER TABLE partitioned NO INHERIT nonpartitioned; -- fail
+ALTER TABLE nonpartitioned INHERIT partitioned; -- fail
+CREATE TABLE partitioned_p1 PARTITION OF partitioned FOR VALUES FROM (0, 0) TO (10, 100);
+ALTER TABLE partitioned_p1 INHERIT nonpartitioned; -- fail
+ALTER TABLE partitioned_p1 NO INHERIT nonpartitioned; -- fail
-- cannot add NO INHERIT constraint to partitioned tables
ALTER TABLE partitioned ADD CONSTRAINT chk_a CHECK (a > 0) NO INHERIT;
--
2.50.1 (Apple Git-155)