Commit df9c8e1a authored by Tom Lane's avatar Tom Lane

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).
parent 0352e3a7
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -1841,35 +1841,39 @@ RelationForgetRelation(Oid rid)
RelationIdCacheLookup(rid, relation); 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) foreach(curr, newlyCreatedRelns)
{ {
Relation reln = lfirst(curr); Relation reln = lfirst(curr);
Assert(reln != NULL && reln->rd_myxactonly); Assert(reln != NULL && reln->rd_myxactonly);
if (RelationGetRelid(reln) == rid) if (RelationGetRelid(reln) == rid)
break; break;
prev = curr; 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);
} }
if (curr == NIL)
/* Unconditionally destroy the relcache entry */ elog(ERROR, "Local relation %s not found in list",
RelationClearRelation(relation, false); RelationGetRelationName(relation));
if (prev == NIL)
newlyCreatedRelns = lnext(newlyCreatedRelns);
else
lnext(prev) = lnext(curr);
pfree(curr);
} }
/* Unconditionally destroy the relcache entry */
RelationClearRelation(relation, false);
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment