[PG19] plpgsql: SELECT INTO sets FOUND wrongly after a function becomes a SRF - Mailing list pgsql-hackers

From shihao zhong
Subject [PG19] plpgsql: SELECT INTO sets FOUND wrongly after a function becomes a SRF
Date
Msg-id CAGRkXqQB_aqWU9OeVPGvATBVZ7c9EYrNXJyHG0jKXW0FGAy2-g@mail.gmail.com
Whole thread
Responses Re: [PG19] plpgsql: SELECT INTO sets FOUND wrongly after a function becomes a SRF
List pgsql-hackers
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
Attachment

pgsql-hackers by date:

Previous
From: Tomas Vondra
Date:
Subject: Re: hashjoins vs. Bloom filters (yet again)
Next
From: Greg Burd
Date:
Subject: Re: Let an ordering index scan hand its ORDER BY value to the target list