diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 4b295f8da5..8027498b73 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -2981,7 +2981,9 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
*
* (Typically, newslot was also generated by ExecGetUpdateNewTuple, so
* that epqslot_clean will be that same slot and the copy step below
- * is not needed.)
+ * is not needed. Though we need to materialize newslot in this case,
+ * since its tuple might share the oldslot's buffer, which might
+ * be freed on fetching trigtuple from oldslot.)
*/
if (epqslot_candidate != NULL)
{
@@ -2992,6 +2994,8 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
if (newslot != epqslot_clean)
ExecCopySlot(newslot, epqslot_clean);
+ else
+ ExecMaterializeSlot(newslot);
}
trigtuple = ExecFetchSlotHeapTuple(oldslot, true, &should_free_trig);