pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
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) download diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index 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])

view thread (6+ messages)  latest in thread

Message-ID: <4048043.1662653834@sss.pgh.pa.us>
Permalink:  ../4048043.1662653834@sss.pgh.pa.us/
Also on:    postgresql.org/message-id/4048043.1662653834@sss.pgh.pa.us

 ·  · 

reply

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