Wrong results with initplans moved by setrefs.c

From: Richard Guo <guofenglinux(at)gmail(dot)com>
To: Pg Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Wrong results with initplans moved by setrefs.c
Date: 2026-11-09 02:53:50
Message-ID: CAMbWs4_JzG96+RjzdEpRQ0-rWkuzU1cmj7xybpzFg6GYdGcE8Q@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Here is another wrong-result issue found when fuzzing with LLM. It
happens in all supported branches.

create table p (a int) partition by list (a);
create table p1 partition of p for values in (1);
insert into p values (1);

select v.x, s.y from (values (1), (2)) v(x),
lateral (select (select v.x) as y from p offset 0) s
where s.y > 0;
x | y
---+---
1 | 1
2 | 1
(2 rows)

Without the OFFSET 0, we get the right answer:

select v.x, s.y from (values (1), (2)) v(x),
lateral (select (select v.x) as y from p) s
where s.y > 0;
x | y
---+---
1 | 1
2 | 2
(2 rows)

In the first query, the initplan for "(select v.x)" is attached to the
Append over p. When setrefs.c removes that single-child Append,
clean_up_removed_plan_level() moves the initplan down to the Seq Scan
on p1. But the Seq Scan's extParam and allParam were computed by
SS_finalize_plan() before the move, so they don't include the Param
for v.x that the initplan depends on. So when the Subquery Scan is
rescanned for the second outer row, UpdateChangedParamSet() filters
that Param out, the initplan is never re-evaluated, and we keep
returning the value from the first row.

I believe the same bug can happen when a trivial SubqueryScan or a
single-child MergeAppend is removed, although I don't have a repro
query for that at the moment.

I think the fix is simply to merge the removed node's extParam and
allParam into the child's, something like below in
clean_up_removed_plan_level():

child->initPlan = list_concat(parent->initPlan,
child->initPlan);
+
+ child->extParam = bms_union(child->extParam, parent->extParam);
+ child->allParam = bms_union(child->allParam, parent->allParam);

Thoughts?

- Richard

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Stef Van Vlierberghe 2026-11-09 03:28:45 Re: Proposal to allow setting cursor options on Portals
Previous Message Michael Paquier 2026-11-09 02:46:39 Re: Add sortsupport to money_ops, pg_lsn_ops and xid8_ops