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.
This commit is contained in:
Tom Lane 2008-10-09 16:35:13 +00:00
parent 5b61c9a812
commit a4f5d8a51e
2 changed files with 10 additions and 3 deletions

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.121 2008/01/01 19:46:00 momjian Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.121.2.1 2008/10/09 16:35:13 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1903,12 +1903,15 @@ compute_function_hashkey(FunctionCallInfo fcinfo,
/* get function OID */ /* get function OID */
hashkey->funcOid = fcinfo->flinfo->fn_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 * 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 * relation is intended to be used, so we leave trigrelOid zero; the hash
* entry built in this case will never really be used. * 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; TriggerData *trigdata = (TriggerData *) fcinfo->context;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.95 2008/01/01 19:46:00 momjian Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.95.2.1 2008/10/09 16:35:13 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -541,6 +541,10 @@ typedef struct PLpgSQL_func_hashkey
{ /* Hash lookup key for functions */ { /* Hash lookup key for functions */
Oid funcOid; 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 * 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 * the hashkey --- we want to compile the trigger separately for each