Re: [(known) BUG] DELETE/UPDATE more than one row in partitioned foreign table

From: Jakub Wartak <jakub(dot)wartak(at)enterprisedb(dot)com>
To: Manu <manuelreyesbravo(at)gmail(dot)com>
Cc: Ajit Awekar <ajitpostgres(at)gmail(dot)com>, Etsuro Fujita <etsuro(dot)fujita(at)gmail(dot)com>, Michael Paquier <michael(at)paquier(dot)xyz>, shihao zhong <zhong950419(at)gmail(dot)com>, Nikita Malakhov <hukutoc(at)gmail(dot)com>, Jehan-Guillaume de Rorthais <jgdr(at)dalibo(dot)com>, pgsql-hackers(at)lists(dot)postgresql(dot)org, rhaas(at)postgresql(dot)org
Subject: Re: [(known) BUG] DELETE/UPDATE more than one row in partitioned foreign table
Date: 2026-10-28 09:12:06
Message-ID: CAKZiRmzpABcNuk+ZrhmV3=GtaA2S=C3=vKw_ggXCUwQUv8D4ag@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Sat, Oct 24, 2026 at 2:29 AM Manu <manuelreyesbravo(at)gmail(dot)com> wrote:
>
> Hi Ajit,
>
> On Mon, Oct 19, 2026 at 11:17 AM Ajit Awekar <ajitpostgres(at)gmail(dot)com>
> wrote:
> > Only setrefs.c needed manual changes; there is no functional change
> > from V3.
>
> I applied V4 to today's master (126976a8ffc). It still applies
> cleanly, builds with --enable-cassert without warnings, and make check
> and postgres_fdw's check pass. The eight cases from my V3 review give
> output byte-identical to V3: the original case, the dropped and renamed
> columns with triggers, the mixed partitions and the self-join return
> the right rows; the chained case still updates the wrong rows, as
> documented.

Judging from behaviour from postgres_fdw on master+v4 it's almost LGTM, please
set as Ready for Commiter with v5, hopefully Commiters notice this bugfix. I'm
already past of understanding of all what is happening in this patchset and
edge cases with executor:

Some open question for debate questions I have are:

a. Confirmed one another edge-case regression in the executor with v4, given:

DROP TABLE big;
DROP FOREIGN TABLE fbig;
CREATE TABLE big (id int primary key, a int, b text);
INSERT INTO big SELECT s, s, 'x'||s FROM generate_series(1,10) s;
ANALYZE big;
CREATE FOREIGN TABLE fbig (id int, a int, b text)
SERVER loopback OPTIONS (table_name 'big');

and now accessing whole row blows up:

postgres=# DELETE FROM fbig WHERE fbig.* IS NULL AND random() <= 1;
ERROR: attribute 3 of type record has wrong type
DETAIL: Table has type fbig, but query expects record.
postgres=# \errverbose
ERROR: 42804: attribute 3 of type record has wrong type
DETAIL: Table has type fbig, but query expects record.
LOCATION: CheckVarSlotCompatibility, execExprInterp.c:2429

and without v4 it is still working:

postgres=# DELETE FROM fbig WHERE fbig.* IS NULL AND random() <= 1;
DELETE 0

quite funny thing is that ROW(id, a, b) instead of fbig.* works there.

b. in plenty of places, e.g. in set_rel_width() and add_vars_to_targetlist(),
there is this thing:
Assert(blabla.fdwroutine != NULL)
for checking this trick of using >max_attr can be done only by FDWs. But
some people developing custom FDWs probably might not run without asserts,
so that wouldn't hit? Maybe we need runtime elog() to catch it? It's open
question.

b. I think also you should split the patch into two files for their's easier
review (something easy: one with optimizer changes and the second one with
just postgres_fdw changes alone)

d. Perhaps, the remaining elephant in the room would be what to do with
backpatching (today this might be corrupting data logically), but to me
those optimizer/executor changes look like invasive (and/or risky).

-J.

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Xuneng Zhou 2026-10-28 09:32:55 Re: Deadlock detector fails to activate on a hot standby replica
Previous Message Iliia Khaprov 2026-10-28 09:05:58 Re: [PATCH] Remove useless ORDER BY from scalar subqueries