]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Revise init_sequence so that it doesn't leak memory if the requested
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 31 Dec 1999 00:54:27 +0000 (00:54 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 31 Dec 1999 00:54:27 +0000 (00:54 +0000)
sequence doesn't exist.

src/backend/commands/sequence.c

index 228aaba7990b3e81d82ef616991013621d29a618..ad81df2316766962128255a0451e1cb12941473f 100644 (file)
@@ -388,57 +388,57 @@ static SeqTable
 init_sequence(char *caller, char *name)
 {
        SeqTable        elm,
-                               priv = (SeqTable) NULL;
-       SeqTable        temp;
+                               prev = (SeqTable) NULL;
+       Relation        seqrel;
 
-       for (elm = seqtab; elm != (SeqTable) NULL;)
+       /* Look to see if we already have a seqtable entry for name */
+       for (elm = seqtab; elm != (SeqTable) NULL; elm = elm->next)
        {
                if (strcmp(elm->name, name) == 0)
                        break;
-               priv = elm;
-               elm = elm->next;
+               prev = elm;
        }
 
-       if (elm == (SeqTable) NULL) /* not found */
-       {
-               temp = (SeqTable) malloc(sizeof(SeqTableData));
-               temp->name = malloc(strlen(name) + 1);
-               strcpy(temp->name, name);
-               temp->rel = (Relation) NULL;
-               temp->cached = temp->last = temp->increment = 0;
-               temp->next = (SeqTable) NULL;
-       }
-       else
-/* found */
-       {
-               if (elm->rel != (Relation) NULL)                /* already opened */
-                       return elm;
-               temp = elm;
-       }
+       /* If so, and if it's already been opened in this xact, just return it */
+       if (elm != (SeqTable) NULL && elm->rel != (Relation) NULL)
+               return elm;
 
-       temp->rel = heap_openr(name, AccessShareLock);
-
-       if (temp->rel->rd_rel->relkind != RELKIND_SEQUENCE)
+       /* Else open and check it */
+       seqrel = heap_openr(name, AccessShareLock);
+       if (seqrel->rd_rel->relkind != RELKIND_SEQUENCE)
                elog(ERROR, "%s.%s: %s is not sequence !", name, caller, name);
 
-       if (elm != (SeqTable) NULL) /* we opened sequence from our */
-       {                                                       /* SeqTable - check relid ! */
-               if (RelationGetRelid(elm->rel) != elm->relid)
+       if (elm != (SeqTable) NULL)
+       {
+               /* We are using a seqtable entry left over from a previous xact;
+                * must check for relid change.
+                */
+               elm->rel = seqrel;
+               if (RelationGetRelid(seqrel) != elm->relid)
                {
                        elog(NOTICE, "%s.%s: sequence was re-created",
                                 name, caller, name);
+                       elm->relid = RelationGetRelid(seqrel);
                        elm->cached = elm->last = elm->increment = 0;
-                       elm->relid = RelationGetRelid(elm->rel);
                }
        }
        else
        {
-               elm = temp;
-               elm->relid = RelationGetRelid(elm->rel);
+               /* Time to make a new seqtable entry.  These entries live as long
+                * as the backend does, so we use plain malloc for them.
+                */
+               elm = (SeqTable) malloc(sizeof(SeqTableData));
+               elm->name = malloc(strlen(name) + 1);
+               strcpy(elm->name, name);
+               elm->rel = seqrel;
+               elm->relid = RelationGetRelid(seqrel);
+               elm->cached = elm->last = elm->increment = 0;
+               elm->next = (SeqTable) NULL;
+
                if (seqtab == (SeqTable) NULL)
                        seqtab = elm;
                else
-                       priv->next = elm;
+                       prev->next = elm;
        }
 
        return elm;