]> granicus.if.org Git - postgresql/commitdiff
Remove arbitrary ALTER TABLE .. ADD COLUMN restriction.
authorRobert Haas <rhaas@postgresql.org>
Wed, 26 Jan 2011 11:23:23 +0000 (06:23 -0500)
committerRobert Haas <rhaas@postgresql.org>
Wed, 26 Jan 2011 11:37:08 +0000 (06:37 -0500)
The previous coding prevented ALTER TABLE .. ADD COLUMN from being used
with a non-NULL default in situations where the table's rowtype was being
used elsewhere.  But this is a completely arbitrary restriction since
you could do the same operation in multiple steps (add the column, add
the default, update the table).

Inspired by a patch from Noah Misch, though I didn't use his code.

src/backend/commands/tablecmds.c
src/test/regress/expected/rowtypes.out
src/test/regress/sql/rowtypes.sql

index 6726ca9733110211d45e7866027e40b82229ba68..8a281968ad89aa6c4fe31e0aca1d6e9492bc20ab 100644 (file)
@@ -142,6 +142,7 @@ typedef struct AlteredTableInfo
        List       *newvals;            /* List of NewColumnValue */
        bool            new_notnull;    /* T if we added new NOT NULL constraints */
        bool            new_changeoids; /* T if we added/dropped the OID column */
+       bool            new_changetypes; /* T if we changed column types */
        Oid                     newTableSpace;  /* new tablespace; 0 means no change */
        /* Objects to rebuild after completing ALTER TYPE operations */
        List       *changedConstraintOids;      /* OIDs of constraints to rebuild */
@@ -3378,14 +3379,14 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
        }
 
        /*
-        * If we need to rewrite the table, the operation has to be propagated to
-        * tables that use this table's rowtype as a column type.
+        * If we change column data types or add/remove OIDs, the operation has to
+        * be propagated to tables that use this table's rowtype as a column type.
         *
         * (Eventually this will probably become true for scans as well, but at
         * the moment a composite type does not enforce any constraints, so it's
         * not necessary/appropriate to enforce them just during ALTER.)
         */
-       if (newrel)
+       if (tab->new_changetypes || tab->new_changeoids)
                find_composite_type_dependencies(oldrel->rd_rel->reltype,
                                                                                 RelationGetRelationName(oldrel),
                                                                                 NULL);
@@ -6429,6 +6430,7 @@ ATPrepAlterColumnType(List **wqueue,
                newval->expr = (Expr *) transform;
 
                tab->newvals = lappend(tab->newvals, newval);
+               tab->new_changetypes = true;
        }
        else if (tab->relkind == RELKIND_FOREIGN_TABLE)
        {
index e5cd71421c636ebd0ddc978e0493cacedf7b8600..3d5f4d6c95b396e407dc1853fea8672b3f81d8b4 100644 (file)
@@ -82,11 +82,14 @@ select * from people;
  (Joe,Blow) | 01-10-1984
 (1 row)
 
--- at the moment this will not work due to ALTER TABLE inadequacy:
+-- the default doesn't need to propagate through to the rowtypes, so this is OK
 alter table fullname add column suffix text default '';
-ERROR:  cannot alter table "fullname" because column "people"."fn" uses its rowtype
--- but this should work:
+alter table fullname drop column suffix;
+-- this one, without a default, is OK too
 alter table fullname add column suffix text default null;
+-- but this should fail, due to ALTER TABLE inadequacy
+alter table fullname alter column suffix set data type integer using null;
+ERROR:  cannot alter table "fullname" because column "people"."fn" uses its rowtype
 select * from people;
      fn      |     bd     
 -------------+------------
index 9041df147fe8999037ad05241344ae1d527704b6..257213d969e98598ee642d439a1e250cbb9401f4 100644 (file)
@@ -45,12 +45,16 @@ insert into people values ('(Joe,Blow)', '1984-01-10');
 
 select * from people;
 
--- at the moment this will not work due to ALTER TABLE inadequacy:
+-- the default doesn't need to propagate through to the rowtypes, so this is OK
 alter table fullname add column suffix text default '';
+alter table fullname drop column suffix;
 
--- but this should work:
+-- this one, without a default, is OK too
 alter table fullname add column suffix text default null;
 
+-- but this should fail, due to ALTER TABLE inadequacy
+alter table fullname alter column suffix set data type integer using null;
+
 select * from people;
 
 -- test insertion/updating of subfields