summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2002-05-22 15:57:40 +0000
committerTom Lane2002-05-22 15:57:40 +0000
commitdf9c8e1a39dc0502c62e164aa94e7e810bcd2009 (patch)
tree372a82c1962559c284750d5b411fee6e9bce1fd8
parent0352e3a7836ab92be4d64f89f7d91b29e29bfd71 (diff)
Make RelationForgetRelation error out if the relcache entry has nonzero
reference count. This avoids leaving dangling pointers around, as in recent bug report against sequences (bug# 671).
-rw-r--r--src/backend/utils/cache/relcache.c54
1 files changed, 29 insertions, 25 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 66954ff816..602af4d888 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.163 2002/04/27 21:24:34 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.164 2002/05/22 15:57:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1841,35 +1841,39 @@ RelationForgetRelation(Oid rid)
RelationIdCacheLookup(rid, relation);
- if (PointerIsValid(relation))
+ if (!PointerIsValid(relation))
+ return; /* not in cache, nothing to do */
+
+ if (!RelationHasReferenceCountZero(relation))
+ elog(ERROR, "RelationForgetRelation: relation %u is still open", rid);
+
+ /* If local, remove from list */
+ if (relation->rd_myxactonly)
{
- if (relation->rd_myxactonly)
- {
- List *curr;
- List *prev = NIL;
+ List *curr;
+ List *prev = NIL;
- foreach(curr, newlyCreatedRelns)
- {
- Relation reln = lfirst(curr);
+ foreach(curr, newlyCreatedRelns)
+ {
+ Relation reln = lfirst(curr);
- Assert(reln != NULL && reln->rd_myxactonly);
- if (RelationGetRelid(reln) == rid)
- break;
- prev = curr;
- }
- if (curr == NIL)
- elog(FATAL, "Local relation %s not found in list",
- RelationGetRelationName(relation));
- if (prev == NIL)
- newlyCreatedRelns = lnext(newlyCreatedRelns);
- else
- lnext(prev) = lnext(curr);
- pfree(curr);
+ Assert(reln != NULL && reln->rd_myxactonly);
+ if (RelationGetRelid(reln) == rid)
+ break;
+ prev = curr;
}
-
- /* Unconditionally destroy the relcache entry */
- RelationClearRelation(relation, false);
+ if (curr == NIL)
+ elog(ERROR, "Local relation %s not found in list",
+ RelationGetRelationName(relation));
+ if (prev == NIL)
+ newlyCreatedRelns = lnext(newlyCreatedRelns);
+ else
+ lnext(prev) = lnext(curr);
+ pfree(curr);
}
+
+ /* Unconditionally destroy the relcache entry */
+ RelationClearRelation(relation, false);
}
/*