Re: BUG #17610: Use of multiple composite types incompatible with record-typed function parameter

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Japin Li <japinli(at)hotmail(dot)com>
Cc: mjurca(at)centrum(dot)cz, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #17610: Use of multiple composite types incompatible with record-typed function parameter
Date: 2022-09-08 18:36:47
Message-ID: 4102534.1662662207@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

I wrote:
> 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.)

Oh ... I see why we hadn't noticed this before. The case works fine
if you refer to the RECORD parameter by name, like this example from
our regression tests:

create function getf1(x record) returns int language plpgsql as
$$ begin return x.f1; end $$;

It does not work fine when you do this:

create function getf1(record) returns int language plpgsql as
$$ begin return $1.f1; end $$;

The reason is that the core parser's callback APIs allow plpgsql
to deal with the "x.f1" construct as a unit, and it can handle
the varying actual type of "x" internally. However, the callback
APIs are not equivalently intelligent about "$N" references.
Those get resolved as Params of type RECORD (with a separate
FieldSelect on top, in this case), and then we don't have enough
context to figure out which record type is involved, or indeed
that different record types could be involved.

My proposed patch fixes things for the case where the caller
passes a named composite type, but not for passing an anonymous
record, as you can see in the test cases in the attached.
(If you don't apply the code patch, the last getf2() call also
fails, matching the OP's complaint. But the getf1() calls
still work.)

So really the way we ought to fix this is to upgrade the parser
APIs so that plpgsql could deal with "$1.f1" as a unit. But
that seems like a lot of work, and it would certainly not be
back-patchable.

In the meantime, I'm uncertain whether we want this change or not.
Duplicating the function cache entry for each composite type
that gets passed during a session is a pretty expensive solution,
especially if it only fixes cases that are being written in a
semi-deprecated fashion.

regards, tom lane

Attachment Content-Type Size
treat-record-inputs-as-polymorphism-2.patch text/x-diff 5.3 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message David Rowley 2022-09-08 21:35:04 Re: huge memory of Postgresql backend process
Previous Message Jeff Davis 2022-09-08 17:30:05 Re: PANIC in heap_delete during ALTER TABLE