]> granicus.if.org Git - postgresql/commitdiff
Make RelationForgetRelation error out if the relcache entry has nonzero
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 22 May 2002 15:57:40 +0000 (15:57 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 22 May 2002 15:57:40 +0000 (15:57 +0000)
reference count.  This avoids leaving dangling pointers around, as in
recent bug report against sequences (bug# 671).

src/backend/utils/cache/relcache.c

index 66954ff8162638a47da99308f68e4403b96628b9..602af4d888103d6c3e7835a91f4e36467957348c 100644 (file)
@@ -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);
 }
 
 /*