Re: postgres_fdw: transaction mode inheritance corner cases

From: Nikolay Samokhvalov <nik(at)postgres(dot)ai>
To: Matheus Alcantara <matheusssilv97(at)gmail(dot)com>
Cc: Etsuro Fujita <etsuro(dot)fujita(at)gmail(dot)com>, Fujii Masao <masao(dot)fujii(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: postgres_fdw: transaction mode inheritance corner cases
Date: 2026-10-06 22:37:12
Message-ID: CAM527d8v2EvmNYA5xfsoV2dyAgjh4V1gqWRq4HmOxTiKkjaifw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Sat, Oct 3, 2026 at 6:38 PM Matheus Alcantara
<matheusssilv97(at)gmail(dot)com> wrote:
> So 0003 declares the remote cursor before
> synchronizing the remote savepoint level, and raises the error only if
> the current remote depth is deeper than the level of the local cursor.

There is another case 0003 misses: parameter evaluation
can open a remote savepoint after create_cursor() checks the depth.

With 0001 and 0003 on REL_19_STABLE at a2148471, run this in a fresh
cursor_min database. Pass its socket directory and port as psql
variables sock and port:

create extension postgres_fdw;

create table t (id int);
insert into t values (1);

create server s foreign data wrapper postgres_fdw options (dbname
'cursor_min', host :'sock', port :'port');
create user mapping for current_user server s;
create foreign table ft (id int) server s options (table_name 't',
fetch_size '1');
create foreign table fa (id int) server s options (table_name 't');

begin;
declare c cursor for select * from ft where id = (select id from fa limit 1);
savepoint sp;
fetch c;
rollback to sp;
fetch c;
commit;

With 0001 alone, the first fetch is rejected by its depth check. With
0003, it returns 1, but the second fetch fails after rollback: cursor
"c2" does not exist. On clean REL_19_STABLE, the second fetch returns
no rows and commit succeeds.

The subquery becomes an initplan for the outer scan's $1 parameter.
process_query_params() runs it after the depth check. Its scan opens a
remote savepoint, so the outer cursor is declared inside it and removed
by rollback to sp.

Nik

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message surya poondla 2026-10-06 23:11:33 Re: pg_walinspect: add functions to locate and list WAL by time and LSN
Previous Message Manu 2026-10-06 22:24:34 Re: Bug: ATTACH PARTITION can leave rows violating default partition constraint