diff options
Diffstat (limited to 'src/backend/commands/trigger.c')
-rw-r--r-- | src/backend/commands/trigger.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 66401f28392..0f2de7e2e01 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -87,6 +87,7 @@ static bool GetTupleForTrigger(EState *estate, LockTupleMode lockmode, TupleTableSlot *oldslot, TupleTableSlot **epqslot, + TM_Result *tmresultp, TM_FailureData *tmfdp); static bool TriggerEnabled(EState *estate, ResultRelInfo *relinfo, Trigger *trigger, TriggerEvent event, @@ -2694,7 +2695,9 @@ ExecBRDeleteTriggers(EState *estate, EPQState *epqstate, ResultRelInfo *relinfo, ItemPointer tupleid, HeapTuple fdw_trigtuple, - TupleTableSlot **epqslot) + TupleTableSlot **epqslot, + TM_Result *tmresult, + TM_FailureData *tmfd) { TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo); TriggerDesc *trigdesc = relinfo->ri_TrigDesc; @@ -2711,7 +2714,7 @@ ExecBRDeleteTriggers(EState *estate, EPQState *epqstate, if (!GetTupleForTrigger(estate, epqstate, relinfo, tupleid, LockTupleExclusive, slot, &epqslot_candidate, - NULL)) + tmresult, tmfd)) return false; /* @@ -2802,6 +2805,7 @@ ExecARDeleteTriggers(EState *estate, LockTupleExclusive, slot, NULL, + NULL, NULL); else ExecForceStoreHeapTuple(fdw_trigtuple, slot, false); @@ -2943,6 +2947,7 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate, ItemPointer tupleid, HeapTuple fdw_trigtuple, TupleTableSlot *newslot, + TM_Result *tmresult, TM_FailureData *tmfd) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; @@ -2967,7 +2972,7 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate, /* get a copy of the on-disk tuple we are planning to update */ if (!GetTupleForTrigger(estate, epqstate, relinfo, tupleid, lockmode, oldslot, &epqslot_candidate, - tmfd)) + tmresult, tmfd)) return false; /* cancel the update action */ /* @@ -3122,6 +3127,7 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, LockTupleExclusive, oldslot, NULL, + NULL, NULL); else if (fdw_trigtuple != NULL) ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false); @@ -3277,6 +3283,7 @@ GetTupleForTrigger(EState *estate, LockTupleMode lockmode, TupleTableSlot *oldslot, TupleTableSlot **epqslot, + TM_Result *tmresultp, TM_FailureData *tmfdp) { Relation relation = relinfo->ri_RelationDesc; @@ -3304,6 +3311,8 @@ GetTupleForTrigger(EState *estate, &tmfd); /* Let the caller know about the status of this operation */ + if (tmresultp) + *tmresultp = test; if (tmfdp) *tmfdp = tmfd; @@ -3331,6 +3340,18 @@ GetTupleForTrigger(EState *estate, case TM_Ok: if (tmfd.traversed) { + /* + * Recheck the tuple using EPQ. For MERGE, we leave this + * to the caller (it must do additional rechecking, and + * might end up executing a different action entirely). + */ + if (estate->es_plannedstmt->commandType == CMD_MERGE) + { + if (tmresultp) + *tmresultp = TM_Updated; + return false; + } + *epqslot = EvalPlanQual(epqstate, relation, relinfo->ri_RangeTableIndex, |