@ -137,6 +137,7 @@ static Size estimate_hashagg_tablesize(Path *path,
static RelOptInfo * create_grouping_paths ( PlannerInfo * root ,
static RelOptInfo * create_grouping_paths ( PlannerInfo * root ,
RelOptInfo * input_rel ,
RelOptInfo * input_rel ,
PathTarget * target ,
PathTarget * target ,
bool target_parallel_safe ,
const AggClauseCosts * agg_costs ,
const AggClauseCosts * agg_costs ,
grouping_sets_data * gd ) ;
grouping_sets_data * gd ) ;
static void consider_groupingsets_paths ( PlannerInfo * root ,
static void consider_groupingsets_paths ( PlannerInfo * root ,
@ -152,6 +153,7 @@ static RelOptInfo *create_window_paths(PlannerInfo *root,
RelOptInfo * input_rel ,
RelOptInfo * input_rel ,
PathTarget * input_target ,
PathTarget * input_target ,
PathTarget * output_target ,
PathTarget * output_target ,
bool output_target_parallel_safe ,
List * tlist ,
List * tlist ,
WindowFuncLists * wflists ,
WindowFuncLists * wflists ,
List * activeWindows ) ;
List * activeWindows ) ;
@ -168,6 +170,7 @@ static RelOptInfo *create_distinct_paths(PlannerInfo *root,
static RelOptInfo * create_ordered_paths ( PlannerInfo * root ,
static RelOptInfo * create_ordered_paths ( PlannerInfo * root ,
RelOptInfo * input_rel ,
RelOptInfo * input_rel ,
PathTarget * target ,
PathTarget * target ,
bool target_parallel_safe ,
double limit_tuples ) ;
double limit_tuples ) ;
static PathTarget * make_group_input_target ( PlannerInfo * root ,
static PathTarget * make_group_input_target ( PlannerInfo * root ,
PathTarget * final_target ) ;
PathTarget * final_target ) ;
@ -1583,6 +1586,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
PathTarget * final_target ;
PathTarget * final_target ;
List * final_targets ;
List * final_targets ;
List * final_targets_contain_srfs ;
List * final_targets_contain_srfs ;
bool final_target_parallel_safe ;
RelOptInfo * current_rel ;
RelOptInfo * current_rel ;
RelOptInfo * final_rel ;
RelOptInfo * final_rel ;
ListCell * lc ;
ListCell * lc ;
@ -1645,6 +1649,10 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
/* Also extract the PathTarget form of the setop result tlist */
/* Also extract the PathTarget form of the setop result tlist */
final_target = current_rel - > cheapest_total_path - > pathtarget ;
final_target = current_rel - > cheapest_total_path - > pathtarget ;
/* And check whether it's parallel safe */
final_target_parallel_safe =
is_parallel_safe ( root , ( Node * ) final_target - > exprs ) ;
/* The setop result tlist couldn't contain any SRFs */
/* The setop result tlist couldn't contain any SRFs */
Assert ( ! parse - > hasTargetSRFs ) ;
Assert ( ! parse - > hasTargetSRFs ) ;
final_targets = final_targets_contain_srfs = NIL ;
final_targets = final_targets_contain_srfs = NIL ;
@ -1676,12 +1684,15 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
PathTarget * sort_input_target ;
PathTarget * sort_input_target ;
List * sort_input_targets ;
List * sort_input_targets ;
List * sort_input_targets_contain_srfs ;
List * sort_input_targets_contain_srfs ;
bool sort_input_target_parallel_safe ;
PathTarget * grouping_target ;
PathTarget * grouping_target ;
List * grouping_targets ;
List * grouping_targets ;
List * grouping_targets_contain_srfs ;
List * grouping_targets_contain_srfs ;
bool grouping_target_parallel_safe ;
PathTarget * scanjoin_target ;
PathTarget * scanjoin_target ;
List * scanjoin_targets ;
List * scanjoin_targets ;
List * scanjoin_targets_contain_srfs ;
List * scanjoin_targets_contain_srfs ;
bool scanjoin_target_parallel_safe ;
bool have_grouping ;
bool have_grouping ;
AggClauseCosts agg_costs ;
AggClauseCosts agg_costs ;
WindowFuncLists * wflists = NULL ;
WindowFuncLists * wflists = NULL ;
@ -1805,6 +1816,8 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
* that were obtained within query_planner ( ) .
* that were obtained within query_planner ( ) .
*/
*/
final_target = create_pathtarget ( root , tlist ) ;
final_target = create_pathtarget ( root , tlist ) ;
final_target_parallel_safe =
is_parallel_safe ( root , ( Node * ) final_target - > exprs ) ;
/*
/*
* If ORDER BY was given , consider whether we should use a post - sort
* If ORDER BY was given , consider whether we should use a post - sort
@ -1812,11 +1825,18 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
* so .
* so .
*/
*/
if ( parse - > sortClause )
if ( parse - > sortClause )
{
sort_input_target = make_sort_input_target ( root ,
sort_input_target = make_sort_input_target ( root ,
final_target ,
final_target ,
& have_postponed_srfs ) ;
& have_postponed_srfs ) ;
sort_input_target_parallel_safe =
is_parallel_safe ( root , ( Node * ) sort_input_target - > exprs ) ;
}
else
else
{
sort_input_target = final_target ;
sort_input_target = final_target ;
sort_input_target_parallel_safe = final_target_parallel_safe ;
}
/*
/*
* If we have window functions to deal with , the output from any
* If we have window functions to deal with , the output from any
@ -1824,11 +1844,18 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
* otherwise , it should be sort_input_target .
* otherwise , it should be sort_input_target .
*/
*/
if ( activeWindows )
if ( activeWindows )
{
grouping_target = make_window_input_target ( root ,
grouping_target = make_window_input_target ( root ,
final_target ,
final_target ,
activeWindows ) ;
activeWindows ) ;
grouping_target_parallel_safe =
is_parallel_safe ( root , ( Node * ) grouping_target - > exprs ) ;
}
else
else
{
grouping_target = sort_input_target ;
grouping_target = sort_input_target ;
grouping_target_parallel_safe = sort_input_target_parallel_safe ;
}
/*
/*
* If we have grouping or aggregation to do , the topmost scan / join
* If we have grouping or aggregation to do , the topmost scan / join
@ -1838,9 +1865,16 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
have_grouping = ( parse - > groupClause | | parse - > groupingSets | |
have_grouping = ( parse - > groupClause | | parse - > groupingSets | |
parse - > hasAggs | | root - > hasHavingQual ) ;
parse - > hasAggs | | root - > hasHavingQual ) ;
if ( have_grouping )
if ( have_grouping )
{
scanjoin_target = make_group_input_target ( root , final_target ) ;
scanjoin_target = make_group_input_target ( root , final_target ) ;
scanjoin_target_parallel_safe =
is_parallel_safe ( root , ( Node * ) grouping_target - > exprs ) ;
}
else
else
{
scanjoin_target = grouping_target ;
scanjoin_target = grouping_target ;
scanjoin_target_parallel_safe = grouping_target_parallel_safe ;
}
/*
/*
* If there are any SRFs in the targetlist , we must separate each of
* If there are any SRFs in the targetlist , we must separate each of
@ -1922,8 +1956,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
* for partial paths . But only parallel - safe expressions can be
* for partial paths . But only parallel - safe expressions can be
* computed by partial paths .
* computed by partial paths .
*/
*/
if ( current_rel - > partial_pathlist & &
if ( current_rel - > partial_pathlist & & scanjoin_target_parallel_safe )
is_parallel_safe ( root , ( Node * ) scanjoin_target - > exprs ) )
{
{
/* Apply the scan/join target to each partial path */
/* Apply the scan/join target to each partial path */
foreach ( lc , current_rel - > partial_pathlist )
foreach ( lc , current_rel - > partial_pathlist )
@ -1984,6 +2017,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
current_rel = create_grouping_paths ( root ,
current_rel = create_grouping_paths ( root ,
current_rel ,
current_rel ,
grouping_target ,
grouping_target ,
grouping_target_parallel_safe ,
& agg_costs ,
& agg_costs ,
gset_data ) ;
gset_data ) ;
/* Fix things up if grouping_target contains SRFs */
/* Fix things up if grouping_target contains SRFs */
@ -2003,6 +2037,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
current_rel ,
current_rel ,
grouping_target ,
grouping_target ,
sort_input_target ,
sort_input_target ,
sort_input_target_parallel_safe ,
tlist ,
tlist ,
wflists ,
wflists ,
activeWindows ) ;
activeWindows ) ;
@ -2036,6 +2071,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
current_rel = create_ordered_paths ( root ,
current_rel = create_ordered_paths ( root ,
current_rel ,
current_rel ,
final_target ,
final_target ,
final_target_parallel_safe ,
have_postponed_srfs ? - 1.0 :
have_postponed_srfs ? - 1.0 :
limit_tuples ) ;
limit_tuples ) ;
/* Fix things up if final_target contains SRFs */
/* Fix things up if final_target contains SRFs */
@ -3623,6 +3659,7 @@ static RelOptInfo *
create_grouping_paths ( PlannerInfo * root ,
create_grouping_paths ( PlannerInfo * root ,
RelOptInfo * input_rel ,
RelOptInfo * input_rel ,
PathTarget * target ,
PathTarget * target ,
bool target_parallel_safe ,
const AggClauseCosts * agg_costs ,
const AggClauseCosts * agg_costs ,
grouping_sets_data * gd )
grouping_sets_data * gd )
{
{
@ -3652,8 +3689,7 @@ create_grouping_paths(PlannerInfo *root,
* target list and HAVING quals are parallel - safe . The partially grouped
* target list and HAVING quals are parallel - safe . The partially grouped
* relation obeys the same rules .
* relation obeys the same rules .
*/
*/
if ( input_rel - > consider_parallel & &
if ( input_rel - > consider_parallel & & target_parallel_safe & &
is_parallel_safe ( root , ( Node * ) target - > exprs ) & &
is_parallel_safe ( root , ( Node * ) parse - > havingQual ) )
is_parallel_safe ( root , ( Node * ) parse - > havingQual ) )
{
{
grouped_rel - > consider_parallel = true ;
grouped_rel - > consider_parallel = true ;
@ -4230,6 +4266,7 @@ create_window_paths(PlannerInfo *root,
RelOptInfo * input_rel ,
RelOptInfo * input_rel ,
PathTarget * input_target ,
PathTarget * input_target ,
PathTarget * output_target ,
PathTarget * output_target ,
bool output_target_parallel_safe ,
List * tlist ,
List * tlist ,
WindowFuncLists * wflists ,
WindowFuncLists * wflists ,
List * activeWindows )
List * activeWindows )
@ -4245,8 +4282,7 @@ create_window_paths(PlannerInfo *root,
* can ' t be parallel - safe , either . Otherwise , we need to examine the
* can ' t be parallel - safe , either . Otherwise , we need to examine the
* target list and active windows for non - parallel - safe constructs .
* target list and active windows for non - parallel - safe constructs .
*/
*/
if ( input_rel - > consider_parallel & &
if ( input_rel - > consider_parallel & & output_target_parallel_safe & &
is_parallel_safe ( root , ( Node * ) output_target - > exprs ) & &
is_parallel_safe ( root , ( Node * ) activeWindows ) )
is_parallel_safe ( root , ( Node * ) activeWindows ) )
window_rel - > consider_parallel = true ;
window_rel - > consider_parallel = true ;
@ -4621,6 +4657,7 @@ static RelOptInfo *
create_ordered_paths ( PlannerInfo * root ,
create_ordered_paths ( PlannerInfo * root ,
RelOptInfo * input_rel ,
RelOptInfo * input_rel ,
PathTarget * target ,
PathTarget * target ,
bool target_parallel_safe ,
double limit_tuples )
double limit_tuples )
{
{
Path * cheapest_input_path = input_rel - > cheapest_total_path ;
Path * cheapest_input_path = input_rel - > cheapest_total_path ;
@ -4635,8 +4672,7 @@ create_ordered_paths(PlannerInfo *root,
* can ' t be parallel - safe , either . Otherwise , it ' s parallel - safe if the
* can ' t be parallel - safe , either . Otherwise , it ' s parallel - safe if the
* target list is parallel - safe .
* target list is parallel - safe .
*/
*/
if ( input_rel - > consider_parallel & &
if ( input_rel - > consider_parallel & & target_parallel_safe )
is_parallel_safe ( root , ( Node * ) target - > exprs ) )
ordered_rel - > consider_parallel = true ;
ordered_rel - > consider_parallel = true ;
/*
/*