Skip to content

Commit 45004f5

Browse files
committed
Fix setrefs.c's failure to do expression processing on prune steps.
We should run the expression subtrees of PartitionedRelPruneInfo structs through fix_scan_expr. Failure to do so means that AlternativeSubPlans within those expressions won't be cleaned up properly, resulting in "unrecognized node type" errors since v14. It seems fairly likely that at least some of the other steps done by fix_scan_expr are important here as well, resulting in as-yet- undetected bugs. Therefore, I've chosen to back-patch this to all supported branches including v13, even though the known symptom doesn't manifest in v13. Per bug #18778 from Alexander Lakhin. Discussion: https://postgr.es/m/18778-24cd399df6c806af@postgresql.org
1 parent c9e50ce commit 45004f5

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

src/backend/optimizer/plan/setrefs.c

+12
Original file line numberDiff line numberDiff line change
@@ -1405,6 +1405,12 @@ set_append_references(PlannerInfo *root,
14051405
PartitionedRelPruneInfo *pinfo = lfirst(l2);
14061406

14071407
pinfo->rtindex += rtoffset;
1408+
pinfo->initial_pruning_steps =
1409+
fix_scan_list(root, pinfo->initial_pruning_steps,
1410+
rtoffset);
1411+
pinfo->exec_pruning_steps =
1412+
fix_scan_list(root, pinfo->exec_pruning_steps,
1413+
rtoffset);
14081414
}
14091415
}
14101416
}
@@ -1477,6 +1483,12 @@ set_mergeappend_references(PlannerInfo *root,
14771483
PartitionedRelPruneInfo *pinfo = lfirst(l2);
14781484

14791485
pinfo->rtindex += rtoffset;
1486+
pinfo->initial_pruning_steps =
1487+
fix_scan_list(root, pinfo->initial_pruning_steps,
1488+
rtoffset);
1489+
pinfo->exec_pruning_steps =
1490+
fix_scan_list(root, pinfo->exec_pruning_steps,
1491+
rtoffset);
14801492
}
14811493
}
14821494
}

src/test/regress/expected/partition_prune.out

+32
Original file line numberDiff line numberDiff line change
@@ -1839,6 +1839,38 @@ explain (costs off) select * from rparted_by_int2 where a > 100000000000000;
18391839
(2 rows)
18401840

18411841
drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, iboolpart, boolrangep, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2;
1842+
-- check that AlternativeSubPlan within a pruning expression gets cleaned up
1843+
create table asptab (id int primary key) partition by range (id);
1844+
create table asptab0 partition of asptab for values from (0) to (1);
1845+
create table asptab1 partition of asptab for values from (1) to (2);
1846+
explain (costs off)
1847+
select * from
1848+
(select exists (select 1 from int4_tbl tinner where f1 = touter.f1) as b
1849+
from int4_tbl touter) ss,
1850+
asptab
1851+
where asptab.id > ss.b::int;
1852+
QUERY PLAN
1853+
-------------------------------------------------------------------------------------------
1854+
Nested Loop
1855+
-> Seq Scan on int4_tbl touter
1856+
-> Append
1857+
-> Index Only Scan using asptab0_pkey on asptab0 asptab_1
1858+
Index Cond: (id > ((alternatives: SubPlan 3 or hashed SubPlan 4))::integer)
1859+
SubPlan 3
1860+
-> Seq Scan on int4_tbl tinner_2
1861+
Filter: (f1 = touter.f1)
1862+
SubPlan 4
1863+
-> Seq Scan on int4_tbl tinner_3
1864+
-> Index Only Scan using asptab1_pkey on asptab1 asptab_2
1865+
Index Cond: (id > ((alternatives: SubPlan 3 or hashed SubPlan 4))::integer)
1866+
SubPlan 1
1867+
-> Seq Scan on int4_tbl tinner
1868+
Filter: (f1 = touter.f1)
1869+
SubPlan 2
1870+
-> Seq Scan on int4_tbl tinner_1
1871+
(17 rows)
1872+
1873+
drop table asptab;
18421874
--
18431875
-- Test Partition pruning for HASH partitioning
18441876
--

src/test/regress/sql/partition_prune.sql

+15
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,21 @@ explain (costs off) select * from rparted_by_int2 where a > 100000000000000;
362362

363363
drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, iboolpart, boolrangep, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2;
364364

365+
-- check that AlternativeSubPlan within a pruning expression gets cleaned up
366+
367+
create table asptab (id int primary key) partition by range (id);
368+
create table asptab0 partition of asptab for values from (0) to (1);
369+
create table asptab1 partition of asptab for values from (1) to (2);
370+
371+
explain (costs off)
372+
select * from
373+
(select exists (select 1 from int4_tbl tinner where f1 = touter.f1) as b
374+
from int4_tbl touter) ss,
375+
asptab
376+
where asptab.id > ss.b::int;
377+
378+
drop table asptab;
379+
365380
--
366381
-- Test Partition pruning for HASH partitioning
367382
--

0 commit comments

Comments
 (0)