Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit598aa19

Browse files
committed
Still another try at fixing scanjoin_target insertion into parallel plans.
The previous code neglected the fact that the scanjoin_target mightcarry sortgroupref labelings that we need to absorb. Instead, docreate_projection_path() unconditionally, and tweak the path's costestimate after the fact. (I'm now convinced that we ought to refactorthe way we account for sometimes not needing a separate projection step,but right now is not the time for that sort of cleanup.)Problem identified by Amit Kapila, patch by me.
1 parent7e81a18 commit598aa19

File tree

3 files changed

+43
-20
lines changed

3 files changed

+43
-20
lines changed

‎src/backend/optimizer/plan/planner.c

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,36 +1788,39 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
17881788
Path*subpath= (Path*)lfirst(lc);
17891789
Path*newpath;
17901790

1791+
/* Shouldn't have any parameterized paths anymore */
1792+
Assert(subpath->param_info==NULL);
1793+
17911794
/*
17921795
* We can't use apply_projection_to_path() here, because there
17931796
* could already be pointers to these paths, and therefore we
1794-
* cannot modify them in place. Instead, we must use
1795-
* create_projection_path(). The good news is this won't
1796-
* actually insert a Result node into the final plan unless
1797-
* it's needed, but the bad news is that it will charge for
1798-
* the node whether it's needed or not. Therefore, if the
1799-
* target list is already what we need it to be, just leave
1800-
* this partial path alone.
1797+
* dare not modify them in place. Instead, we must use
1798+
* create_projection_path() unconditionally.
18011799
*/
1802-
if (equal(scanjoin_target->exprs,subpath->pathtarget->exprs))
1803-
continue;
1804-
1805-
Assert(subpath->param_info==NULL);
18061800
newpath= (Path*)create_projection_path(root,
18071801
current_rel,
18081802
subpath,
18091803
scanjoin_target);
1810-
if (is_projection_capable_path(subpath))
1804+
1805+
/*
1806+
* Although create_projection_path() inserts a ProjectionPath
1807+
* unconditionally, create_projection_plan() will only insert
1808+
* a Result node if the subpath is not projection-capable, so
1809+
* we should discount the cost of that node if it will not
1810+
* actually get inserted. (This is pretty grotty but we can
1811+
* improve it later if it seems important.)
1812+
*/
1813+
if (equal(scanjoin_target->exprs,subpath->pathtarget->exprs))
18111814
{
1812-
/*
1813-
* Since the target lists differ, a projection path is
1814-
* essential, but it will disappear at plan creation time
1815-
* because the subpath is projection-capable. So avoid
1816-
* charging anything for the disappearing node.
1817-
*/
1815+
/* at most we need a relabeling of the subpath */
18181816
newpath->startup_cost=subpath->startup_cost;
18191817
newpath->total_cost=subpath->total_cost;
18201818
}
1819+
elseif (is_projection_capable_path(subpath))
1820+
{
1821+
/* need to project, but we don't need a Result */
1822+
newpath->total_cost-=cpu_tuple_cost*subpath->rows;
1823+
}
18211824

18221825
lfirst(lc)=newpath;
18231826
}

‎src/test/regress/expected/select_parallel.out

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ create or replace function parallel_restricted(int) returns int as
66
-- Serializable isolation would disable parallel query, so explicitly use an
77
-- arbitrary other level.
88
begin isolation level repeatable read;
9-
--setupparalleltest
9+
--encourage use ofparallelplans
1010
set parallel_setup_cost=0;
1111
set parallel_tuple_cost=0;
12+
set min_parallel_relation_size=0;
1213
set max_parallel_workers_per_gather=4;
1314
explain (costs off)
1415
select count(*) from a_star;
@@ -71,6 +72,21 @@ select length(stringu1) from tenk1 group by length(stringu1);
7172
6
7273
(1 row)
7374

75+
explain (costs off)
76+
select stringu1, count(*) from tenk1 group by stringu1 order by stringu1;
77+
QUERY PLAN
78+
----------------------------------------------------
79+
Sort
80+
Sort Key: stringu1
81+
-> Finalize HashAggregate
82+
Group Key: stringu1
83+
-> Gather
84+
Workers Planned: 4
85+
-> Partial HashAggregate
86+
Group Key: stringu1
87+
-> Parallel Seq Scan on tenk1
88+
(9 rows)
89+
7490
-- test that parallel plan for aggregates is not selected when
7591
-- target list contains parallel restricted clause.
7692
explain (costs off)

‎src/test/regress/sql/select_parallel.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ create or replace function parallel_restricted(int) returns int as
99
-- arbitrary other level.
1010
begin isolation level repeatable read;
1111

12-
--setupparalleltest
12+
--encourage use ofparallelplans
1313
set parallel_setup_cost=0;
1414
set parallel_tuple_cost=0;
15+
set min_parallel_relation_size=0;
1516
set max_parallel_workers_per_gather=4;
1617

1718
explain (costs off)
@@ -29,6 +30,9 @@ explain (costs off)
2930
select length(stringu1)from tenk1group by length(stringu1);
3031
select length(stringu1)from tenk1group by length(stringu1);
3132

33+
explain (costs off)
34+
select stringu1,count(*)from tenk1group by stringu1order by stringu1;
35+
3236
-- test that parallel plan for aggregates is not selected when
3337
-- target list contains parallel restricted clause.
3438
explain (costs off)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp