| 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 |
| From | Date | Subject | |
|---|---|---|---|
| Previous Message | Pierre Forstmann | 2026-08-18 13:13:36 | Re: BUG #19597: getQuadrant: impossible case is reachable |