mirror of
https://github.com/postgres/postgres.git
synced 2025-05-03 22:24:49 +03:00
Revise init_sequence so that it doesn't leak memory if the requested
sequence doesn't exist.
This commit is contained in:
parent
8a40400d40
commit
f35e1c8c1f
@ -388,57 +388,57 @@ static SeqTable
|
|||||||
init_sequence(char *caller, char *name)
|
init_sequence(char *caller, char *name)
|
||||||
{
|
{
|
||||||
SeqTable elm,
|
SeqTable elm,
|
||||||
priv = (SeqTable) NULL;
|
prev = (SeqTable) NULL;
|
||||||
SeqTable temp;
|
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)
|
if (strcmp(elm->name, name) == 0)
|
||||||
break;
|
break;
|
||||||
priv = elm;
|
prev = elm;
|
||||||
elm = elm->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elm == (SeqTable) NULL) /* not found */
|
/* If so, and if it's already been opened in this xact, just return it */
|
||||||
{
|
if (elm != (SeqTable) NULL && elm->rel != (Relation) NULL)
|
||||||
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;
|
return elm;
|
||||||
temp = elm;
|
|
||||||
}
|
|
||||||
|
|
||||||
temp->rel = heap_openr(name, AccessShareLock);
|
/* Else open and check it */
|
||||||
|
seqrel = heap_openr(name, AccessShareLock);
|
||||||
if (temp->rel->rd_rel->relkind != RELKIND_SEQUENCE)
|
if (seqrel->rd_rel->relkind != RELKIND_SEQUENCE)
|
||||||
elog(ERROR, "%s.%s: %s is not sequence !", name, caller, name);
|
elog(ERROR, "%s.%s: %s is not sequence !", name, caller, name);
|
||||||
|
|
||||||
if (elm != (SeqTable) NULL) /* we opened sequence from our */
|
if (elm != (SeqTable) NULL)
|
||||||
{ /* SeqTable - check relid ! */
|
{
|
||||||
if (RelationGetRelid(elm->rel) != elm->relid)
|
/* 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",
|
elog(NOTICE, "%s.%s: sequence was re-created",
|
||||||
name, caller, name);
|
name, caller, name);
|
||||||
|
elm->relid = RelationGetRelid(seqrel);
|
||||||
elm->cached = elm->last = elm->increment = 0;
|
elm->cached = elm->last = elm->increment = 0;
|
||||||
elm->relid = RelationGetRelid(elm->rel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
elm = temp;
|
/* Time to make a new seqtable entry. These entries live as long
|
||||||
elm->relid = RelationGetRelid(elm->rel);
|
* 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)
|
if (seqtab == (SeqTable) NULL)
|
||||||
seqtab = elm;
|
seqtab = elm;
|
||||||
else
|
else
|
||||||
priv->next = elm;
|
prev->next = elm;
|
||||||
}
|
}
|
||||||
|
|
||||||
return elm;
|
return elm;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user