| From: | Tender Wang <tndrwang(at)gmail(dot)com> |
|---|---|
| To: | Jacob Brazeal <jacob(dot)brazeal(at)gmail(dot)com> |
| Cc: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: Partition pruning can incorrectly exclude a RANGE default partition |
| Date: | 2026-07-27 10:41:19 |
| Message-ID: | CAHewXNn0Wv-NOryRDxCE5UTav7fT7AF_aA+tpJih_Dv89vA5xw@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Tender Wang <tndrwang(at)gmail(dot)com> 于2026年7月27日周一 17:48写道:
>
> Yes, it seems that we should use step_result instead of result in
> perform_pruning_combine_step().
> After replacing it, I get the correct result.
> diff --git a/src/backend/partitioning/partprune.c
> b/src/backend/partitioning/partprune.c
> index e7c318bbcac..8eedb6cce16 100644
> --- a/src/backend/partitioning/partprune.c
> +++ b/src/backend/partitioning/partprune.c
> @@ -3685,9 +3685,9 @@
> perform_pruning_combine_step(PartitionPruneContext *context,
>
> step_result->bound_offsets);
>
> /* Update whether to scan null
> and default partitions. */
> - if (result->scan_null)
> + if (step_result->scan_null)
> result->scan_null =
> step_result->scan_null;
> - if (result->scan_default)
> + if (step_result->scan_default)
> result->scan_default =
> step_result->scan_default;
>
> postgres=# SELECT count(*) FROM s2
> WHERE a IS NOT NULL
> AND a IN (5, 15);
> count
> -------
> 2
> (1 row)
>
> postgres=# SET plan_cache_mode = force_generic_plan;
> SET
> postgres=# PREPARE s2p(int, int) AS
> SELECT count(*) FROM s2
> WHERE a IS NOT NULL
> AND a IN ($1, $2);
> PREPARE
> postgres=# execute s2p(5,15);
> count
> -------
> 2
> (1 row)
>
> See the attached patch. (no test ).
>
The attached patch I wrote in the last email may be wrong. Because
some cases in the regression failed.
After digging deep into this issue, the problem seems to be with
processing (5,15); to be more precise, it is processing 15.
See the debug info:
PartitionPruneStepOp [step_id=0]
[opstrategy=3]
[exprs]
Const [consttype=23 constlen=4 constvalue=5
constisnull=false constbyval=true]
[cmpfns] OidList: [351]
(gdb) n
(gdb) pgprint argsteps
PartitionPruneStepOp [step_id=1]
[opstrategy=3]
[exprs]
Const [consttype=23 constlen=4 constvalue=15
constisnull=false constbyval=true]
[cmpfns] OidList: [351]
The above steps are processing (5,15). When we process 15 in (5,15),
the result is :
PruneStepResult [scan_default=false scan_null=false]
[bound_offsets] Bitmapset [2]
We should scan the default partition, and perform_pruning_base_step()
returned the above result.
But the scan_default flag is false; I think it should be true here.
When we process "a is not null and a in (5,15)", we first process the
result of "(5,15), in perform_pruning_combine_step() : case
PARTPRUNE_COMBINE_INTERSECT.
As we said above, the result->scan_default is false when processing "a
is not null", because firststep is false, so we enter :
....
else
{
/* Record datum indexes common to both steps */
result->bound_offsets =
bms_int_members(result->bound_offsets,
step_result->bound_offsets);
/* Update whether to scan null and default partitions. */
if (result->scan_null)
result->scan_null = step_result->scan_null;
if (result->scan_default)
result->scan_default = step_result->scan_default;
}
....
The result->scan_default is finally false, even though
step_result->scan_default is true.
--
Thanks,
Tender Wang
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Ajin Cherian | 2026-07-27 10:46:22 | Re: [PATCH] Preserve replication origin OIDs in pg_upgrade |
| Previous Message | Sergey | 2026-07-27 10:41:00 | Re: Patch for migration of the pg_commit_ts directory |