Assert failure in standard_join_search()

From: Richard Guo <guofenglinux(at)gmail(dot)com>
To: Pg Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Assert failure in standard_join_search()
Date: 2026-10-11 14:27:26
Message-ID: CAMbWs49xvh4-uPv3rxWkk_rtMT1ic+psHvEAxaFEXu2Rf-32Tw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Fuzzing testing ran into an assertion failure with this query:

create table t (a int);

select 1 from t t1
left join t t2 on true
left join lateral (select t2.a, 1 from t t3) s(x, y) on true
left join t t4 on t4.a = s.x
join t t5 on true
where s.y is not null;

TRAP: failed Assert("list_length(root->join_rel_level[levels_needed]) == 1")

The problem is in make_outerjoininfo(). When the join clause is
strict for a lower join's RHS, we assume it also references that RHS.
But find_nonnullable_rels() looks inside PHVs, so it can report a rel
that the PHV only references laterally, which pull_varnos() does not.
Here s.x is a PHV containing t2.a, so the t4 join ends up marked as
commutable with the t1/t2 join even though its clause doesn't mention
t2.

I think we can fix it by intersecting strict_relids with
clause_relids:

--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -2117,6 +2117,12 @@ make_outerjoininfo(PlannerInfo *root,
*/
strict_relids = find_nonnullable_rels((Node *) clause);

+ /*
+ * find_nonnullable_rels looks inside PlaceHolderVars, so it can report
+ * rels that the clause references only laterally. Ignore those.
+ */
+ strict_relids = bms_int_members(strict_relids, clause_relids);
+

Thoughts?

- Richard

Browse pgsql-hackers by date

  From Date Subject
Previous Message Hannu Krosing 2026-10-11 14:13:23 Re: Idea to enhance pgbench by more modes to generate data (multi-TXNs, UNNEST, COPY BINARY)