Re: BUG #19626: Segmentation fault planning self-join IN subquery with LATERAL UNION ALL

From: Andrey Rachitskiy <pl0h0yp1(at)gmail(dot)com>
To: syzhong16(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #19626: Segmentation fault planning self-join IN subquery with LATERAL UNION ALL
Date: 2026-08-18 13:29:40
Message-ID: CAB8bMitstgj-VxwVPKYjdvXt+Q9oLyjXZ6BHOnwycCEEbAA8OQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

вт, 18 авг. 2026 г. в 17:16, PG Bug reporting form <noreply(at)postgresql(dot)org>:

> The following bug has been logged on the website:
>
> Bug reference: 19626
> Logged by: Suyang Zhong
> Email address: syzhong16(at)gmail(dot)com
> PostgreSQL version: 19beta3
> Operating system: Ubuntu 22.04
> Description:
>
> Hi,
>
> The following test case caused a segmentation fault.
>
> ```
> CREATE TABLE t0(c2 INT PRIMARY KEY, c3 INT);
>
> SELECT count(*) FROM t0
> INNER JOIN LATERAL (SELECT t0.c3 UNION ALL SELECT t0.c3) AS s ON (s.c3 IS
> NOT NULL)
> WHERE t0.c2 IN (SELECT c2 FROM t0);
> -- server closed the connection unexpectedly
> ```
>
> Hi, Suyang!

Thanks for the report.

SET enable_self_join_elimination = off avoids the crash.
So does replacing the IS NOT NULL with ON true, using UNION rather than
UNION ALL, or omitting a unique index on c2. A UNIQUE constraint is enough.
It does not have to be a primary key.

Backtrace:
```
#0 var_is_nonnullable (root=..., var=..., source=...) at clauses.c:4726
rte = 0x0
#1 expr_is_nonnullable () at clauses.c:4823
#2 eval_const_expressions_mutator () at clauses.c:3942
#3 eval_const_expressions () at clauses.c:2537
#4 apply_child_basequals () at inherit.c:866
#5 build_simple_rel () at relnode.c:425
#6 expand_appendrel_subquery () at inherit.c:818
#7 expand_inherited_rtentry () at inherit.c:102
#8 add_other_rels_to_query () at initsplan.c:235
#9 query_planner () at planmain.c:285
```

The LATERAL UNION ALL is flattened to an appendrel. The leaf expressions
t0.c3 are stored in AppendRelInfo.translated_vars. The IN subquery on the
primary key is reduced to an inner join and then removed by self-join
elimination. SJE rewrites Vars in the Query tree, PlaceHolderVars,
RestrictInfos and EquivalenceClasses. It does not touch
root->append_rel_list. After that it NULLs the removed rel's slots in
simple_rel_array and simple_rte_array.

add_other_rels_to_query runs later. apply_child_basequals() substitutes the
stale translated_vars into s.c3 IS NOT NULL. eval_const_expressions() then
asks var_is_nonnullable() about a Var whose varno has no RTE.
planner_rt_fetch() returns NULL because simple_rte_array is already built
and that slot is empty. The subsequent rte->rtekind dereference crashes.

The attached patch runs ChangeVarNodesExtended() over append_rel_list in
remove_self_join_rel(), same as for the Query tree.

--
Regards,
Rachitskiy Andrey

Attachment Content-Type Size
0001-Fix-SIGSEGV-in-self-join-elimination-with-LATERAL-UNION-ALL.patch text/x-patch 2.8 KB

In response to

Browse pgsql-bugs by date

  From Date Subject
Previous Message Pierre Forstmann 2026-08-18 13:13:36 Re: BUG #19597: getQuadrant: impossible case is reachable