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

From Richard Guo
Subject Re: Teaching planner to short-circuit empty UNION/EXCEPT/INTERSECT inputs
Date
Msg-id CAMbWs484To5tnQ+Qzt=NcwtnK2aHVGiPw-tCXCO8D+XOO7nHaw@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, Nov 4, 2025 at 5:00 PM 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
> LOCATION:  create_plan_recurse, createplan.c:538

I looked into this.  The child relation with relid 3 (the scan on the
partitioned table) is a dummy, so it is skipped in
generate_union_paths().  As a result, the final setop relation ends up
the same as the child relation with relid set to (1, 2).  Then,
generate_union_paths() creates an Append path using this relation's
cheapest path as its subpath.  Somehow, add_path() determines that
this new Append path dominates the original cheapest path, causing the
original cheapest path to be freed.  This leads to the final Append
path referencing a subpath that has already been freed.

- Richard



pgsql-hackers by date:

Previous
From: Chao Li
Date:
Subject: Fix redundant memset after palloc0 in heap_form_minimal_tuple()
Next
From: John Naylor
Date:
Subject: Re: Confine vacuum skip logic to lazy_scan_skip