aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-01-30 16:18:58 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-01-30 16:18:58 +0000
commit0dd0e289c70783a98eda97bdbda01ae2e90d149c (patch)
tree7efc7b066406df4e8a50f44423822079f84dd364 /src/backend/commands/tablecmds.c
parent3276e911d154acd83c7ad5abeda11a4ab90866d3 (diff)
downloadpostgresql-0dd0e289c70783a98eda97bdbda01ae2e90d149c.tar.gz
postgresql-0dd0e289c70783a98eda97bdbda01ae2e90d149c.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.
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 43a56f50308..48ebd597c99 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.176 2005/11/22 18:17:09 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.177 2006/01/30 16:18:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -4967,12 +4967,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;
@@ -5140,9 +5166,11 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab)
/*
* 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.
+ * 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.
*/
foreach(l, tab->changedConstraintOids)
{