From: | Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com> |
---|---|
To: | Joel Jacobson <joel(at)compiler(dot)org> |
Cc: | pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Assert single row returning SQL-standard functions |
Date: | 2025-08-29 12:30:35 |
Message-ID: | CAFj8pRC_8N1B=ZEz=Em5Cisw-BRMASgkQ4QuE50SMBRMAchigA@mail.gmail.com |
Views: | Whole Thread | Raw Message | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
pá 29. 8. 2025 v 12:22 odesílatel Joel Jacobson <joel(at)compiler(dot)org> napsal:
> On Fri, Aug 29, 2025, at 12:12, Pavel Stehule wrote:
>
> >> Yes, maybe, do you mean something like below?
> >> CREATE OR REPLACE FUNCTION fx(_a int)
> >> RETURNS bool
> >> SET assert_single_row = true
> >> BEGIN ATOMIC
> >> SELECT id = _a FROM footab WHERE id = _a; END;
> >>
> >
> > maybe, but the question is a scope. It should to work everywhere, or
> > just inside SQL function - or just for last SQL command in SQL function?
>
> Yeah, good question. I can see a value in such a GUC for psql sessions,
> to prevent against accidentally updating/deleting more rows than
> intended, but that's more "rows affected" than "rows returned", so maybe
> not a good match? If the semantics rows affected for DML, then it would
> work for functions that returns VOID also, so maybe that's better.
>
> Thanks to your ideas and focus on trying to find a way to achieve this
> with what we already have, I came up with a trick to prevent against
> >1 rows for DML, which is to use a SETOF returning wrapper function,
> in combination with the RETURN (...) trick:
>
> CREATE TABLE footab (id INT);
> INSERT INTO footab (id) VALUES (1), (10), (10);
>
> CREATE FUNCTION _test_update(_a int)
> RETURNS SETOF int
> BEGIN ATOMIC
> UPDATE footab SET id = _a WHERE id = _a RETURNING id;
> END;
>
> CREATE FUNCTION test_update(_a int)
> RETURNS int
> RETURN (SELECT _test_update(_a));
>
> joel=# SELECT test_update(1);
> test_update
> -------------
> 1
> (1 row)
>
> joel=# SELECT test_update(10);
> ERROR: more than one row returned by a subquery used as an expression
> CONTEXT: SQL function "test_update" statement 1
>
> Could something like that work? If so, then with your NOT NULL flag idea
> we would have a solution!
>
another possibility is to use plpgsql and extra check of row_count. It will
be more verbose and maybe more intuitive.
the overhead of plpgsql is low and usually it is faster than non-inlined
sql. Dependencies can be generated from plpgsql_check dependency report
>
> /Joel
>
From | Date | Subject | |
---|---|---|---|
Next Message | Hayato Kuroda (Fujitsu) | 2025-08-29 12:31:18 | RE: POC: enable logical decoding when wal_level = 'replica' without a server restart |
Previous Message | Bernd Reiß | 2025-08-29 11:45:52 | Re: Use-after-free in expand_partitioned_rtentry |