From: Tom Lane Date: Wed, 22 May 2002 17:29:45 +0000 (+0000) Subject: Make RelationForgetRelation error out if the relcache entry has nonzero X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=ae76304433b57a16324d03e61ff9045d8db9e861;p=users%2Fbernd%2Fpostgres.git 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). --- diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index fc6f18fc59..daa62c9f98 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -1755,35 +1755,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); } /*