From df9c8e1a39dc0502c62e164aa94e7e810bcd2009 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 22 May 2002 15:57:40 +0000 Subject: [PATCH] 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). --- src/backend/utils/cache/relcache.c | 54 ++++++++++++++++-------------- 1 file 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; + + foreach(curr, newlyCreatedRelns) { - List *curr; - List *prev = NIL; + 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); } /*