diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/trigger.c | 5 | ||||
-rw-r--r-- | src/backend/executor/execMain.c | 32 | ||||
-rw-r--r-- | src/include/executor/executor.h | 4 |
3 files changed, 32 insertions, 9 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 2bcbd89fddf..86af435116b 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.195.2.1 2005/11/22 18:23:07 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.195.2.2 2006/01/12 21:49:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1736,7 +1736,8 @@ ltrmark:; epqslot = EvalPlanQual(estate, relinfo->ri_RangeTableIndex, &update_ctid, - update_xmax); + update_xmax, + cid); if (!TupIsNull(epqslot)) { *tid = update_ctid; diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 04e36b87b08..36d031b10ab 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -26,7 +26,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.256.2.4 2005/11/22 18:23:08 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.256.2.5 2006/01/12 21:49:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1219,7 +1219,8 @@ lnext: ; newSlot = EvalPlanQual(estate, erm->rti, &update_ctid, - update_xmax); + update_xmax, + estate->es_snapshot->curcid); if (!TupIsNull(newSlot)) { slot = newSlot; @@ -1527,7 +1528,8 @@ ldelete:; epqslot = EvalPlanQual(estate, resultRelInfo->ri_RangeTableIndex, &update_ctid, - update_xmax); + update_xmax, + estate->es_snapshot->curcid); if (!TupIsNull(epqslot)) { *tupleid = update_ctid; @@ -1679,7 +1681,8 @@ lreplace:; epqslot = EvalPlanQual(estate, resultRelInfo->ri_RangeTableIndex, &update_ctid, - update_xmax); + update_xmax, + estate->es_snapshot->curcid); if (!TupIsNull(epqslot)) { *tupleid = update_ctid; @@ -1826,6 +1829,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo, * rti - rangetable index of table containing tuple * *tid - t_ctid from the outdated tuple (ie, next updated version) * priorXmax - t_xmax from the outdated tuple + * curCid - command ID of current command of my transaction * * *tid is also an output parameter: it's modified to hold the TID of the * latest version of the tuple (note this may be changed even on failure) @@ -1835,7 +1839,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo, */ TupleTableSlot * EvalPlanQual(EState *estate, Index rti, - ItemPointer tid, TransactionId priorXmax) + ItemPointer tid, TransactionId priorXmax, CommandId curCid) { evalPlanQual *epq; EState *epqstate; @@ -1912,6 +1916,24 @@ EvalPlanQual(EState *estate, Index rti, } /* + * If tuple was inserted by our own transaction, we have to check + * cmin against curCid: cmin >= curCid means our command cannot + * see the tuple, so we should ignore it. Without this we are + * open to the "Halloween problem" of indefinitely re-updating + * the same tuple. (We need not check cmax because + * HeapTupleSatisfiesDirty will consider a tuple deleted by + * our transaction dead, regardless of cmax.) We just checked + * that priorXmax == xmin, so we can test that variable instead + * of doing HeapTupleHeaderGetXmin again. + */ + if (TransactionIdIsCurrentTransactionId(priorXmax) && + HeapTupleHeaderGetCmin(tuple.t_data) >= curCid) + { + ReleaseBuffer(buffer); + return NULL; + } + + /* * We got tuple - now copy it for use by recheck query. */ copyTuple = heap_copytuple(&tuple); diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index a2c12d3202c..7e14801184d 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.120.2.1 2005/11/23 20:28:05 tgl Exp $ + * $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.120.2.2 2006/01/12 21:49:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -98,7 +98,7 @@ extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids); extern void ExecConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate); extern TupleTableSlot *EvalPlanQual(EState *estate, Index rti, - ItemPointer tid, TransactionId priorXmax); + ItemPointer tid, TransactionId priorXmax, CommandId curCid); /* * prototypes from functions in execProcnode.c |