aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2025-01-16 20:40:07 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2025-01-16 20:40:07 -0500
commit724ebebb110493f2000114404188cc3e935153f6 (patch)
tree7190473487a622b4bfe587386fd071a991d9d835
parente5d113057d5fb8e6ecd39521784d48d4966f6a53 (diff)
downloadpostgresql-724ebebb110493f2000114404188cc3e935153f6.tar.gz
postgresql-724ebebb110493f2000114404188cc3e935153f6.zip
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
-rw-r--r--src/backend/optimizer/plan/setrefs.c12
-rw-r--r--src/test/regress/expected/partition_prune.out29
-rw-r--r--src/test/regress/sql/partition_prune.sql15
3 files changed, 56 insertions, 0 deletions
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index e165810e807..4d05d59c5bd 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -1679,6 +1679,12 @@ set_append_references(PlannerInfo *root,
PartitionedRelPruneInfo *pinfo = lfirst(l2);
pinfo->rtindex += rtoffset;
+ pinfo->initial_pruning_steps =
+ fix_scan_list(root, pinfo->initial_pruning_steps,
+ rtoffset, 1);
+ pinfo->exec_pruning_steps =
+ fix_scan_list(root, pinfo->exec_pruning_steps,
+ rtoffset, 1);
}
}
}
@@ -1751,6 +1757,12 @@ set_mergeappend_references(PlannerInfo *root,
PartitionedRelPruneInfo *pinfo = lfirst(l2);
pinfo->rtindex += rtoffset;
+ pinfo->initial_pruning_steps =
+ fix_scan_list(root, pinfo->initial_pruning_steps,
+ rtoffset, 1);
+ pinfo->exec_pruning_steps =
+ fix_scan_list(root, pinfo->exec_pruning_steps,
+ rtoffset, 1);
}
}
}
diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out
index fa1f2f230eb..5635e6bf1a0 100644
--- a/src/test/regress/expected/partition_prune.out
+++ b/src/test/regress/expected/partition_prune.out
@@ -1839,6 +1839,35 @@ explain (costs off) select * from rparted_by_int2 where a > 100000000000000;
(2 rows)
drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, iboolpart, boolrangep, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2;
+-- check that AlternativeSubPlan within a pruning expression gets cleaned up
+create table asptab (id int primary key) partition by range (id);
+create table asptab0 partition of asptab for values from (0) to (1);
+create table asptab1 partition of asptab for values from (1) to (2);
+explain (costs off)
+select * from
+ (select exists (select 1 from int4_tbl tinner where f1 = touter.f1) as b
+ from int4_tbl touter) ss,
+ asptab
+where asptab.id > ss.b::int;
+ QUERY PLAN
+--------------------------------------------------------------------
+ Nested Loop
+ -> Seq Scan on int4_tbl touter
+ -> Append
+ -> Index Only Scan using asptab0_pkey on asptab0 asptab_1
+ Index Cond: (id > ((SubPlan 3))::integer)
+ SubPlan 4
+ -> Seq Scan on int4_tbl tinner_2
+ -> Index Only Scan using asptab1_pkey on asptab1 asptab_2
+ Index Cond: (id > ((SubPlan 3))::integer)
+ SubPlan 3
+ -> Seq Scan on int4_tbl tinner_1
+ Filter: (f1 = touter.f1)
+ SubPlan 2
+ -> Seq Scan on int4_tbl tinner
+(14 rows)
+
+drop table asptab;
--
-- Test Partition pruning for HASH partitioning
--
diff --git a/src/test/regress/sql/partition_prune.sql b/src/test/regress/sql/partition_prune.sql
index 6977efd0fbb..34a8e40509b 100644
--- a/src/test/regress/sql/partition_prune.sql
+++ b/src/test/regress/sql/partition_prune.sql
@@ -362,6 +362,21 @@ explain (costs off) select * from rparted_by_int2 where a > 100000000000000;
drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, iboolpart, boolrangep, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2;
+-- check that AlternativeSubPlan within a pruning expression gets cleaned up
+
+create table asptab (id int primary key) partition by range (id);
+create table asptab0 partition of asptab for values from (0) to (1);
+create table asptab1 partition of asptab for values from (1) to (2);
+
+explain (costs off)
+select * from
+ (select exists (select 1 from int4_tbl tinner where f1 = touter.f1) as b
+ from int4_tbl touter) ss,
+ asptab
+where asptab.id > ss.b::int;
+
+drop table asptab;
+
--
-- Test Partition pruning for HASH partitioning
--