Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b971a98

Browse files
committed
Fix placement of initPlans when forcibly materializing a subplan.
If we forcibly place a Material node atop a finished subplan, we need to move any initPlans attached to the subplan up to the Material node, in order to keep SS_finalize_plan() happy. I'd figured this out in commit 7b67a0a for the case of materializing a cursor plan, but out of an abundance of caution, I put the initPlan movement hack at the call site for that case, rather than inside materialize_finished_plan(). That was the wrong thing, because it turns out to also be necessary for the only other caller of materialize_finished_plan(), ie subselect.c. We lacked any test cases that exposed the mistake, but bug#14524 from Wei Congrui shows that it's possible to get an initPlan reference into the top tlist in that case too, and then SS_finalize_plan() complains. Hence, move the hack into materialize_finished_plan(). In HEAD, also relocate some recently-added tests in subselect.sql, which I'd unthinkingly dropped into the middle of a sequence of related tests. Report: https://postgr.es/m/20170202060020.1400.89021@wrigleys.postgresql.org
1 parent 3aab31b commit b971a98

File tree

4 files changed

+39
-15
lines changed

4 files changed

+39
-15
lines changed

src/backend/optimizer/plan/createplan.c

+10
Original file line numberDiff line numberDiff line change
@@ -5629,6 +5629,16 @@ materialize_finished_plan(Plan *subplan)
56295629

56305630
matplan = (Plan *) make_material(subplan);
56315631

5632+
/*
5633+
* XXX horrid kluge: if there are any initPlans attached to the subplan,
5634+
* move them up to the Material node, which is now effectively the top
5635+
* plan node in its query level. This prevents failure in
5636+
* SS_finalize_plan(), which see for comments. We don't bother adjusting
5637+
* the subplan's cost estimate for this.
5638+
*/
5639+
matplan->initPlan = subplan->initPlan;
5640+
subplan->initPlan = NIL;
5641+
56325642
/* Set cost data */
56335643
cost_material(&matpath,
56345644
subplan->startup_cost,

src/backend/optimizer/plan/planner.c

+1-15
Original file line numberDiff line numberDiff line change
@@ -305,21 +305,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
305305
if (cursorOptions & CURSOR_OPT_SCROLL)
306306
{
307307
if (!ExecSupportsBackwardScan(top_plan))
308-
{
309-
Plan *sub_plan = top_plan;
310-
311-
top_plan = materialize_finished_plan(sub_plan);
312-
313-
/*
314-
* XXX horrid kluge: if there are any initPlans attached to the
315-
* formerly-top plan node, move them up to the Material node. This
316-
* prevents failure in SS_finalize_plan, which see for comments.
317-
* We don't bother adjusting the sub_plan's cost estimate for
318-
* this.
319-
*/
320-
top_plan->initPlan = sub_plan->initPlan;
321-
sub_plan->initPlan = NIL;
322-
}
308+
top_plan = materialize_finished_plan(top_plan);
323309
}
324310

325311
/*

src/test/regress/expected/subselect.out

+23
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,29 @@ from int8_tbl group by q1 order by q1;
221221
4567890123456789 | 0.6
222222
(2 rows)
223223

224+
-- check materialization of an initplan reference (bug #14524)
225+
explain (verbose, costs off)
226+
select 1 = all (select (select 1));
227+
QUERY PLAN
228+
-----------------------------------
229+
Result
230+
Output: (SubPlan 2)
231+
SubPlan 2
232+
-> Materialize
233+
Output: ($0)
234+
InitPlan 1 (returns $0)
235+
-> Result
236+
Output: 1
237+
-> Result
238+
Output: $0
239+
(10 rows)
240+
241+
select 1 = all (select (select 1));
242+
?column?
243+
----------
244+
t
245+
(1 row)
246+
224247
--
225248
-- Check EXISTS simplification with LIMIT
226249
--

src/test/regress/sql/subselect.sql

+5
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ SELECT '' AS eight, ss.f1 AS "Correlated Field", ss.f3 AS "Second Field"
9292
select q1, float8(count(*)) / (select count(*) from int8_tbl)
9393
from int8_tbl group by q1 order by q1;
9494

95+
-- check materialization of an initplan reference (bug #14524)
96+
explain (verbose, costs off)
97+
select 1 = all (select (select 1));
98+
select 1 = all (select (select 1));
99+
95100
--
96101
-- Check EXISTS simplification with LIMIT
97102
--

0 commit comments

Comments
 (0)