Fix for recursive plpython triggers

Lists: pgsql-hackers
From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Fix for recursive plpython triggers
Date: 2024-05-04 20:16:39
Message-ID: 3008982.1714853799@sss.pgh.pa.us
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

This fixes bug #18456 [1]. Since we're in back-branch release freeze,
I'll just park it for the moment. But I think we should shove it in
once the freeze lifts so it's in 17beta1.

regards, tom lane

[1] https://www.postgresql.org/message-id/18456-82d3d70134aefd28%40postgresql.org

Attachment Content-Type Size
v1-save-TD-in-recursive-plpython-triggers.patch text/x-diff 6.5 KB

From: Andreas Karlsson <andreas(at)proxel(dot)se>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: Fix for recursive plpython triggers
Date: 2024-05-08 07:03:01
Message-ID: 1651a46d-3c15-4028-a8c1-d74937b54e19@proxel.se
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

On 5/4/24 10:16 PM, Tom Lane wrote:
> This fixes bug #18456 [1]. Since we're in back-branch release freeze,
> I'll just park it for the moment. But I think we should shove it in
> once the freeze lifts so it's in 17beta1.
There is a similar issue with the return type (at least if it is a
generic record) in the code but it is hard to trigger with sane code so
I don't know if it is worth fixing but this and the bug Jacques found
shows the downsides of the hacky fix for recursion that we have in plpython.

I found this issue while reading the code, so am very unclear if there
is any sane code which could trigger it.

In the example below the recursive call to f('int') changes the return
type of the f('text') call causing it to fail.

# CREATE OR REPLACE FUNCTION f(t text) RETURNS record LANGUAGE
plpython3u AS $$
if t == "text":
plpy.execute("SELECT * FROM f('int') AS (a int)");
return { "a": "x" }
elif t == "int":
return { "a": 1 }
$$;
CREATE FUNCTION

# SELECT * FROM f('text') AS (a text);
ERROR: invalid input syntax for type integer: "x"
CONTEXT: while creating return value
PL/Python function "f"

Andreas


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Andreas Karlsson <andreas(at)proxel(dot)se>
Cc: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: Fix for recursive plpython triggers
Date: 2024-05-08 15:51:17
Message-ID: 552755.1715183477@sss.pgh.pa.us
Views: Whole Thread | Raw Message | Download mbox | Resend email
Lists: pgsql-hackers

Andreas Karlsson <andreas(at)proxel(dot)se> writes:
> I found this issue while reading the code, so am very unclear if there
> is any sane code which could trigger it.

> In the example below the recursive call to f('int') changes the return
> type of the f('text') call causing it to fail.

> # CREATE OR REPLACE FUNCTION f(t text) RETURNS record LANGUAGE
> plpython3u AS $$
> if t == "text":
> plpy.execute("SELECT * FROM f('int') AS (a int)");
> return { "a": "x" }
> elif t == "int":
> return { "a": 1 }
> $$;
> CREATE FUNCTION

> # SELECT * FROM f('text') AS (a text);
> ERROR: invalid input syntax for type integer: "x"
> CONTEXT: while creating return value
> PL/Python function "f"

Oh, nice one. I think we can fix this trivially though: the problem
is that RECORD return-type setup was stuck into PLy_function_build_args,
where it has no particular business being in the first place, rather
than being done at the point of use. We can just move the code.

regards, tom lane

Attachment Content-Type Size
fix-plpython-record-result-setup.patch text/x-diff 1.7 KB