Repair relation refcount leakage caused by SELECT FOR UPDATE.

This commit is contained in:
Tom Lane 2000-02-03 00:02:58 +00:00
parent 31a8996ba4
commit 40055db1eb
1 changed files with 26 additions and 15 deletions

View File

@ -27,7 +27,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.107 2000/01/26 05:56:21 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.108 2000/02/03 00:02:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -596,19 +596,19 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
estate->es_rowMark = NULL; estate->es_rowMark = NULL;
if (parseTree->rowMark != NULL) if (parseTree->rowMark != NULL)
{ {
Relation relation;
Oid relid;
RowMark *rm;
List *l; List *l;
execRowMark *erm;
foreach(l, parseTree->rowMark) foreach(l, parseTree->rowMark)
{ {
rm = lfirst(l); RowMark *rm = lfirst(l);
relid = rt_fetch(rm->rti, rangeTable)->relid; Oid relid;
relation = heap_open(relid, RowShareLock); Relation relation;
execRowMark *erm;
if (!(rm->info & ROW_MARK_FOR_UPDATE)) if (!(rm->info & ROW_MARK_FOR_UPDATE))
continue; continue;
relid = rt_fetch(rm->rti, rangeTable)->relid;
relation = heap_open(relid, RowShareLock);
erm = (execRowMark *) palloc(sizeof(execRowMark)); erm = (execRowMark *) palloc(sizeof(execRowMark));
erm->relation = relation; erm->relation = relation;
erm->rti = rm->rti; erm->rti = rm->rti;
@ -756,6 +756,7 @@ EndPlan(Plan *plan, EState *estate)
{ {
RelationInfo *resultRelationInfo; RelationInfo *resultRelationInfo;
Relation intoRelationDesc; Relation intoRelationDesc;
List *l;
/* /*
* get information from state * get information from state
@ -796,10 +797,20 @@ EndPlan(Plan *plan, EState *estate)
} }
/* /*
* close the "into" relation if necessary * close the "into" relation if necessary, again keeping lock
*/ */
if (intoRelationDesc != NULL) if (intoRelationDesc != NULL)
heap_close(intoRelationDesc, NoLock); heap_close(intoRelationDesc, NoLock);
/*
* close any relations selected FOR UPDATE, again keeping locks
*/
foreach(l, estate->es_rowMark)
{
execRowMark *erm = lfirst(l);
heap_close(erm->relation, NoLock);
}
} }
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
@ -926,16 +937,16 @@ lnext: ;
else if (estate->es_rowMark != NULL) else if (estate->es_rowMark != NULL)
{ {
List *l; List *l;
execRowMark *erm;
Buffer buffer;
HeapTupleData tuple;
TupleTableSlot *newSlot;
int test;
lmark: ; lmark: ;
foreach(l, estate->es_rowMark) foreach(l, estate->es_rowMark)
{ {
erm = lfirst(l); execRowMark *erm = lfirst(l);
Buffer buffer;
HeapTupleData tuple;
TupleTableSlot *newSlot;
int test;
if (!ExecGetJunkAttribute(junkfilter, if (!ExecGetJunkAttribute(junkfilter,
slot, slot,
erm->resname, erm->resname,