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.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 8facabbadad..3e2b986034c 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.246 2005/04/14 01:38:17 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.247 2005/04/28 21:47:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -560,9 +560,10 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
}
/*
- * Have to lock relations selected for update
+ * Have to lock relations selected FOR UPDATE/FOR SHARE
*/
estate->es_rowMark = NIL;
+ estate->es_forUpdate = parseTree->forUpdate;
if (parseTree->rowMarks != NIL)
{
ListCell *l;
@@ -986,7 +987,7 @@ ExecEndPlan(PlanState *planstate, EState *estate)
heap_close(estate->es_into_relation_descriptor, NoLock);
/*
- * close any relations selected FOR UPDATE, again keeping locks
+ * close any relations selected FOR UPDATE/FOR SHARE, again keeping locks
*/
foreach(l, estate->es_rowMark)
{
@@ -1126,6 +1127,9 @@ lnext: ;
* ctid!! */
tupleid = &tuple_ctid;
}
+ /*
+ * Process any FOR UPDATE or FOR SHARE locking requested.
+ */
else if (estate->es_rowMark != NIL)
{
ListCell *l;
@@ -1137,6 +1141,7 @@ lnext: ;
Buffer buffer;
HeapTupleData tuple;
TupleTableSlot *newSlot;
+ LockTupleMode lockmode;
HTSU_Result test;
if (!ExecGetJunkAttribute(junkfilter,
@@ -1151,9 +1156,15 @@ lnext: ;
if (isNull)
elog(ERROR, "\"%s\" is NULL", erm->resname);
+ if (estate->es_forUpdate)
+ lockmode = LockTupleExclusive;
+ else
+ lockmode = LockTupleShared;
+
tuple.t_self = *((ItemPointer) DatumGetPointer(datum));
- test = heap_mark4update(erm->relation, &tuple, &buffer,
- estate->es_snapshot->curcid);
+ test = heap_lock_tuple(erm->relation, &tuple, &buffer,
+ estate->es_snapshot->curcid,
+ lockmode);
ReleaseBuffer(buffer);
switch (test)
{
@@ -1189,7 +1200,7 @@ lnext: ;
goto lnext;
default:
- elog(ERROR, "unrecognized heap_mark4update status: %u",
+ elog(ERROR, "unrecognized heap_lock_tuple status: %u",
test);
return (NULL);
}
@@ -1574,8 +1585,8 @@ ExecUpdate(TupleTableSlot *slot,
* If we generate a new candidate tuple after EvalPlanQual testing, we
* must loop back here and recheck constraints. (We don't need to
* redo triggers, however. If there are any BEFORE triggers then
- * trigger.c will have done mark4update to lock the correct tuple, so
- * there's no need to do them again.)
+ * trigger.c will have done heap_lock_tuple to lock the correct tuple,
+ * so there's no need to do them again.)
*/
lreplace:;
if (resultRelationDesc->rd_att->constr)
@@ -2088,6 +2099,7 @@ EvalPlanQualStart(evalPlanQual *epq, EState *estate, evalPlanQual *priorepq)
epqstate->es_param_exec_vals = (ParamExecData *)
palloc0(estate->es_topPlan->nParamExec * sizeof(ParamExecData));
epqstate->es_rowMark = estate->es_rowMark;
+ epqstate->es_forUpdate = estate->es_forUpdate;
epqstate->es_instrument = estate->es_instrument;
epqstate->es_select_into = estate->es_select_into;
epqstate->es_into_oids = estate->es_into_oids;