diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-01-30 16:19:12 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-01-30 16:19:12 +0000 |
commit | 2426c62140545dc60d550a7e41356fa1d69775ca (patch) | |
tree | 87f3ce484792cf6f147117d7491098433c71c106 | |
parent | a021ea021c87dc0e29d9cbdfcf74e9ce5fd0bfe4 (diff) | |
download | postgresql-2426c62140545dc60d550a7e41356fa1d69775ca.tar.gz postgresql-2426c62140545dc60d550a7e41356fa1d69775ca.zip |
Fix ALTER COLUMN TYPE bug: it sometimes tried to drop UNIQUE or PRIMARY KEY
constraints before FOREIGN KEY constraints that depended on them. Originally
reported by Neil Conway on 29-Jun-2005. Patch by Nakano Yoshihisa.
-rw-r--r-- | src/backend/commands/tablecmds.c | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 20c6437897a..bc28c596831 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.142.4.4 2005/10/03 02:45:25 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.142.4.5 2006/01/30 16:19:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -4926,12 +4926,38 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, case OCLASS_CONSTRAINT: Assert(foundObject.objectSubId == 0); - if (!list_member_oid(tab->changedConstraintOids, foundObject.objectId)) + if (!list_member_oid(tab->changedConstraintOids, + foundObject.objectId)) { - tab->changedConstraintOids = lappend_oid(tab->changedConstraintOids, - foundObject.objectId); - tab->changedConstraintDefs = lappend(tab->changedConstraintDefs, - pg_get_constraintdef_string(foundObject.objectId)); + char *defstring = pg_get_constraintdef_string(foundObject.objectId); + + /* + * Put NORMAL dependencies at the front of the list and + * AUTO dependencies at the back. This makes sure that + * foreign-key constraints depending on this column will + * be dropped before unique or primary-key constraints of + * the column; which we must have because the FK + * constraints depend on the indexes belonging to the + * unique constraints. + */ + if (foundDep->deptype == DEPENDENCY_NORMAL) + { + tab->changedConstraintOids = + lcons_oid(foundObject.objectId, + tab->changedConstraintOids); + tab->changedConstraintDefs = + lcons(defstring, + tab->changedConstraintDefs); + } + else + { + tab->changedConstraintOids = + lappend_oid(tab->changedConstraintOids, + foundObject.objectId); + tab->changedConstraintDefs = + lappend(tab->changedConstraintDefs, + defstring); + } } break; @@ -5099,10 +5125,12 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab) ATPostAlterTypeParse((char *) lfirst(l), wqueue); /* - * Now we can drop the existing constraints and indexes --- - * constraints first, since some of them might depend on the indexes. - * It should be okay to use DROP_RESTRICT here, since nothing else - * should be depending on these objects. + * Now we can drop the existing constraints and indexes --- constraints + * first, since some of them might depend on the indexes. In fact, we + * have to delete FOREIGN KEY constraints before UNIQUE constraints, + * but we already ordered the constraint list to ensure that would happen. + * It should be okay to use DROP_RESTRICT here, since nothing else should + * be depending on these objects. */ if (tab->changedConstraintOids) obj.classId = get_system_catalog_relid(ConstraintRelationName); |