From b15531033e8bcff1e0a436d6bd18b5a09e477a20 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 9 Oct 2008 16:35:07 +0000
Subject: [PATCH] Fix overly tense optimization of PLpgSQL_func_hashkey: we
 must represent the isTrigger state explicitly, not rely on nonzero-ness of
 trigrelOid to indicate trigger-hood, because trigrelOid will be left zero
 when compiling for validation.  The (useless) function hash entry built by
 the validator was able to match an ordinary non-trigger call later in the
 same session, thereby bypassing the check that is supposed to prevent such a
 call. Per report from Alvaro.

It might be worth suppressing the useless hash entry altogether, but
that's a bigger change than I want to consider back-patching.

Back-patch to 8.0.  7.4 doesn't have the problem because it doesn't
have validation mode.
---
 src/pl/plpgsql/src/pl_comp.c | 7 +++++--
 src/pl/plpgsql/src/plpgsql.h | 6 +++++-
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 1355c827d19..4c88e2ac4cb 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.130 2008/09/01 20:42:46 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.131 2008/10/09 16:35:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1941,12 +1941,15 @@ compute_function_hashkey(FunctionCallInfo fcinfo,
 	/* get function OID */
 	hashkey->funcOid = fcinfo->flinfo->fn_oid;
 
+	/* get call context */
+	hashkey->isTrigger = CALLED_AS_TRIGGER(fcinfo);
+
 	/*
 	 * if trigger, get relation OID.  In validation mode we do not know what
 	 * relation is intended to be used, so we leave trigrelOid zero; the hash
 	 * entry built in this case will never really be used.
 	 */
-	if (CALLED_AS_TRIGGER(fcinfo) && !forValidator)
+	if (hashkey->isTrigger && !forValidator)
 	{
 		TriggerData *trigdata = (TriggerData *) fcinfo->context;
 
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 735a6810053..8cc050773fb 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.100 2008/05/15 22:39:49 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.101 2008/10/09 16:35:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -616,6 +616,10 @@ typedef struct PLpgSQL_func_hashkey
 {								/* Hash lookup key for functions */
 	Oid			funcOid;
 
+	bool		isTrigger;		/* true if called as a trigger */
+
+	/* be careful that pad bytes in this struct get zeroed! */
+
 	/*
 	 * For a trigger function, the OID of the relation triggered on is part of
 	 * the hashkey --- we want to compile the trigger separately for each
-- 
GitLab