Re: BUG #19653: "variable not found in subplan target list" during planning with parallel parameterized nested loop,

From: Richard Guo <guofenglinux(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: 10215501441(at)stu(dot)ecnu(dot)edu(dot)cn, Robert Haas <robertmhaas(at)gmail(dot)com>, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #19653: "variable not found in subplan target list" during planning with parallel parameterized nested loop,
Date: 2026-09-04 23:09:42
Message-ID: CAMbWs4_aJo_wEQCzT=mLBSQEdKt-J0OM5weZtt-szZSKvnPusw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On Sat, Sep 5, 2026 at 12:27 AM Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> The proximate cause of the failure is that we have a NestLoopParam
> containing a Var, which we need to find in the tlist of the nestloop's
> outer relation, but what is in the tlist is a PlaceHolderVar wrapping
> that Var. So it's possible to see some connection to cc5d98525, but
> it seems entirely accidental that 014f9a831 fixed it. I bet there
> are related cases that are still broken.

I think the connection to cc5d98525 is also accidental. cc5d98525
just makes it possible for plain Vars to be wrapped in PHV, but this
failure can be reproduced with PHVs built from other ways, such as
non-strict expressions from the nullable-side of an outer join. For
me, I can reproduce this same error on all branches from v14 to
master with the query below, using tables in partition_join.sql.

set enable_partitionwise_join to on;

EXPLAIN (COSTS OFF)
SELECT * FROM prt1 t1 LEFT JOIN
(SELECT b, COALESCE(c, 'x') AS c FROM prt2 WHERE a = 0) t2 ON t1.a = t2.b
WHERE t1.c = t2.c;
ERROR: variable not found in subplan target list

It seems to me the root cause is that in a partitionwise child join,
root->curOuterRels holds child relids, but PlaceHolderInfo.ph_eval_at
is always expressed in top-parent relids. So in
replace_nestloop_params_mutator the subset check fails for a PHV
evaluated at the outer child rel.

It seems we can fix it by:

@@ -4374,8 +4374,15 @@ create_nestloop_plan(PlannerInfo *root,
/* NestLoop can project, so no need to be picky about child tlists */
outer_plan = create_plan_recurse(root, best_path->jpath.outerjoinpath, 0);

- /* For a nestloop, include outer relids in curOuterRels for inner side */
+ /*
+ * For a nestloop, include outer relids in curOuterRels for inner side.
+ * If the outer rel is a child rel, also include its top parent's relids,
+ * since PlaceHolderInfo.ph_eval_at is expressed in terms of parent rels.
+ */
outerrelids = best_path->jpath.outerjoinpath->parent->relids;
+ if (best_path->jpath.outerjoinpath->parent->top_parent_relids)
+ outerrelids = bms_union(outerrelids,
+
best_path->jpath.outerjoinpath->parent->top_parent_relids);

- Richard

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message Andrey Rachitskiy 2026-09-05 07:52:39 Re: BUG #19649: Qual pushdown into GROUP BY subqueries ignores non-equivalence-preserving references to grouping col
Previous Message Tom Lane 2026-09-04 17:27:19 Re: BUG #19644: byteaout, float8out and float4out are marked IMMUTABLE but depend on GUCs