aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/trigger.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/trigger.c')
-rw-r--r--src/backend/commands/trigger.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 84494c4b81f..35eb7180f7e 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -2773,8 +2773,8 @@ ExecBRDeleteTriggers(EState *estate, EPQState *epqstate,
void
ExecARDeleteTriggers(EState *estate,
ResultRelInfo *relinfo,
+ ItemPointer tupleid,
HeapTuple fdw_trigtuple,
- TupleTableSlot *slot,
TransitionCaptureState *transition_capture,
bool is_crosspart_update)
{
@@ -2783,11 +2783,20 @@ ExecARDeleteTriggers(EState *estate,
if ((trigdesc && trigdesc->trig_delete_after_row) ||
(transition_capture && transition_capture->tcs_delete_old_table))
{
- /*
- * Put the FDW old tuple to the slot. Otherwise, the caller is
- * expected to have an old tuple already fetched to the slot.
- */
- if (fdw_trigtuple != NULL)
+ TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo);
+
+ Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid));
+ if (fdw_trigtuple == NULL)
+ GetTupleForTrigger(estate,
+ NULL,
+ relinfo,
+ tupleid,
+ LockTupleExclusive,
+ slot,
+ NULL,
+ NULL,
+ NULL);
+ else
ExecForceStoreHeapTuple(fdw_trigtuple, slot, false);
AfterTriggerSaveEvent(estate, relinfo, NULL, NULL,
@@ -3078,17 +3087,18 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
* Note: 'src_partinfo' and 'dst_partinfo', when non-NULL, refer to the source
* and destination partitions, respectively, of a cross-partition update of
* the root partitioned table mentioned in the query, given by 'relinfo'.
- * 'oldslot' contains the "old" tuple in the source partition, and 'newslot'
- * contains the "new" tuple in the destination partition. This interface
- * allows to support the requirements of ExecCrossPartitionUpdateForeignKey();
- * is_crosspart_update must be true in that case.
+ * 'tupleid' in that case refers to the ctid of the "old" tuple in the source
+ * partition, and 'newslot' contains the "new" tuple in the destination
+ * partition. This interface allows to support the requirements of
+ * ExecCrossPartitionUpdateForeignKey(); is_crosspart_update must be true in
+ * that case.
*/
void
ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
ResultRelInfo *src_partinfo,
ResultRelInfo *dst_partinfo,
+ ItemPointer tupleid,
HeapTuple fdw_trigtuple,
- TupleTableSlot *oldslot,
TupleTableSlot *newslot,
List *recheckIndexes,
TransitionCaptureState *transition_capture,
@@ -3107,14 +3117,29 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
* separately for DELETE and INSERT to capture transition table rows.
* In such case, either old tuple or new tuple can be NULL.
*/
+ TupleTableSlot *oldslot;
+ ResultRelInfo *tupsrc;
+
Assert((src_partinfo != NULL && dst_partinfo != NULL) ||
!is_crosspart_update);
- if (fdw_trigtuple != NULL)
- {
- Assert(oldslot);
+ tupsrc = src_partinfo ? src_partinfo : relinfo;
+ oldslot = ExecGetTriggerOldSlot(estate, tupsrc);
+
+ if (fdw_trigtuple == NULL && ItemPointerIsValid(tupleid))
+ GetTupleForTrigger(estate,
+ NULL,
+ tupsrc,
+ tupleid,
+ LockTupleExclusive,
+ oldslot,
+ NULL,
+ NULL,
+ NULL);
+ else if (fdw_trigtuple != NULL)
ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false);
- }
+ else
+ ExecClearTuple(oldslot);
AfterTriggerSaveEvent(estate, relinfo,
src_partinfo, dst_partinfo,