aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/commands/trigger.c5
-rw-r--r--src/backend/executor/execMain.c32
-rw-r--r--src/include/executor/executor.h4
3 files changed, 32 insertions, 9 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index ec998aa7b9f..a6b75f06d58 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.177.4.2 2005/08/25 19:44:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.177.4.3 2006/01/12 21:49:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1603,7 +1603,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 a825c281618..3a86d311629 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.241.4.1 2005/08/25 19:45:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.241.4.2 2006/01/12 21:49:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1159,7 +1159,8 @@ lnext: ;
newSlot = EvalPlanQual(estate,
erm->rti,
&update_ctid,
- update_xmax);
+ update_xmax,
+ estate->es_snapshot->curcid);
if (!TupIsNull(newSlot))
{
slot = newSlot;
@@ -1470,7 +1471,8 @@ ldelete:;
epqslot = EvalPlanQual(estate,
resultRelInfo->ri_RangeTableIndex,
&update_ctid,
- update_xmax);
+ update_xmax,
+ estate->es_snapshot->curcid);
if (!TupIsNull(epqslot))
{
*tupleid = update_ctid;
@@ -1615,7 +1617,8 @@ lreplace:;
epqslot = EvalPlanQual(estate,
resultRelInfo->ri_RangeTableIndex,
&update_ctid,
- update_xmax);
+ update_xmax,
+ estate->es_snapshot->curcid);
if (!TupIsNull(epqslot))
{
*tupleid = update_ctid;
@@ -1770,6 +1773,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)
@@ -1779,7 +1783,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
*/
TupleTableSlot *
EvalPlanQual(EState *estate, Index rti,
- ItemPointer tid, TransactionId priorXmax)
+ ItemPointer tid, TransactionId priorXmax, CommandId curCid)
{
evalPlanQual *epq;
EState *epqstate;
@@ -1856,6 +1860,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 6c7eff0d46d..77f7310d5ea 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.115.4.1 2005/08/25 19:45:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.115.4.2 2006/01/12 21:49:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -109,7 +109,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