aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execMain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r--src/backend/executor/execMain.c65
1 files changed, 42 insertions, 23 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 4b6ad47adb0..5886234a1e8 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.300 2007/11/15 22:25:15 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.301 2007/11/30 21:22:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -161,6 +161,30 @@ ExecutorStart(QueryDesc *queryDesc, int eflags)
palloc0(queryDesc->plannedstmt->nParamExec * sizeof(ParamExecData));
/*
+ * If non-read-only query, set the command ID to mark output tuples with
+ */
+ switch (queryDesc->operation)
+ {
+ case CMD_SELECT:
+ /* SELECT INTO and SELECT FOR UPDATE/SHARE need to mark tuples */
+ if (queryDesc->plannedstmt->intoClause != NULL ||
+ queryDesc->plannedstmt->rowMarks != NIL)
+ estate->es_output_cid = GetCurrentCommandId(true);
+ break;
+
+ case CMD_INSERT:
+ case CMD_DELETE:
+ case CMD_UPDATE:
+ estate->es_output_cid = GetCurrentCommandId(true);
+ break;
+
+ default:
+ elog(ERROR, "unrecognized operation code: %d",
+ (int) queryDesc->operation);
+ break;
+ }
+
+ /*
* Copy other important information into the EState
*/
estate->es_snapshot = queryDesc->snapshot;
@@ -1285,7 +1309,7 @@ lnext: ;
test = heap_lock_tuple(erm->relation, &tuple, &buffer,
&update_ctid, &update_xmax,
- estate->es_snapshot->curcid,
+ estate->es_output_cid,
lockmode, erm->noWait);
ReleaseBuffer(buffer);
switch (test)
@@ -1309,8 +1333,7 @@ lnext: ;
newSlot = EvalPlanQual(estate,
erm->rti,
&update_ctid,
- update_xmax,
- estate->es_snapshot->curcid);
+ update_xmax);
if (!TupIsNull(newSlot))
{
slot = planSlot = newSlot;
@@ -1503,7 +1526,7 @@ ExecInsert(TupleTableSlot *slot,
* t_self field.
*/
newId = heap_insert(resultRelationDesc, tuple,
- estate->es_snapshot->curcid,
+ estate->es_output_cid,
true, true);
IncrAppended();
@@ -1557,8 +1580,7 @@ ExecDelete(ItemPointer tupleid,
{
bool dodelete;
- dodelete = ExecBRDeleteTriggers(estate, resultRelInfo, tupleid,
- estate->es_snapshot->curcid);
+ dodelete = ExecBRDeleteTriggers(estate, resultRelInfo, tupleid);
if (!dodelete) /* "do nothing" */
return;
@@ -1575,7 +1597,7 @@ ExecDelete(ItemPointer tupleid,
ldelete:;
result = heap_delete(resultRelationDesc, tupleid,
&update_ctid, &update_xmax,
- estate->es_snapshot->curcid,
+ estate->es_output_cid,
estate->es_crosscheck_snapshot,
true /* wait for commit */ );
switch (result)
@@ -1599,8 +1621,7 @@ ldelete:;
epqslot = EvalPlanQual(estate,
resultRelInfo->ri_RangeTableIndex,
&update_ctid,
- update_xmax,
- estate->es_snapshot->curcid);
+ update_xmax);
if (!TupIsNull(epqslot))
{
*tupleid = update_ctid;
@@ -1708,8 +1729,7 @@ ExecUpdate(TupleTableSlot *slot,
HeapTuple newtuple;
newtuple = ExecBRUpdateTriggers(estate, resultRelInfo,
- tupleid, tuple,
- estate->es_snapshot->curcid);
+ tupleid, tuple);
if (newtuple == NULL) /* "do nothing" */
return;
@@ -1755,7 +1775,7 @@ lreplace:;
*/
result = heap_update(resultRelationDesc, tupleid, tuple,
&update_ctid, &update_xmax,
- estate->es_snapshot->curcid,
+ estate->es_output_cid,
estate->es_crosscheck_snapshot,
true /* wait for commit */ );
switch (result)
@@ -1779,8 +1799,7 @@ lreplace:;
epqslot = EvalPlanQual(estate,
resultRelInfo->ri_RangeTableIndex,
&update_ctid,
- update_xmax,
- estate->es_snapshot->curcid);
+ update_xmax);
if (!TupIsNull(epqslot))
{
*tupleid = update_ctid;
@@ -1973,7 +1992,6 @@ ExecProcessReturning(ProjectionInfo *projectReturning,
* 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)
@@ -1983,7 +2001,7 @@ ExecProcessReturning(ProjectionInfo *projectReturning,
*/
TupleTableSlot *
EvalPlanQual(EState *estate, Index rti,
- ItemPointer tid, TransactionId priorXmax, CommandId curCid)
+ ItemPointer tid, TransactionId priorXmax)
{
evalPlanQual *epq;
EState *epqstate;
@@ -2063,17 +2081,17 @@ 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
+ * cmin against es_output_cid: cmin >= current CID 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)
+ HeapTupleHeaderGetCmin(tuple.t_data) >= estate->es_output_cid)
{
ReleaseBuffer(buffer);
return NULL;
@@ -2360,6 +2378,7 @@ EvalPlanQualStart(evalPlanQual *epq, EState *estate, evalPlanQual *priorepq)
epqstate->es_snapshot = estate->es_snapshot;
epqstate->es_crosscheck_snapshot = estate->es_crosscheck_snapshot;
epqstate->es_range_table = estate->es_range_table;
+ epqstate->es_output_cid = estate->es_output_cid;
epqstate->es_result_relations = estate->es_result_relations;
epqstate->es_num_result_relations = estate->es_num_result_relations;
epqstate->es_result_relation_info = estate->es_result_relation_info;
@@ -2718,7 +2737,7 @@ intorel_receive(TupleTableSlot *slot, DestReceiver *self)
heap_insert(estate->es_into_relation_descriptor,
tuple,
- estate->es_snapshot->curcid,
+ estate->es_output_cid,
estate->es_into_relation_use_wal,
false); /* never any point in using FSM */