]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix ALTER COLUMN TYPE bug: it sometimes tried to drop UNIQUE or PRIMARY KEY
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 30 Jan 2006 16:19:04 +0000 (16:19 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 30 Jan 2006 16:19:04 +0000 (16:19 +0000)
constraints before FOREIGN KEY constraints that depended on them.  Originally
reported by Neil Conway on 29-Jun-2005.  Patch by Nakano Yoshihisa.

src/backend/commands/tablecmds.c

index 1f2e8b2367c4f51e91ee577b73ab37f847d96cb0..8190cbb408a43f46e3d354d4429d679988c7bde8 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.174.2.1 2005/11/22 18:23:07 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.174.2.2 2006/01/30 16:19:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -4968,12 +4968,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;
 
@@ -5141,9 +5167,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)
        {