From f5b78fa51fa69d5fbf1282ed6e5374b83aabdabc Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 3 Aug 2006 16:04:41 +0000
Subject: [PATCH] Fix AfterTriggerExecute() to pass tg_trigtuple and
 tg_newtuple as NULLs rather than pointers to garbage, when calling AFTER
 STATEMENT triggers. Michael Fuhr

---
 src/backend/commands/trigger.c | 45 ++++++++++++++--------------------
 1 file changed, 19 insertions(+), 26 deletions(-)

diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 13e7cab721b..42d89a9a21a 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.205 2006/07/31 20:09:00 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.206 2006/08/03 16:04:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2090,11 +2090,18 @@ AfterTriggerExecute(AfterTriggerEvent event,
 	/*
 	 * Fetch the required OLD and NEW tuples.
 	 */
+	LocTriggerData.tg_trigtuple = NULL;
+	LocTriggerData.tg_newtuple = NULL;
+	LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
+	LocTriggerData.tg_newtuplebuf = InvalidBuffer;
+
 	if (ItemPointerIsValid(&(event->ate_oldctid)))
 	{
 		ItemPointerCopy(&(event->ate_oldctid), &(oldtuple.t_self));
 		if (!heap_fetch(rel, SnapshotAny, &oldtuple, &oldbuffer, false, NULL))
 			elog(ERROR, "failed to fetch old tuple for AFTER trigger");
+		LocTriggerData.tg_trigtuple = &oldtuple;
+		LocTriggerData.tg_trigtuplebuf = oldbuffer;
 	}
 
 	if (ItemPointerIsValid(&(event->ate_newctid)))
@@ -2102,40 +2109,26 @@ AfterTriggerExecute(AfterTriggerEvent event,
 		ItemPointerCopy(&(event->ate_newctid), &(newtuple.t_self));
 		if (!heap_fetch(rel, SnapshotAny, &newtuple, &newbuffer, false, NULL))
 			elog(ERROR, "failed to fetch new tuple for AFTER trigger");
+		if (LocTriggerData.tg_trigtuple != NULL)
+		{
+			LocTriggerData.tg_newtuple = &newtuple;
+			LocTriggerData.tg_newtuplebuf = newbuffer;
+		}
+		else
+		{
+			LocTriggerData.tg_trigtuple = &newtuple;
+			LocTriggerData.tg_trigtuplebuf = newbuffer;
+		}
 	}
 
 	/*
-	 * Setup the trigger information
+	 * Setup the remaining trigger information
 	 */
 	LocTriggerData.type = T_TriggerData;
 	LocTriggerData.tg_event =
 		event->ate_event & (TRIGGER_EVENT_OPMASK | TRIGGER_EVENT_ROW);
 	LocTriggerData.tg_relation = rel;
 
-	switch (event->ate_event & TRIGGER_EVENT_OPMASK)
-	{
-		case TRIGGER_EVENT_INSERT:
-			LocTriggerData.tg_trigtuple = &newtuple;
-			LocTriggerData.tg_newtuple = NULL;
-			LocTriggerData.tg_trigtuplebuf = newbuffer;
-			LocTriggerData.tg_newtuplebuf = InvalidBuffer;
-			break;
-
-		case TRIGGER_EVENT_UPDATE:
-			LocTriggerData.tg_trigtuple = &oldtuple;
-			LocTriggerData.tg_newtuple = &newtuple;
-			LocTriggerData.tg_trigtuplebuf = oldbuffer;
-			LocTriggerData.tg_newtuplebuf = newbuffer;
-			break;
-
-		case TRIGGER_EVENT_DELETE:
-			LocTriggerData.tg_trigtuple = &oldtuple;
-			LocTriggerData.tg_newtuple = NULL;
-			LocTriggerData.tg_trigtuplebuf = oldbuffer;
-			LocTriggerData.tg_newtuplebuf = InvalidBuffer;
-			break;
-	}
-
 	MemoryContextReset(per_tuple_context);
 
 	/*
-- 
GitLab