Re: Teaching planner to short-circuit empty UNION/EXCEPT/INTERSECT inputs - Mailing list pgsql-hackers

From David Rowley
Subject Re: Teaching planner to short-circuit empty UNION/EXCEPT/INTERSECT inputs
Date
Msg-id CAApHDvrHPnPFYHprOBSAVZp8BjNBoFtbPuKZrJt8tvSRR6SV4Q@mail.gmail.com
Whole thread Raw
In response to Re: Teaching planner to short-circuit empty UNION/EXCEPT/INTERSECT inputs  (Alexander Lakhin <exclusion@gmail.com>)
Responses Re: Teaching planner to short-circuit empty UNION/EXCEPT/INTERSECT inputs
List pgsql-hackers
On Tue, 4 Nov 2025 at 21:00, Alexander Lakhin <exclusion@gmail.com> wrote:
> Please look at a new anomaly, introduced with 03d40e4b5:
> CREATE TABLE t(i integer);
> CREATE TABLE pt(i integer) PARTITION BY LIST(i);
>
> SET enable_seqscan = 'off';
> SELECT * FROM t UNION SELECT * FROM t
> UNION ALL
> SELECT * FROM pt;
> produces:
> ERROR:  XX000: unrecognized node type: 0

Thanks for the report.

This seems to be due to the fact that the same UPPERREL_SETOP
RelOptInfo is being used for the UNION and UNION ALL. When doing the
add_path() for the UNION ALL at prepunion.c:1030, the sole child path
of the Append being added is an AggPath for the previous UNION
operation. When we add_path() the AppendPath, the previous AggPath is
already in the pathlist of the result_rel.  add_path() ends up freeing
the old Path due to the new AppendPath being better and the end result
is the Append's subpath is free'd.

The reason we end up with the same result_rel is that we're not
passing all the relids in fetch_upper_rel(root, UPPERREL_SETOP,
relids) due to having removed dummy rels. I guess the fix might be
something like record the relids even when skipping dummy relations.
I'll go and explore that as an option.

David



pgsql-hackers by date:

Previous
From: shveta malik
Date:
Subject: Re: How can end users know the cause of LR slot sync delays?
Next
From: Álvaro Herrera
Date:
Subject: Re: pg_createsubscriber --dry-run logging concerns