From: Tom Lane <tgl@sss.pgh.pa.us>
To: Japin Li <japinli@hotmail.com>
Cc: mjurca@centrum.cz
Cc: pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #17610: Use of multiple composite types incompatible with record-typed function parameter
Date: Thu, 08 Sep 2022 12:17:14 -0400
Message-ID: <4048043.1662653834@sss.pgh.pa.us> (raw)
In-Reply-To: <MEYP282MB16693A87D77FF13C23E45EA4B6409@MEYP282MB1669.AUSP282.PROD.OUTLOOK.COM>
References: <17610-fb1eef75bf6c2364@postgresql.org>
<MEYP282MB16693A87D77FF13C23E45EA4B6409@MEYP282MB1669.AUSP282.PROD.OUTLOOK.COM>
Japin Li <japinli@hotmail.com> writes:
> On Thu, 08 Sep 2022 at 18:19, PG Bug reporting form <noreply@postgresql.org> wrote:
>> The SQL code at the end of this bug report ends with the following error:
>> 2022-09-08 10:09:02.173 GMT [174] ERROR: type of parameter 1
>> (composite_type_2) does not match that when preparing the plan
>> (composite_type_1)
> The documentation says:
> The mutable nature of record variables presents another problem in this
> connection. When fields of a record variable are used in expressions or
> statements, **the data types of the fields must not change from one call
> of the function to the next**, since each expression will be analyzed
> using the data type that is present when the expression is first reached.
I think that is specifically referring to function internal variables of
type RECORD, which are handled specially. For function input arguments,
we could get around this by treating RECORD like a polymorphic type, as
attached. (For some reason I thought we already did that, but nope.)
regards, tom lane
Attachments:treat-record-inputs-as-polymorphism.patch (text/x-diff, 2.3K) downloaddiff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.cindex 61fbdf0686..4d68f030e4 100644--- a/src/pl/plpgsql/src/pl_comp.c+++ b/src/pl/plpgsql/src/pl_comp.c@@ -2498,9 +2498,15 @@ compute_function_hashkey(FunctionCallInfo fcinfo,
/*
* This is the same as the standard resolve_polymorphic_argtypes() function,
- * but with a special case for validation: assume that polymorphic arguments- * are integer, integer-array or integer-range. Also, we go ahead and report- * the error if we can't resolve the types.+ * except that:+ * 1. We go ahead and report the error if we can't resolve the types.+ * 2. We treat RECORD-type input parameters (not output parameters) as if+ * they were polymorphic, replacing their types with the actual input+ * types if we can determine those. This allows us to create a separate+ * function cache entry for each named composite type passed to such a+ * parameter.+ * 3. In validation mode, we have no inputs to look at, so assume that+ * polymorphic arguments are integer, integer-array or integer-range.
*/
static void
plpgsql_resolve_polymorphic_argtypes(int numargs,
@@ -2512,6 +2518,8 @@ plpgsql_resolve_polymorphic_argtypes(int numargs,
if (!forValidator)
{
+ int inargno;+
/* normal case, pass to standard routine */
if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
call_expr))
@@ -2520,10 +2528,28 @@ plpgsql_resolve_polymorphic_argtypes(int numargs,
errmsg("could not determine actual argument "
"type for polymorphic function \"%s\"",
proname)));
+ /* also, treat RECORD inputs (but not outputs) as polymorphic */+ inargno = 0;+ for (i = 0; i < numargs; i++)+ {+ char argmode = argmodes ? argmodes[i] : PROARGMODE_IN;++ if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)+ continue;+ if (argtypes[i] == RECORDOID || argtypes[i] == RECORDARRAYOID)+ {+ Oid resolvedtype = get_call_expr_argtype(call_expr,+ inargno);++ if (OidIsValid(resolvedtype))+ argtypes[i] = resolvedtype;+ }+ inargno++;+ }
}
else
{
- /* special validation case */+ /* special validation case (no need to do anything for RECORD) */
for (i = 0; i < numargs; i++)
{
switch (argtypes[i])
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: tgl@sss.pgh.pa.us, japinli@hotmail.com, mjurca@centrum.cz, pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #17610: Use of multiple composite types incompatible with record-typed function parameter
In-Reply-To: <4048043.1662653834@sss.pgh.pa.us>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox