On Wed, Aug 5, 2026 at 11:48 PM Gleb Kashkin <[email protected]> wrote:
> Thank you for the fix!

You are welcome!  Pushed/backpatched after tweaking a comment a bit.

While working on the back-patch for v14, I noticed that async is
disabled for the test cases in v14.  I didn't look into that in
detail, but I think that the reason is probably is_async_capable_plan
in v14, which is restrictive compared to new versions.  However, I
think that v14 too would have the same issue, so I applied the patch
to v14 as well after just removing the test cases.  I think we could
add test cases for v14 later if needed.

For the record: here is a test case that produces incorrect results on
a production build without the patch.  It might depend on the
environment, though.  (On an assert-enabled build it causes an
assertion failure.)  I didn't add this, though, as it's
time-consuming:

create table base_tbl1 (a int, b int, c text);
create table base_tbl2 (a int, b int, c text);
create table base_tbl3 (a int, b int, c text);

insert into base_tbl1 select 1000 + i, i, to_char(i, 'FM0000') from
generate_series(0, 999, 5) i;
insert into base_tbl2 values (2000, 0, '0000');
insert into base_tbl3 select 3000 + i, i, to_char(i, 'FM0000') from
generate_series(0, 999, 5) i;

create view base_tbl2_slow as with delay as materialized (select
pg_sleep(1.0)) select t.* from base_tbl2 t, delay where t.a > 2500;;

create server loopback foreign data wrapper postgres_fdw options
(dbname 'postgres');
create server loopback2 foreign data wrapper postgres_fdw options
(dbname 'postgres');

alter server loopback options (add async_capable 'true');
alter server loopback2 options (add async_capable 'true');

create user mapping for current_user server loopback;
create user mapping for current_user server loopback2;

create table async_pt (a int, b int, c text) partition by range (a);
create foreign table async_p1 partition of async_pt for values from
(1000) to (2000) server loopback options (table_name 'base_tbl1');
create foreign table async_p2 partition of async_pt for values from
(2000) to (3000) server loopback2 options (table_name
'base_tbl2_slow');
create foreign table async_p3 partition of async_pt for values from
(3000) to (4000) server loopback2 options (table_name 'base_tbl3');

analyze async_pt;

create function rescantest(int) returns boolean as 'begin if $1 < 3000
then return true; else perform count(*) from async_p2; return false;
end if; end;' language plpgsql;

select o.x from (values (2505), (3505)) o(x), lateral (select a from
async_pt where a = o.x or (a = 1505 and rescantest(o.x)) limit 1) s
order by o.x;

Thanks again!

Best regards,
Etsuro Fujita


Reply via email to