Skip to content

Commit 960df2a

Browse files
committed
Correctly assess parallel-safety of tlists when SRFs are used.
Since commit 69f4b9c, the existing code was no longer assessing the parallel-safety of the real tlist for each upper rel, but rather the first of possibly several tlists created by split_pathtarget_at_srfs(). Repair. Even though this is clearly wrong, it's not clear that it has any user-visible consequences at the moment, so no back-patch for now. If we discover later that it does have user-visible consequences, we might need to back-patch this to v10. Patch by me, per a report from Rajkumar Raghuwanshi. Discussion: http://postgr.es/m/CA+Tgmoaob_Strkg4Dcx=VyxnyXtrmkV=ofj=pX7gH9hSre-g0Q@mail.gmail.com
1 parent 44468f4 commit 960df2a

File tree

1 file changed

+44
-8
lines changed

1 file changed

+44
-8
lines changed

src/backend/optimizer/plan/planner.c

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ static Size estimate_hashagg_tablesize(Path *path,
137137
static RelOptInfo *create_grouping_paths(PlannerInfo *root,
138138
RelOptInfo *input_rel,
139139
PathTarget *target,
140+
bool target_parallel_safe,
140141
const AggClauseCosts *agg_costs,
141142
grouping_sets_data *gd);
142143
static void consider_groupingsets_paths(PlannerInfo *root,
@@ -152,6 +153,7 @@ static RelOptInfo *create_window_paths(PlannerInfo *root,
152153
RelOptInfo *input_rel,
153154
PathTarget *input_target,
154155
PathTarget *output_target,
156+
bool output_target_parallel_safe,
155157
List *tlist,
156158
WindowFuncLists *wflists,
157159
List *activeWindows);
@@ -168,6 +170,7 @@ static RelOptInfo *create_distinct_paths(PlannerInfo *root,
168170
static RelOptInfo *create_ordered_paths(PlannerInfo *root,
169171
RelOptInfo *input_rel,
170172
PathTarget *target,
173+
bool target_parallel_safe,
171174
double limit_tuples);
172175
static PathTarget *make_group_input_target(PlannerInfo *root,
173176
PathTarget *final_target);
@@ -1583,6 +1586,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
15831586
PathTarget *final_target;
15841587
List *final_targets;
15851588
List *final_targets_contain_srfs;
1589+
bool final_target_parallel_safe;
15861590
RelOptInfo *current_rel;
15871591
RelOptInfo *final_rel;
15881592
ListCell *lc;
@@ -1645,6 +1649,10 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
16451649
/* Also extract the PathTarget form of the setop result tlist */
16461650
final_target = current_rel->cheapest_total_path->pathtarget;
16471651

1652+
/* And check whether it's parallel safe */
1653+
final_target_parallel_safe =
1654+
is_parallel_safe(root, (Node *) final_target->exprs);
1655+
16481656
/* The setop result tlist couldn't contain any SRFs */
16491657
Assert(!parse->hasTargetSRFs);
16501658
final_targets = final_targets_contain_srfs = NIL;
@@ -1676,12 +1684,15 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
16761684
PathTarget *sort_input_target;
16771685
List *sort_input_targets;
16781686
List *sort_input_targets_contain_srfs;
1687+
bool sort_input_target_parallel_safe;
16791688
PathTarget *grouping_target;
16801689
List *grouping_targets;
16811690
List *grouping_targets_contain_srfs;
1691+
bool grouping_target_parallel_safe;
16821692
PathTarget *scanjoin_target;
16831693
List *scanjoin_targets;
16841694
List *scanjoin_targets_contain_srfs;
1695+
bool scanjoin_target_parallel_safe;
16851696
bool have_grouping;
16861697
AggClauseCosts agg_costs;
16871698
WindowFuncLists *wflists = NULL;
@@ -1805,30 +1816,46 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
18051816
* that were obtained within query_planner().
18061817
*/
18071818
final_target = create_pathtarget(root, tlist);
1819+
final_target_parallel_safe =
1820+
is_parallel_safe(root, (Node *) final_target->exprs);
18081821

18091822
/*
18101823
* If ORDER BY was given, consider whether we should use a post-sort
18111824
* projection, and compute the adjusted target for preceding steps if
18121825
* so.
18131826
*/
18141827
if (parse->sortClause)
1828+
{
18151829
sort_input_target = make_sort_input_target(root,
18161830
final_target,
18171831
&have_postponed_srfs);
1832+
sort_input_target_parallel_safe =
1833+
is_parallel_safe(root, (Node *) sort_input_target->exprs);
1834+
}
18181835
else
1836+
{
18191837
sort_input_target = final_target;
1838+
sort_input_target_parallel_safe = final_target_parallel_safe;
1839+
}
18201840

18211841
/*
18221842
* If we have window functions to deal with, the output from any
18231843
* grouping step needs to be what the window functions want;
18241844
* otherwise, it should be sort_input_target.
18251845
*/
18261846
if (activeWindows)
1847+
{
18271848
grouping_target = make_window_input_target(root,
18281849
final_target,
18291850
activeWindows);
1851+
grouping_target_parallel_safe =
1852+
is_parallel_safe(root, (Node *) grouping_target->exprs);
1853+
}
18301854
else
1855+
{
18311856
grouping_target = sort_input_target;
1857+
grouping_target_parallel_safe = sort_input_target_parallel_safe;
1858+
}
18321859

18331860
/*
18341861
* If we have grouping or aggregation to do, the topmost scan/join
@@ -1838,9 +1865,16 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
18381865
have_grouping = (parse->groupClause || parse->groupingSets ||
18391866
parse->hasAggs || root->hasHavingQual);
18401867
if (have_grouping)
1868+
{
18411869
scanjoin_target = make_group_input_target(root, final_target);
1870+
scanjoin_target_parallel_safe =
1871+
is_parallel_safe(root, (Node *) grouping_target->exprs);
1872+
}
18421873
else
1874+
{
18431875
scanjoin_target = grouping_target;
1876+
scanjoin_target_parallel_safe = grouping_target_parallel_safe;
1877+
}
18441878

18451879
/*
18461880
* If there are any SRFs in the targetlist, we must separate each of
@@ -1922,8 +1956,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
19221956
* for partial paths. But only parallel-safe expressions can be
19231957
* computed by partial paths.
19241958
*/
1925-
if (current_rel->partial_pathlist &&
1926-
is_parallel_safe(root, (Node *) scanjoin_target->exprs))
1959+
if (current_rel->partial_pathlist && scanjoin_target_parallel_safe)
19271960
{
19281961
/* Apply the scan/join target to each partial path */
19291962
foreach(lc, current_rel->partial_pathlist)
@@ -1984,6 +2017,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
19842017
current_rel = create_grouping_paths(root,
19852018
current_rel,
19862019
grouping_target,
2020+
grouping_target_parallel_safe,
19872021
&agg_costs,
19882022
gset_data);
19892023
/* Fix things up if grouping_target contains SRFs */
@@ -2003,6 +2037,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
20032037
current_rel,
20042038
grouping_target,
20052039
sort_input_target,
2040+
sort_input_target_parallel_safe,
20062041
tlist,
20072042
wflists,
20082043
activeWindows);
@@ -2036,6 +2071,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
20362071
current_rel = create_ordered_paths(root,
20372072
current_rel,
20382073
final_target,
2074+
final_target_parallel_safe,
20392075
have_postponed_srfs ? -1.0 :
20402076
limit_tuples);
20412077
/* Fix things up if final_target contains SRFs */
@@ -3623,6 +3659,7 @@ static RelOptInfo *
36233659
create_grouping_paths(PlannerInfo *root,
36243660
RelOptInfo *input_rel,
36253661
PathTarget *target,
3662+
bool target_parallel_safe,
36263663
const AggClauseCosts *agg_costs,
36273664
grouping_sets_data *gd)
36283665
{
@@ -3652,8 +3689,7 @@ create_grouping_paths(PlannerInfo *root,
36523689
* target list and HAVING quals are parallel-safe. The partially grouped
36533690
* relation obeys the same rules.
36543691
*/
3655-
if (input_rel->consider_parallel &&
3656-
is_parallel_safe(root, (Node *) target->exprs) &&
3692+
if (input_rel->consider_parallel && target_parallel_safe &&
36573693
is_parallel_safe(root, (Node *) parse->havingQual))
36583694
{
36593695
grouped_rel->consider_parallel = true;
@@ -4230,6 +4266,7 @@ create_window_paths(PlannerInfo *root,
42304266
RelOptInfo *input_rel,
42314267
PathTarget *input_target,
42324268
PathTarget *output_target,
4269+
bool output_target_parallel_safe,
42334270
List *tlist,
42344271
WindowFuncLists *wflists,
42354272
List *activeWindows)
@@ -4245,8 +4282,7 @@ create_window_paths(PlannerInfo *root,
42454282
* can't be parallel-safe, either. Otherwise, we need to examine the
42464283
* target list and active windows for non-parallel-safe constructs.
42474284
*/
4248-
if (input_rel->consider_parallel &&
4249-
is_parallel_safe(root, (Node *) output_target->exprs) &&
4285+
if (input_rel->consider_parallel && output_target_parallel_safe &&
42504286
is_parallel_safe(root, (Node *) activeWindows))
42514287
window_rel->consider_parallel = true;
42524288

@@ -4621,6 +4657,7 @@ static RelOptInfo *
46214657
create_ordered_paths(PlannerInfo *root,
46224658
RelOptInfo *input_rel,
46234659
PathTarget *target,
4660+
bool target_parallel_safe,
46244661
double limit_tuples)
46254662
{
46264663
Path *cheapest_input_path = input_rel->cheapest_total_path;
@@ -4635,8 +4672,7 @@ create_ordered_paths(PlannerInfo *root,
46354672
* can't be parallel-safe, either. Otherwise, it's parallel-safe if the
46364673
* target list is parallel-safe.
46374674
*/
4638-
if (input_rel->consider_parallel &&
4639-
is_parallel_safe(root, (Node *) target->exprs))
4675+
if (input_rel->consider_parallel && target_parallel_safe)
46404676
ordered_rel->consider_parallel = true;
46414677

46424678
/*

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