Hi hackers, I used Opus to analyze the new features in PG19, and it found a problem with the "SELECT simple-expression INTO var" fast path from ce8d5fe0e28.
create function f1() returns int language sql as 'select 1';
create function caller() returns bool language plpgsql as $$
declare v int;
begin
select f1() into v;
return found;
end $$;
select caller();
drop function f1();
create function f1() returns setof int language sql
as 'select 1 where false';
select caller();
The last call gives f on 18 and t on 19. Only the first call after the
change is wrong. The attached .sql has more cases.
It is hard to hit. f1() has to be recreated as set-returning while a
session has caller() cached, for example by an extension update.
I think it is because exec_stmt_execsql() calls exec_eval_expr(), which
falls back to SPI when a replan finds the query is no longer simple.
FOUND is then set as if one row came back.
0001 calls exec_eval_simple_expr() directly and uses the regular SPI
code when it returns false. That is the only time the new branch runs,
so the fast path costs the same. It also removes a doubled 'SQL
statement' context line in errors raised under recursion. 0002 is a
test, it is optional.
It is a regression from 18, but a narrow one, so I will not set the open
items list.
Thanks,
Shihao
v1-0001-plpgsql-fix-SELECT-INTO-when-the-expression-is-no.patch
Description: Binary data
v1-0002-plpgsql-test-SELECT-INTO-after-a-function-becomes.patch
Description: Binary data
