diff options
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r-- | src/backend/executor/execMain.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 9d5d829406e..23a6a612565 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -162,7 +162,8 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags) case CMD_SELECT: /* - * SELECT FOR UPDATE/SHARE and modifying CTEs need to mark tuples + * SELECT FOR [KEY] UPDATE/SHARE and modifying CTEs need to mark + * tuples */ if (queryDesc->plannedstmt->rowMarks != NIL || queryDesc->plannedstmt->hasModifyingCTE) @@ -775,7 +776,7 @@ InitPlan(QueryDesc *queryDesc, int eflags) } /* - * Similarly, we have to lock relations selected FOR UPDATE/FOR SHARE + * Similarly, we have to lock relations selected FOR [KEY] UPDATE/SHARE * before we initialize the plan tree, else we'd be risking lock upgrades. * While we are at it, build the ExecRowMark list. */ @@ -794,7 +795,9 @@ InitPlan(QueryDesc *queryDesc, int eflags) switch (rc->markType) { case ROW_MARK_EXCLUSIVE: + case ROW_MARK_NOKEYEXCLUSIVE: case ROW_MARK_SHARE: + case ROW_MARK_KEYSHARE: relid = getrelid(rc->rti, rangeTable); relation = heap_open(relid, RowShareLock); break; @@ -1341,7 +1344,7 @@ ExecEndPlan(PlanState *planstate, EState *estate) } /* - * close any relations selected FOR UPDATE/FOR SHARE, again keeping locks + * close any relations selected FOR [KEY] UPDATE/SHARE, again keeping locks */ foreach(l, estate->es_rowMarks) { @@ -1694,6 +1697,7 @@ ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist) * epqstate - state for EvalPlanQual rechecking * relation - table containing tuple * rti - rangetable index of table containing tuple + * lockmode - requested tuple lock mode * *tid - t_ctid from the outdated tuple (ie, next updated version) * priorXmax - t_xmax from the outdated tuple * @@ -1702,10 +1706,13 @@ ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist) * * Returns a slot containing the new candidate update/delete tuple, or * NULL if we determine we shouldn't process the row. + * + * Note: properly, lockmode should be declared as enum LockTupleMode, + * but we use "int" to avoid having to include heapam.h in executor.h. */ TupleTableSlot * EvalPlanQual(EState *estate, EPQState *epqstate, - Relation relation, Index rti, + Relation relation, Index rti, int lockmode, ItemPointer tid, TransactionId priorXmax) { TupleTableSlot *slot; @@ -1716,7 +1723,7 @@ EvalPlanQual(EState *estate, EPQState *epqstate, /* * Get and lock the updated version of the row; if fail, return NULL. */ - copyTuple = EvalPlanQualFetch(estate, relation, LockTupleExclusive, + copyTuple = EvalPlanQualFetch(estate, relation, lockmode, tid, priorXmax); if (copyTuple == NULL) @@ -1864,7 +1871,7 @@ EvalPlanQualFetch(EState *estate, Relation relation, int lockmode, test = heap_lock_tuple(relation, &tuple, estate->es_output_cid, lockmode, false /* wait */, - &buffer, &hufd); + false, &buffer, &hufd); /* We now have two pins on the buffer, get rid of one */ ReleaseBuffer(buffer); @@ -1965,7 +1972,7 @@ EvalPlanQualFetch(EState *estate, Relation relation, int lockmode, /* updated, so look at the updated row */ tuple.t_self = tuple.t_data->t_ctid; /* updated row should have xmin matching this xmax */ - priorXmax = HeapTupleHeaderGetXmax(tuple.t_data); + priorXmax = HeapTupleHeaderGetUpdateXid(tuple.t_data); ReleaseBuffer(buffer); /* loop back to fetch next in chain */ } |