Re: BUG #18463: Possible bug in stored procedures with polymorphic OUT parameters

Andrew Bille <andrewbille@gmail.com>

From: Andrew Bille <andrewbille@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Dmitry Dolgov <9erthalion6@gmail.com>, drewk@cockroachlabs.com, pgsql-bugs@lists.postgresql.org
Date: 2024-06-04T14:22:37Z
Lists: pgsql-bugs

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Fix failure with SQL-procedure polymorphic output arguments in v12.

  2. Fix handling of polymorphic output arguments for procedures.

Hello!

After 70ffb27b in REL_12 following script
CREATE OR REPLACE PROCEDURE p(inout a anyelement, inout b anyelement)
LANGUAGE SQL
AS $$
  SELECT $1, 1;
$$;
CALL p(1.1, null);
crash server with backtrace:
Core was generated by `postgres: andrew postgres'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000055b81c1d090d in memcpy (__len=18446744073709551615,
__src=0x55b81d000239, __dest=0x55b81cfefc94) at
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:29
29        return __builtin___memcpy_chk (__dest, __src, __len,
(gdb) bt
#0  0x000055b81c1d090d in memcpy (__len=18446744073709551615,
__src=0x55b81d000239, __dest=0x55b81cfefc94) at
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:29
#1  heap_tuple_untoast_attr (attr=0x55b81d000238) at tuptoaster.c:243
#2  0x000055b81c570b35 in pg_detoast_datum (datum=<optimized out>) at
fmgr.c:1742
#3  0x000055b81c4e5491 in numeric_out (fcinfo=<optimized out>) at
numeric.c:649
#4  0x000055b81c570728 in FunctionCall1Coll (arg1=<optimized out>,
collation=0, flinfo=0x55b81cf5d730) at fmgr.c:1140
#5  OutputFunctionCall (flinfo=0x55b81cf5d730, val=<optimized out>) at
fmgr.c:1577
#6  0x000055b81c190d5d in printtup (slot=0x55b81cf5d438,
self=0x55b81cf3b1a0) at printtup.c:434
#7  0x000055b81c45c1be in RunFromStore (portal=portal@entry=0x55b81cfa0d30,
direction=direction@entry=ForwardScanDirection, count=count@entry=0,
dest=0x55b81cf3b1a0) at pquery.c:1112
#8  0x000055b81c45c25b in PortalRunSelect (portal=0x55b81cfa0d30,
forward=<optimized out>, count=0, dest=<optimized out>) at pquery.c:934
#9  0x000055b81c45da3e in PortalRun (portal=portal@entry=0x55b81cfa0d30,
count=count@entry=9223372036854775807, isTopLevel=isTopLevel@entry=true,
run_once=run_once@entry=true, dest=dest@entry=0x55b81cf3b1a0,
altdest=altdest@entry=0x55b81cf3b1a0, completionTag=0x7ffd621f8850 "") at
pquery.c:779
#10 0x000055b81c4597a1 in exec_simple_query (query_string=0x55b81cf39f10
"CALL p(1.1, null);") at postgres.c:1214
#11 0x000055b81c45b5f2 in PostgresMain (argc=<optimized out>,
argv=argv@entry=0x55b81cf64e68, dbname=<optimized out>, username=<optimized
out>) at postgres.c:4297
#12 0x000055b81c3e71a7 in BackendRun (port=0x55b81cf5c140) at
postmaster.c:4517
#13 BackendStartup (port=0x55b81cf5c140) at postmaster.c:4200
#14 ServerLoop () at postmaster.c:1725
#15 0x000055b81c3e80c2 in PostmasterMain (argc=argc@entry=3,
argv=argv@entry=0x55b81cf346b0)
at postmaster.c:1398
#16 0x000055b81c18594d in main (argc=3, argv=0x55b81cf346b0) at main.c:228

This doesn't repoduce in 13+

Best regards, Andrew!

On Tue, Jun 4, 2024 at 9:16 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

> Dmitry Dolgov <9erthalion6@gmail.com> writes:
> > I'm now curious why it is different for functions, when creating one
> > with an INOUT ANYELEMENT argument and record return type will error out.
> > Disabling the corresponding ereport check in CreateFunction seems to
> > produce a function that works in the similar way as the procedure in
> > this thread. Are those type of functions incorrect in some way?
>
> With procedures, there's no explicit RETURNS clause; we just
> automatically fill RECORD into prorettype because (a) we gotta
> put something and (b) that's the right thing anyway if there's
> multiple OUT parameters.  Arguably it's not wrong for a single
> output parameter, either, since CALL will return a tuple in
> that case too.  I think it might've been better to put VOID
> for the case of zero output parameters, since CALL doesn't
> return a zero-column tuple in that case.  But that ship's
> sailed, and it's not worth quibbling about.
>
> We do this differently for functions: if there's exactly one
> output parameter, that is the function result, so prorettype
> has to match.  If we were to allow RETURNS RECORD with a
> single output parameter, I think that'd have to mean that
> we return a one-column tuple containing that parameter value.
> That's not implemented, and I have doubts that it'd be useful.
> It'd certainly be a bit inefficient.
>
>                         regards, tom lane
>
>
>
>
>