From a06e41deebdf74b8b5109329dc75b2e9d9057962 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Wed, 26 Jan 2011 06:23:23 -0500 Subject: [PATCH] Remove arbitrary ALTER TABLE .. ADD COLUMN restriction. 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 | 8 +++++--- src/test/regress/expected/rowtypes.out | 9 ++++++--- src/test/regress/sql/rowtypes.sql | 8 ++++++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 6726ca9733..8a281968ad 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -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) { diff --git a/src/test/regress/expected/rowtypes.out b/src/test/regress/expected/rowtypes.out index e5cd71421c..3d5f4d6c95 100644 --- a/src/test/regress/expected/rowtypes.out +++ b/src/test/regress/expected/rowtypes.out @@ -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 -------------+------------ diff --git a/src/test/regress/sql/rowtypes.sql b/src/test/regress/sql/rowtypes.sql index 9041df147f..257213d969 100644 --- a/src/test/regress/sql/rowtypes.sql +++ b/src/test/regress/sql/rowtypes.sql @@ -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 -- GitLab