From a0e8df527ec24e8dba98f295c0e2ab6ccf3e5d2c Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Wed, 20 Apr 2011 22:49:37 -0400
Subject: [PATCH] Allow ALTER TYPE .. ADD ATTRIBUTE .. CASCADE to recurse to
 descendants.

Without this, adding an attribute to a typed table with an inheritance
child fails, which is surprising.

Noah Misch, with minor changes by me.
---
 doc/src/sgml/ref/alter_type.sgml          |  2 +-
 src/backend/commands/tablecmds.c          |  5 +++--
 src/test/regress/expected/alter_table.out | 15 +++++++++++++++
 src/test/regress/sql/alter_table.sql      |  4 ++++
 4 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/doc/src/sgml/ref/alter_type.sgml b/doc/src/sgml/ref/alter_type.sgml
index e889ffbc352..a417c0d01b3 100644
--- a/doc/src/sgml/ref/alter_type.sgml
+++ b/doc/src/sgml/ref/alter_type.sgml
@@ -122,7 +122,7 @@ ALTER TYPE <replaceable class="PARAMETER">name</replaceable> ADD VALUE <replacea
     <listitem>
      <para>
       Automatically propagate the operation to typed tables of the
-      type being altered.
+      type being altered, and their descendants.
      </para>
     </listitem>
    </varlistentry>
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 26062f45602..bcf660b6de0 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -3876,7 +3876,8 @@ ATSimpleRecursion(List **wqueue, Relation rel,
  * ATTypedTableRecursion
  *
  * Propagate ALTER TYPE operations to the typed tables of that type.
- * Also check the RESTRICT/CASCADE behavior.
+ * Also check the RESTRICT/CASCADE behavior.  Given CASCADE, also permit
+ * recursion to inheritance children of the typed tables.
  */
 static void
 ATTypedTableRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd,
@@ -3898,7 +3899,7 @@ ATTypedTableRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd,
 
 		childrel = relation_open(childrelid, lockmode);
 		CheckTableNotInUse(childrel, "ALTER TABLE");
-		ATPrepCmd(wqueue, childrel, cmd, false, true, lockmode);
+		ATPrepCmd(wqueue, childrel, cmd, true, true, lockmode);
 		relation_close(childrel, NoLock);
 	}
 }
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index 8344d8542fa..a6fb36e2d97 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -1845,6 +1845,7 @@ ALTER TYPE test_type1 ALTER ATTRIBUTE b TYPE varchar; -- fails
 ERROR:  cannot alter type "test_type1" because column "test_tbl1"."y" uses it
 CREATE TYPE test_type2 AS (a int, b text);
 CREATE TABLE test_tbl2 OF test_type2;
+CREATE TABLE test_tbl2_subclass () INHERITS (test_tbl2);
 \d test_type2
 Composite type "public.test_type2"
  Column |  Type   | Modifiers 
@@ -1858,6 +1859,7 @@ Composite type "public.test_type2"
 --------+---------+-----------
  a      | integer | 
  b      | text    | 
+Number of child tables: 1 (Use \d+ to list them.)
 Typed table of type: test_type2
 
 ALTER TYPE test_type2 ADD ATTRIBUTE c text; -- fails
@@ -1879,6 +1881,7 @@ Composite type "public.test_type2"
  a      | integer | 
  b      | text    | 
  c      | text    | 
+Number of child tables: 1 (Use \d+ to list them.)
 Typed table of type: test_type2
 
 ALTER TYPE test_type2 ALTER ATTRIBUTE b TYPE varchar; -- fails
@@ -1900,6 +1903,7 @@ ALTER TYPE test_type2 ALTER ATTRIBUTE b TYPE varchar CASCADE;
  a      | integer           | 
  b      | character varying | 
  c      | text              | 
+Number of child tables: 1 (Use \d+ to list them.)
 Typed table of type: test_type2
 
 ALTER TYPE test_type2 DROP ATTRIBUTE b; -- fails
@@ -1919,6 +1923,7 @@ Composite type "public.test_type2"
 --------+---------+-----------
  a      | integer | 
  c      | text    | 
+Number of child tables: 1 (Use \d+ to list them.)
 Typed table of type: test_type2
 
 ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa; -- fails
@@ -1938,8 +1943,18 @@ Composite type "public.test_type2"
 --------+---------+-----------
  aa     | integer | 
  c      | text    | 
+Number of child tables: 1 (Use \d+ to list them.)
 Typed table of type: test_type2
 
+\d test_tbl2_subclass
+Table "public.test_tbl2_subclass"
+ Column |  Type   | Modifiers 
+--------+---------+-----------
+ aa     | integer | 
+ c      | text    | 
+Inherits: test_tbl2
+
+DROP TABLE test_tbl2_subclass;
 CREATE TYPE test_type_empty AS ();
 DROP TYPE test_type_empty;
 --
diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql
index 25fa7d562c5..4b2afe8bc93 100644
--- a/src/test/regress/sql/alter_table.sql
+++ b/src/test/regress/sql/alter_table.sql
@@ -1344,6 +1344,7 @@ ALTER TYPE test_type1 ALTER ATTRIBUTE b TYPE varchar; -- fails
 
 CREATE TYPE test_type2 AS (a int, b text);
 CREATE TABLE test_tbl2 OF test_type2;
+CREATE TABLE test_tbl2_subclass () INHERITS (test_tbl2);
 \d test_type2
 \d test_tbl2
 
@@ -1366,6 +1367,9 @@ ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa; -- fails
 ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa CASCADE;
 \d test_type2
 \d test_tbl2
+\d test_tbl2_subclass
+
+DROP TABLE test_tbl2_subclass;
 
 CREATE TYPE test_type_empty AS ();
 DROP TYPE test_type_empty;
-- 
GitLab