]> git.ipfire.org Git - thirdparty/postgresql.git/commit
Fix issue with RANGE's DEFAULT partition pruning
authorDavid Rowley <drowley@postgresql.org>
Fri, 31 Jul 2026 03:36:31 +0000 (15:36 +1200)
committerDavid Rowley <drowley@postgresql.org>
Fri, 31 Jul 2026 03:36:31 +0000 (15:36 +1200)
commit709dfd27f14f07ee87fd9707dc765d0338752b5a
tree379ad3ef7a8845f565798b1ac415346d49c074cd
parentd64c805dea27d189904394ece7576762bece278c
Fix issue with RANGE's DEFAULT partition pruning

Partition pruning for RANGE-partitioned tables could mistakenly prune
the DEFAULT partition in some cases when it was not valid to do so,
which could lead to rows missing from query results.

The only known cases where this could happen is when combining pruning
steps from an IS NOT NULL clause with other steps that matched to the
DEFAULT partition.  This could occur due to RANGE partitioned tables
having two distinct internal representations for marking if the DEFAULT
partition should be scanned.  The IS NOT NULL steps would mark the
"scan_default" boolean, but other steps created for different purposes
could mark a bound_offset Bitmapset, which would ultimately translate into
also scanning the default partition.  This could all fail after multiple
steps were combined with a combine intersect operator, as that will
intersect the bound_offset bits and only set scan_default if all pruning
steps have that flag set.  When both input steps to the intersect operator
had different representations of whether to scan the DEFAULT partition,
the resulting intersect step result would contain neither representation.

Here, we fix this by having the IS NOT NULL pruning result mark the
bound_offsets so that it uses both representations to mark that the
DEFAULT partition must be scanned.

Reported-by: Jacob Brazeal <jacob.brazeal@gmail.com>
Diagnosed-by: Jacob Brazeal <jacob.brazeal@gmail.com>
Author: David Rowley <dgrowleyml@gmail.com>
Discussion: https://postgr.es/m/CA+COZaDXrfTaBjLE=Z79MTaH6Xun1V4PeKxLvCNv8mXS8wn0rw@mail.gmail.com
Backpatch-through: 14
src/backend/partitioning/partprune.c
src/test/regress/expected/partition_prune.out
src/test/regress/sql/partition_prune.sql