Re: Partition pruning can incorrectly exclude a RANGE default partition - Mailing list pgsql-hackers

From Tender Wang
Subject Re: Partition pruning can incorrectly exclude a RANGE default partition
Date
Msg-id CAHewXN=Ho1khxWPJb0K=7Be-1tQZYACTUo7qNicJqgvi32w-xg@mail.gmail.com
Whole thread
Responses Re: [PATCH] Fix ProcKill lock-group vs procLatch recycle race
List pgsql-hackers
Chengpeng Yan <chengpeng_yan@outlook.com> 于2026年7月27日周一 22:53写道:
>
> ```diff
> diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
> index e7c318bbcac..48d16ebb4fb 100644
> --- a/src/backend/partitioning/partprune.c
> +++ b/src/backend/partitioning/partprune.c
> @@ -3031,15 +3031,7 @@ get_matching_range_bounds(PartitionPruneContext *context,
> */
> if (nvalues == 0)
> {
> - /* ignore key space not covered by any partitions */
> - if (partindices[minoff] < 0)
> - minoff++;
> - if (partindices[maxoff] < 0)
> - maxoff--;
> -
> result->scan_default = partition_bound_has_default(boundinfo);
> - Assert(partindices[minoff] >= 0 &&
> - partindices[maxoff] >= 0);
> result->bound_offsets = bms_add_range(NULL, minoff, maxoff);
> return result;
> ```

postgres=# create table s2_2 partition of s2 for values from (20) to (30);
CREATE TABLE
postgres=# explain SELECT count(*) FROM s2
WHERE a IS NOT NULL
  AND a IN (5, 15);
                                 QUERY PLAN
-----------------------------------------------------------------------------
 Aggregate  (cost=84.12..84.14 rows=1 width=8)
   ->  Append  (cost=0.00..84.00 rows=50 width=0)
         ->  Seq Scan on s2_1  (cost=0.00..41.88 rows=25 width=0)
               Filter: ((a IS NOT NULL) AND (a = ANY ('{5,15}'::integer[])))
         ->  Seq Scan on s2_d s2_2  (cost=0.00..41.88 rows=25 width=0)
               Filter: ((a IS NOT NULL) AND (a = ANY ('{5,15}'::integer[])))
(6 rows)

The above query is OK.
If the value in the IN clause is larger than the max datum in
boundinfo or lower than the min datum in boundinfo,
per the if (nvalues == 0) logic, the min and max offset will finally
be excluded. So the default partition is pruned.
It seems that the current logic ignores the reported case.

Before this email, I thought that as long as every prune_step is
correct, then the final result is correct.
But that way, there seem to be more places where we should consider
the result->scan_default flag in get_matching_range_bounds().

Your fix seems simpler.
I added Amit to the CC list; the original author seems to be him. He
should know more than I do.

--
Thanks,
Tender Wang



Attachment

pgsql-hackers by date:

Previous
From: Ayush Tiwari
Date:
Subject: Re: Prove a NOT IN's left-hand expressions non-nullable from quals
Next
From: Chauhan Dhruv
Date:
Subject: Re: Expression index can get an empty generated column name