]> granicus.if.org Git - postgresql/commitdiff
Repair 'expected both swapped tables to have TOAST tables' bug in 7.4
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 31 Aug 2004 23:16:36 +0000 (23:16 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 31 Aug 2004 23:16:36 +0000 (23:16 +0000)
branch.  I wasn't excited about doing this when the first report came in,
but now that we have two of 'em, I suppose it had better get fixed.

src/backend/commands/cluster.c

index a3f9ae8aac7129cdea41fb69fc1ddd704b33a82a..dfe67617c5289f4cac80425e8772a896d21ef403 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.116 2003/09/25 06:57:58 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.116.2.1 2004/08/31 23:16:36 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -787,9 +787,8 @@ swap_relfilenodes(Oid r1, Oid r2)
         * their new owning relations.  Otherwise the wrong one will get
         * dropped ...
         *
-        * NOTE: for now, we can assume the new table will have a TOAST table if
-        * and only if the old one does.  This logic might need work if we get
-        * smarter about dropped columns.
+        * NOTE: it is possible that only one table has a toast table; this can
+        * happen in CLUSTER if there were dropped columns in the old table.
         *
         * NOTE: at present, a TOAST table's only dependency is the one on its
         * owning table.  If more are ever created, we'd need to use something
@@ -802,35 +801,43 @@ swap_relfilenodes(Oid r1, Oid r2)
                                        toastobject;
                long            count;
 
-               if (!(relform1->reltoastrelid && relform2->reltoastrelid))
-                       elog(ERROR, "expected both swapped tables to have TOAST tables");
-
                /* Delete old dependencies */
-               count = deleteDependencyRecordsFor(RelOid_pg_class,
-                                                                                  relform1->reltoastrelid);
-               if (count != 1)
-                       elog(ERROR, "expected one dependency record for TOAST table, found %ld",
-                                count);
-               count = deleteDependencyRecordsFor(RelOid_pg_class,
-                                                                                  relform2->reltoastrelid);
-               if (count != 1)
-                       elog(ERROR, "expected one dependency record for TOAST table, found %ld",
-                                count);
+               if (relform1->reltoastrelid)
+               {
+                       count = deleteDependencyRecordsFor(RelOid_pg_class,
+                                                                                          relform1->reltoastrelid);
+                       if (count != 1)
+                               elog(ERROR, "expected one dependency record for TOAST table, found %ld",
+                                        count);
+               }
+               if (relform2->reltoastrelid)
+               {
+                       count = deleteDependencyRecordsFor(RelOid_pg_class,
+                                                                                          relform2->reltoastrelid);
+                       if (count != 1)
+                               elog(ERROR, "expected one dependency record for TOAST table, found %ld",
+                                        count);
+               }
 
                /* Register new dependencies */
                baseobject.classId = RelOid_pg_class;
-               baseobject.objectId = r1;
                baseobject.objectSubId = 0;
                toastobject.classId = RelOid_pg_class;
-               toastobject.objectId = relform1->reltoastrelid;
                toastobject.objectSubId = 0;
 
-               recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL);
-
-               baseobject.objectId = r2;
-               toastobject.objectId = relform2->reltoastrelid;
+               if (relform1->reltoastrelid)
+               {
+                       baseobject.objectId = r1;
+                       toastobject.objectId = relform1->reltoastrelid;
+                       recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL);
+               }
 
-               recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL);
+               if (relform2->reltoastrelid)
+               {
+                       baseobject.objectId = r2;
+                       toastobject.objectId = relform2->reltoastrelid;
+                       recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL);
+               }
        }
 
        /*