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

Started by PG Bug reporting form23 days ago9 messagesbugs
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

needs rebasesuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t253469
psql -h localhost -U postgres

Built from patchset v2 (message #2), August 28, 2026 at 02:22 PM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t253469_2 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t253469_2 && git checkout t253469_2

Patchset v2 (message #2) is on t253469_2

Jump to latest
#1PG Bug reporting form
noreply@postgresql.org

The following bug has been logged on the website:

Bug reference: 19626
Logged by: Suyang Zhong
Email address: syzhong16@gmail.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
```

Here's the log on the server side.

```
2026-08-18 02:50:27.936 UTC [530] STATEMENT: CREATE TABLE t0(c2 INT PRIMARY
KEY, c3 INT);
2026-08-18 02:50:32.126 UTC [1] LOG: client backend (PID 530) was
terminated by signal 11: Segmentation fault
2026-08-18 02:50:32.126 UTC [1] DETAIL: Failed process was running: 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);
2026-08-18 02:50:32.126 UTC [1] LOG: terminating any other active server
processes
2026-08-18 02:50:32.128 UTC [1] LOG: all server processes terminated;
reinitializing
2026-08-18 02:50:32.143 UTC [534] LOG: database system was interrupted;
last known up at 2026-08-18 01:27:03 UTC
```

Reproduced on 20devel and 19beta3.

#2Andrey Rachitskiy
pl0h0yp1@gmail.com
In reply to: PG Bug reporting form (#1)
Re: BUG #19626: Segmentation fault planning self-join IN subquery with LATERAL UNION ALL

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

The following bug has been logged on the website:

Bug reference: 19626
Logged by: Suyang Zhong
Email address: syzhong16@gmail.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

Attachments:

t253469_2
0001-Fix-SIGSEGV-in-self-join-elimination-with-LATERAL-UNION-ALL.patchtext/x-patch; charset=US-ASCII; name=0001-Fix-SIGSEGV-in-self-join-elimination-with-LATERAL-UNION-ALL.patchDownload+28-0
#3Tender Wang
tndrwang@gmail.com
In reply to: Andrey Rachitskiy (#2)
Re: BUG #19626: Segmentation fault planning self-join IN subquery with LATERAL UNION ALL

Andrey Rachitskiy <pl0h0yp1@gmail.com> 于2026年8月18日周二 21:29写道:

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

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);

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.

In apply_child_basequals(), it calls adjust_appendrel_attrs() to
adjust childqual's varno to childRTIndex according to appinfo; the
current info is below:

(gdb) pgprint rinfo->clause <=== parent qual
NullTest [nulltesttype=IS_NOT_NULL argisrow=false location=103]
[arg] Var [varno=2 varattno=1 vartype=23
varreturningtype=VAR_RETURNING_DEFAULT varnosyn=2 varattnosyn=1]
(gdb) pgprint appinfo
AppendRelInfo [parent_relid=2 child_relid=7 parent_reltype=0
child_reltype=0 num_child_cols=1 parent_colnos=0x5fcd7f621d58
parent_reloid=0]
[translated_vars]
Var [varno=1 varattno=2 vartype=23
varreturningtype=VAR_RETURNING_DEFAULT varnosyn=1 varattnosyn=2]

Then the childqual was adjusted to:

(gdb) pgprint childqual
NullTest [nulltesttype=IS_NOT_NULL argisrow=false location=103]
[arg] Var [varno=1 varattno=2 vartype=23
varreturningtype=VAR_RETURNING_DEFAULT varnosyn=1 varattnosyn=2]

"varno=1" is the reference to the first rtable in parse->rtable. But
that rtable was set to NULL after SJE. So the crash occurs in
var_is_nonnullable().

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

The patch looks good to me.

--
Thanks,
Tender Wang

#4Andrey Rachitskiy
pl0h0yp1@gmail.com
In reply to: Tender Wang (#3)
Re: BUG #19626: Segmentation fault planning self-join IN subquery with LATERAL UNION ALL

ср, 19 авг. 2026 г. в 07:28, Tender Wang <tndrwang@gmail.com>:

The patch looks good to me.

Hi Tender,

Thanks for the review.

--
Regards,
Rachitskiy Andrey

#5Nathan Bossart
nathandbossart@gmail.com
In reply to: Andrey Rachitskiy (#4)
Re: BUG #19626: Segmentation fault planning self-join IN subquery with LATERAL UNION ALL

Does this one deserve a mention on the open items wiki [0]https://wiki.postgresql.org/wiki/PostgreSQL_19_Open_Items?

[0]: https://wiki.postgresql.org/wiki/PostgreSQL_19_Open_Items

--
nathan

#6Andrey Rachitskiy
pl0h0yp1@gmail.com
In reply to: Nathan Bossart (#5)
Re: BUG #19626: Segmentation fault planning self-join IN subquery with LATERAL UNION ALL

ср, 26 авг. 2026 г. в 00:23, Nathan Bossart <nathandbossart@gmail.com>:

Does this one deserve a mention on the open items wiki [0]?

[0] https://wiki.postgresql.org/wiki/PostgreSQL_19_Open_Items

Dear Nathan,

I think we can add that.

--
Regards,
Rachitskiy Andrey

#7Tender Wang
tndrwang@gmail.com
In reply to: Andrey Rachitskiy (#6)
Re: BUG #19626: Segmentation fault planning self-join IN subquery with LATERAL UNION ALL

Hi all,

Andrey Rachitskiy <pl0h0yp1@gmail.com> 于2026年8月26日周三 04:02写道:

ср, 26 авг. 2026 г. в 00:23, Nathan Bossart <nathandbossart@gmail.com>:

Does this one deserve a mention on the open items wiki [0]?

[0] https://wiki.postgresql.org/wiki/PostgreSQL_19_Open_Items

Dear Nathan,

I think we can add that.

With 2ebf25e7d70a, this crash is gone. I think we can remove this item
from pg19_open_items.

--
Thanks,
Tender Wang

#8Alexander Korotkov
aekorotkov@gmail.com
In reply to: Tender Wang (#7)
Re: BUG #19626: Segmentation fault planning self-join IN subquery with LATERAL UNION ALL

Hi, Tender,
HI, Andrey,

On Fri, Sep 4, 2026 at 6:11 AM Tender Wang <tndrwang@gmail.com> wrote:

Andrey Rachitskiy <pl0h0yp1@gmail.com> 于2026年8月26日周三 04:02写道:

ср, 26 авг. 2026 г. в 00:23, Nathan Bossart <nathandbossart@gmail.com>:

Does this one deserve a mention on the open items wiki [0]?

[0] https://wiki.postgresql.org/wiki/PostgreSQL_19_Open_Items

Dear Nathan,

I think we can add that.

With 2ebf25e7d70a, this crash is gone. I think we can remove this item
from pg19_open_items.

I was going to look at this. Andrey, could you, please, recheck if
issue is gone and your patch no longer needed?

------
Regards,
Alexander Korotkov
Supabase

#9Andrey Rachitskiy
pl0h0yp1@gmail.com
In reply to: Alexander Korotkov (#8)
Re: BUG #19626: Segmentation fault planning self-join IN subquery with LATERAL UNION ALL

пт, 4 сент. 2026 г. в 11:38, Alexander Korotkov <aekorotkov@gmail.com>:

I was going to look at this. Andrey, could you, please, recheck if
issue is gone and your patch no longer needed?

Hi, Alexander!

I've re-tested this, and the bug is no longer reproducible.
Tom has already fixed it.

Please take a look at this thread: [0]/messages/by-id/CAB8bMivfsjkq_kG3VehogS8-PNMMxuVdprpXKMPxoEyh6WS-Rw@mail.gmail.com — it's still relevant.

[0]: /messages/by-id/CAB8bMivfsjkq_kG3VehogS8-PNMMxuVdprpXKMPxoEyh6WS-Rw@mail.gmail.com
/messages/by-id/CAB8bMivfsjkq_kG3VehogS8-PNMMxuVdprpXKMPxoEyh6WS-Rw@mail.gmail.com