1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-17 06:41:09 +03:00

Back-patch fix for TRUNCATE failure on relations with indexes.

This commit is contained in:
Tom Lane
2000-09-30 18:47:07 +00:00
parent 956ba755e7
commit 31ab0831a4

View 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,22 +1091,31 @@ 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,
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 heapId,
indexId,
Oid indexId,
procId,
accessMethodId;
Node *oldPred = NULL;
@ -1119,17 +1128,6 @@ RelationTruncateIndexes(Relation heapRelation)
numberOfAttributes;
char *predString;
heapId = RelationGetRelid(heapRelation);
/* Scan pg_index to find indexes on heapRelation */
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)))
{
/*
* For each index, fetch index attributes so we can apply
* index_build
@ -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);
}