Skip to content

Commit cbb9086

Browse files
committed
Fix bug in cbc1279 to handle nested Append correctly
A non-leaf partition with a subplan that is an Append node was omitted from PlannedStmt.unprunableRelids because it was mistakenly included in PlannerGlobal.prunableRelids due to the way PartitionedRelPruneInfo.leafpart_rti_map[] is constructed. This happened when a non-leaf partition used an unflattened Append or MergeAppend. As a result, ExecGetRangeTableRelation() reported an error when called from CreatePartitionPruneState() to process the partition's own PartitionPruneInfo, since it was treated as prunable when it should not have been. Reported-by: Alexander Lakhin <exclusion@gmail.com> (via sqlsmith) Diagnosed-by: Tender Wang <tndrwang@gmail.com> Reviewed-by: Tender Wang <tndrwang@gmail.com> Discussion: https://postgr.es/m/74839af6-aadc-4f60-ae77-ae65f94bf607@gmail.com
1 parent 48796a9 commit cbb9086

File tree

4 files changed

+77
-5
lines changed

4 files changed

+77
-5
lines changed

src/backend/executor/execPartition.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,9 +2589,9 @@ ExecFindMatchingSubPlans(PartitionPruneState *prunestate,
25892589
* find_matching_subplans_recurse
25902590
* Recursive worker function for ExecFindMatchingSubPlans
25912591
*
2592-
* Adds valid (non-prunable) subplan IDs to *validsubplans and the RT indexes
2593-
* of their corresponding leaf partitions to *validsubplan_rtis if
2594-
* it's non-NULL.
2592+
* Adds valid (non-prunable) subplan IDs to *validsubplans. If
2593+
* *validsubplan_rtis is non-NULL, it also adds the RT indexes of their
2594+
* corresponding partitions, but only if they are leaf partitions.
25952595
*/
25962596
static void
25972597
find_matching_subplans_recurse(PartitionPruningData *prunedata,
@@ -2628,7 +2628,12 @@ find_matching_subplans_recurse(PartitionPruningData *prunedata,
26282628
{
26292629
*validsubplans = bms_add_member(*validsubplans,
26302630
pprune->subplan_map[i]);
2631-
if (validsubplan_rtis)
2631+
2632+
/*
2633+
* Only report leaf partitions. Non-leaf partitions may appear
2634+
* here when they use an unflattened Append or MergeAppend.
2635+
*/
2636+
if (validsubplan_rtis && pprune->leafpart_rti_map[i])
26322637
*validsubplan_rtis = bms_add_member(*validsubplan_rtis,
26332638
pprune->leafpart_rti_map[i]);
26342639
}

src/backend/partitioning/partprune.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,14 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
687687
if (subplanidx >= 0)
688688
{
689689
present_parts = bms_add_member(present_parts, i);
690-
leafpart_rti_map[i] = (int) partrel->relid;
690+
691+
/*
692+
* Non-leaf partitions may appear here when they use an
693+
* unflattened Append or MergeAppend. These should not be
694+
* included in prunableRelids.
695+
*/
696+
if (partrel->nparts == -1)
697+
leafpart_rti_map[i] = (int) partrel->relid;
691698

692699
/* Record finding this subplan */
693700
subplansfound = bms_add_member(subplansfound, subplanidx);

src/test/regress/expected/partition_prune.out

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4590,5 +4590,53 @@ table part_abc_view;
45904590
2 | c | t
45914591
(1 row)
45924592

4593+
-- A case with nested MergeAppend with its own PartitionPruneInfo.
4594+
create index on part_abc (a);
4595+
alter table part_abc add d int;
4596+
create table part_abc_3 partition of part_abc for values in (3, 4) partition by range (d);
4597+
create table part_abc_3_1 partition of part_abc_3 for values from (minvalue) to (1);
4598+
create table part_abc_3_2 partition of part_abc_3 for values from (1) to (100);
4599+
create table part_abc_3_3 partition of part_abc_3 for values from (100) to (maxvalue);
4600+
explain (costs off)
4601+
select min(a) over (partition by a order by a) from part_abc where a >= stable_one() + 1 and d <= stable_one()
4602+
union all
4603+
select min(a) over (partition by a order by a) from part_abc where a >= stable_one() + 1 and d >= stable_one();
4604+
QUERY PLAN
4605+
----------------------------------------------------------------------------------------------
4606+
Append
4607+
-> Subquery Scan on "*SELECT* 1_1"
4608+
-> WindowAgg
4609+
-> Append
4610+
Subplans Removed: 1
4611+
-> Index Scan using part_abc_2_a_idx on part_abc_2 part_abc_1
4612+
Index Cond: (a >= (stable_one() + 1))
4613+
Filter: (d <= stable_one())
4614+
-> Merge Append
4615+
Sort Key: part_abc_3.a
4616+
Subplans Removed: 1
4617+
-> Index Scan using part_abc_3_1_a_idx on part_abc_3_1 part_abc_3
4618+
Index Cond: (a >= (stable_one() + 1))
4619+
Filter: (d <= stable_one())
4620+
-> Index Scan using part_abc_3_2_a_idx on part_abc_3_2 part_abc_4
4621+
Index Cond: (a >= (stable_one() + 1))
4622+
Filter: (d <= stable_one())
4623+
-> Subquery Scan on "*SELECT* 2"
4624+
-> WindowAgg
4625+
-> Append
4626+
Subplans Removed: 1
4627+
-> Index Scan using part_abc_2_a_idx on part_abc_2 part_abc_6
4628+
Index Cond: (a >= (stable_one() + 1))
4629+
Filter: (d >= stable_one())
4630+
-> Merge Append
4631+
Sort Key: a
4632+
Subplans Removed: 1
4633+
-> Index Scan using part_abc_3_2_a_idx on part_abc_3_2 part_abc_8
4634+
Index Cond: (a >= (stable_one() + 1))
4635+
Filter: (d >= stable_one())
4636+
-> Index Scan using part_abc_3_3_a_idx on part_abc_3_3 part_abc_9
4637+
Index Cond: (a >= (stable_one() + 1))
4638+
Filter: (d >= stable_one())
4639+
(33 rows)
4640+
45934641
drop view part_abc_view;
45944642
drop table part_abc;

src/test/regress/sql/partition_prune.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,5 +1397,17 @@ using (select stable_one() + 2 as pid) as q join part_abc_1 pt1 on (q.pid = pt1.
13971397
when matched then delete returning pt.a;
13981398
table part_abc_view;
13991399

1400+
-- A case with nested MergeAppend with its own PartitionPruneInfo.
1401+
create index on part_abc (a);
1402+
alter table part_abc add d int;
1403+
create table part_abc_3 partition of part_abc for values in (3, 4) partition by range (d);
1404+
create table part_abc_3_1 partition of part_abc_3 for values from (minvalue) to (1);
1405+
create table part_abc_3_2 partition of part_abc_3 for values from (1) to (100);
1406+
create table part_abc_3_3 partition of part_abc_3 for values from (100) to (maxvalue);
1407+
explain (costs off)
1408+
select min(a) over (partition by a order by a) from part_abc where a >= stable_one() + 1 and d <= stable_one()
1409+
union all
1410+
select min(a) over (partition by a order by a) from part_abc where a >= stable_one() + 1 and d >= stable_one();
1411+
14001412
drop view part_abc_view;
14011413
drop table part_abc;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy