Back-patch fix for TRUNCATE failure on relations with indexes.
authorTom Lane <[email protected]>
Sat, 30 Sep 2000 18:47:07 +0000 (18:47 +0000)
committerTom Lane <[email protected]>
Sat, 30 Sep 2000 18:47:07 +0000 (18:47 +0000)
src/backend/catalog/heap.c

index 762bff810d0b25f46538ad6dc57cdd1abfaadf4c..91530e15154510ef2d2d552712776449549f670d 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.128 2000/05/25 21:25:32 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.128.2.1 2000/09/30 18:47:07 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1091,44 +1091,42 @@ DeleteRelationTuple(Relation rel)
  * RelationTruncateIndexes - This routine is used to truncate all
  * indices associated with the heap relation to zero tuples.
  * The routine will truncate and then reconstruct the indices on
- * the relation specified by the heapRelation parameter.
+ * the relation specified by the heapId parameter.
  * --------------------------------
  */
 static void
-RelationTruncateIndexes(Relation heapRelation)
+RelationTruncateIndexes(Oid heapId)
 {
-   Relation    indexRelation,
-               currentIndex;
+   Relation    indexRelation;
    ScanKeyData entry;
    HeapScanDesc scan;
-   HeapTuple   indexTuple,
-               procTuple,
-               classTuple;
-   Form_pg_index index;
-   Oid         heapId,
-               indexId,
-               procId,
-               accessMethodId;
-   Node       *oldPred = NULL;
-   PredInfo   *predInfo;
-   List       *cnfPred = NULL;
-   AttrNumber *attributeNumberA;
-   FuncIndexInfo fInfo,
-              *funcInfo = NULL;
-   int         i,
-               numberOfAttributes;
-   char       *predString;
-
-   heapId = RelationGetRelid(heapRelation);
-
-   /* Scan pg_index to find indexes on heapRelation */
+   HeapTuple   indexTuple;
 
+   /* Scan pg_index to find indexes on specified heap */
    indexRelation = heap_openr(IndexRelationName, AccessShareLock);
    ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid, F_OIDEQ,
                           ObjectIdGetDatum(heapId));
    scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry);
+
    while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
    {
+       Relation    heapRelation,
+                   currentIndex;
+       HeapTuple   procTuple,
+                   classTuple;
+       Form_pg_index index;
+       Oid         indexId,
+                   procId,
+                   accessMethodId;
+       Node       *oldPred = NULL;
+       PredInfo   *predInfo;
+       List       *cnfPred = NULL;
+       AttrNumber *attributeNumberA;
+       FuncIndexInfo fInfo,
+                  *funcInfo = NULL;
+       int         i,
+                   numberOfAttributes;
+       char       *predString;
 
        /*
         * For each index, fetch index attributes so we can apply
@@ -1183,10 +1181,17 @@ RelationTruncateIndexes(Relation heapRelation)
            elog(ERROR, "RelationTruncateIndexes: index access method not found");
        accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
 
+       /*
+        * We have to re-open the heap rel each time through this loop
+        * because index_build will close it again.  We need grab no lock,
+        * however, because we assume heap_truncate is holding an exclusive
+        * lock on the heap rel.
+        */
+       heapRelation = heap_open(heapId, NoLock);
+       Assert(heapRelation != NULL);
+
        /* Open our index relation */
        currentIndex = index_open(indexId);
-       if (currentIndex == NULL)
-           elog(ERROR, "RelationTruncateIndexes: can't open index relation");
 
        /* Obtain exclusive lock on it, just to be sure */
        LockRelation(currentIndex, AccessExclusiveLock);
@@ -1205,16 +1210,10 @@ RelationTruncateIndexes(Relation heapRelation)
        InitIndexStrategy(numberOfAttributes, currentIndex, accessMethodId);
        index_build(heapRelation, currentIndex, numberOfAttributes,
                    attributeNumberA, 0, NULL, funcInfo, predInfo);
-
        /*
         * index_build will close both the heap and index relations (but
-        * not give up the locks we hold on them).  That's fine for the
-        * index, but we need to open the heap again.  We need no new
-        * lock, since this backend still has the exclusive lock grabbed
-        * by heap_truncate.
+        * not give up the locks we hold on them).
         */
-       heapRelation = heap_open(heapId, NoLock);
-       Assert(heapRelation != NULL);
    }
 
    /* Complete the scan and close pg_index */
@@ -1270,17 +1269,12 @@ heap_truncate(char *relname)
    rel->rd_nblocks = 0;
 
    /* If this relation has indexes, truncate the indexes too */
-   RelationTruncateIndexes(rel);
+   RelationTruncateIndexes(rid);
 
    /*
     * Close the relation, but keep exclusive lock on it until commit.
     */
    heap_close(rel, NoLock);
-
-   /*
-    * Is this really necessary?
-    */
-   RelationForgetRelation(rid);
 }