summaryrefslogtreecommitdiffstats
path: root/src/backend/commands/trigger.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/backend/commands/trigger.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 0769ae3..72b1134 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -3056,10 +3056,6 @@ ExecBRUpdateTriggersNew(EState *estate, EPQState *epqstate,
* received in newslot. Neither we nor our callers have any further
* interest in the passed-in tuple, so it's okay to overwrite newslot
* with the newer data.
- *
- * (Typically, newslot was also generated by ExecGetUpdateNewTuple, so
- * that epqslot_clean will be that same slot and the copy step below
- * is not needed.)
*/
if (epqslot_candidate != NULL)
{
@@ -3068,14 +3064,36 @@ ExecBRUpdateTriggersNew(EState *estate, EPQState *epqstate,
epqslot_clean = ExecGetUpdateNewTuple(relinfo, epqslot_candidate,
oldslot);
- if (newslot != epqslot_clean)
+ /*
+ * Typically, the caller's newslot was also generated by
+ * ExecGetUpdateNewTuple, so that epqslot_clean will be the same
+ * slot and copying is not needed. But do the right thing if it
+ * isn't.
+ */
+ if (unlikely(newslot != epqslot_clean))
ExecCopySlot(newslot, epqslot_clean);
+
+ /*
+ * At this point newslot contains a virtual tuple that may
+ * reference some fields of oldslot's tuple in some disk buffer.
+ * If that tuple is in a different page than the original target
+ * tuple, then our only pin on that buffer is oldslot's, and we're
+ * about to release it. Hence we'd better materialize newslot to
+ * ensure it doesn't contain references into an unpinned buffer.
+ * (We'd materialize it below anyway, but too late for safety.)
+ */
+ ExecMaterializeSlot(newslot);
}
+ /*
+ * Here we convert oldslot to a materialized slot holding trigtuple.
+ * Neither slot passed to the triggers will hold any buffer pin.
+ */
trigtuple = ExecFetchSlotHeapTuple(oldslot, true, &should_free_trig);
}
else
{
+ /* Put the FDW-supplied tuple into oldslot to unify the cases */
ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false);
trigtuple = fdw_trigtuple;
}