@ -99,18 +99,13 @@ static void set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
Index rti , RangeTblEntry * rte ) ;
static void generate_orderedappend_paths ( PlannerInfo * root , RelOptInfo * rel ,
List * live_childrels ,
List * all_child_pathkeys ,
List * partitioned_rels ) ;
List * all_child_pathkeys ) ;
static Path * get_cheapest_parameterized_child_path ( PlannerInfo * root ,
RelOptInfo * rel ,
Relids required_outer ) ;
static List * accumulate_partitioned_rels ( List * partitioned_rels ,
List * sub_partitioned_rels ,
bool flatten_partitioned_rels ) ;
static void accumulate_append_subpath ( Path * path ,
List * * subpaths , List * * special_subpaths ,
List * * partitioned_rels ,
bool flatten_partitioned_rels ) ;
List * * subpaths ,
List * * special_subpaths ) ;
static Path * get_singleton_append_subpath ( Path * path ) ;
static void set_dummy_rel_pathlist ( RelOptInfo * rel ) ;
static void set_subquery_pathlist ( PlannerInfo * root , RelOptInfo * rel ,
@ -1299,38 +1294,11 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
List * all_child_pathkeys = NIL ;
List * all_child_outers = NIL ;
ListCell * l ;
List * partitioned_rels = NIL ;
List * partial_partitioned_rels = NIL ;
List * pa_partitioned_rels = NIL ;
double partial_rows = - 1 ;
bool flatten_partitioned_rels ;
/* If appropriate, consider parallel append */
pa_subpaths_valid = enable_parallel_append & & rel - > consider_parallel ;
/* What we do with the partitioned_rels list is different for UNION ALL */
flatten_partitioned_rels = ( rel - > rtekind ! = RTE_SUBQUERY ) ;
/*
* For partitioned tables , we accumulate a list of Relids of each
* partitioned table which has at least one of its subpartitions directly
* present as a subpath in this Append . This is used later for run - time
* partition pruning . We must maintain separate lists for each Append
* Path that we create as some paths that we create here can ' t flatten
* sub - Appends and sub - MergeAppends into the top - level Append . We needn ' t
* bother doing this for join rels as no run - time pruning is done on
* those .
*/
if ( rel - > reloptkind ! = RELOPT_JOINREL & & rel - > part_scheme ! = NULL )
{
partitioned_rels = list_make1 ( bms_make_singleton ( rel - > relid ) ) ;
partial_partitioned_rels = list_make1 ( bms_make_singleton ( rel - > relid ) ) ;
/* skip this one if we're not going to make a Parallel Append path */
if ( pa_subpaths_valid )
pa_partitioned_rels = list_make1 ( bms_make_singleton ( rel - > relid ) ) ;
}
/*
* For every non - dummy child , remember the cheapest path . Also , identify
* all pathkeys ( orderings ) and parameterizations ( required_outer sets )
@ -1353,8 +1321,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
if ( childrel - > pathlist ! = NIL & &
childrel - > cheapest_total_path - > param_info = = NULL )
accumulate_append_subpath ( childrel - > cheapest_total_path ,
& subpaths , NULL , & partitioned_rels ,
flatten_partitioned_rels ) ;
& subpaths , NULL ) ;
else
subpaths_valid = false ;
@ -1363,9 +1330,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
{
cheapest_partial_path = linitial ( childrel - > partial_pathlist ) ;
accumulate_append_subpath ( cheapest_partial_path ,
& partial_subpaths , NULL ,
& partial_partitioned_rels ,
flatten_partitioned_rels ) ;
& partial_subpaths , NULL ) ;
}
else
partial_subpaths_valid = false ;
@ -1394,10 +1359,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
Assert ( cheapest_partial_path ! = NULL ) ;
accumulate_append_subpath ( cheapest_partial_path ,
& pa_partial_subpaths ,
& pa_nonpartial_subpaths ,
& pa_partitioned_rels ,
flatten_partitioned_rels ) ;
& pa_nonpartial_subpaths ) ;
}
else
{
@ -1416,9 +1378,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
*/
accumulate_append_subpath ( nppath ,
& pa_nonpartial_subpaths ,
NULL ,
& pa_partitioned_rels ,
flatten_partitioned_rels ) ;
NULL ) ;
}
}
@ -1495,7 +1455,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
if ( subpaths_valid )
add_path ( rel , ( Path * ) create_append_path ( root , rel , subpaths , NIL ,
NIL , NULL , 0 , false ,
partitioned_rels , - 1 ) ) ;
- 1 ) ) ;
/*
* Consider an append of unordered , unparameterized partial paths . Make
@ -1538,7 +1498,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
appendpath = create_append_path ( root , rel , NIL , partial_subpaths ,
NIL , NULL , parallel_workers ,
enable_parallel_append ,
partial_partitioned_rels , - 1 ) ;
- 1 ) ;
/*
* Make sure any subsequent partial paths use the same row count
@ -1587,7 +1547,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
appendpath = create_append_path ( root , rel , pa_nonpartial_subpaths ,
pa_partial_subpaths ,
NIL , NULL , parallel_workers , true ,
pa_partitioned_rels , pa rtial_rows ) ;
partial_rows ) ;
add_partial_path ( rel , ( Path * ) appendpath ) ;
}
@ -1597,8 +1557,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
*/
if ( subpaths_valid )
generate_orderedappend_paths ( root , rel , live_childrels ,
all_child_pathkeys ,
partitioned_rels ) ;
all_child_pathkeys ) ;
/*
* Build Append paths for each parameterization seen among the child rels .
@ -1617,10 +1576,6 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
{
Relids required_outer = ( Relids ) lfirst ( l ) ;
ListCell * lcr ;
List * part_rels = NIL ;
if ( rel - > reloptkind ! = RELOPT_JOINREL & & rel - > part_scheme ! = NULL )
part_rels = list_make1 ( bms_make_singleton ( rel - > relid ) ) ;
/* Select the child paths for an Append with this parameterization */
subpaths = NIL ;
@ -1646,15 +1601,14 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
subpaths_valid = false ;
break ;
}
accumulate_append_subpath ( subpath , & subpaths , NULL , & part_rels ,
flatten_partitioned_rels ) ;
accumulate_append_subpath ( subpath , & subpaths , NULL ) ;
}
if ( subpaths_valid )
add_path ( rel , ( Path * )
create_append_path ( root , rel , subpaths , NIL ,
NIL , required_outer , 0 , false ,
part_rels , - 1 ) ) ;
- 1 ) ) ;
}
/*
@ -1681,7 +1635,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
appendpath = create_append_path ( root , rel , NIL , list_make1 ( path ) ,
NIL , NULL ,
path - > parallel_workers , true ,
partitioned_rels , parti al_rows ) ;
partial_rows ) ;
add_partial_path ( rel , ( Path * ) appendpath ) ;
}
}
@ -1717,26 +1671,13 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
static void
generate_orderedappend_paths ( PlannerInfo * root , RelOptInfo * rel ,
List * live_childrels ,
List * all_child_pathkeys ,
List * partitioned_rels )
List * all_child_pathkeys )
{
ListCell * lcp ;
List * partition_pathkeys = NIL ;
List * partition_pathkeys_desc = NIL ;
bool partition_pathkeys_partial = true ;
bool partition_pathkeys_desc_partial = true ;
List * startup_partitioned_rels = NIL ;
List * total_partitioned_rels = NIL ;
bool flatten_partitioned_rels ;
/* Set up the method for building the partitioned rels lists */
flatten_partitioned_rels = ( rel - > rtekind ! = RTE_SUBQUERY ) ;
if ( rel - > reloptkind ! = RELOPT_JOINREL & & rel - > part_scheme ! = NULL )
{
startup_partitioned_rels = list_make1 ( bms_make_singleton ( rel - > relid ) ) ;
total_partitioned_rels = list_make1 ( bms_make_singleton ( rel - > relid ) ) ;
}
/*
* Some partitioned table setups may allow us to use an Append node
@ -1878,13 +1819,9 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
* child paths for the MergeAppend .
*/
accumulate_append_subpath ( cheapest_startup ,
& startup_subpaths , NULL ,
& startup_partitioned_rels ,
flatten_partitioned_rels ) ;
& startup_subpaths , NULL ) ;
accumulate_append_subpath ( cheapest_total ,
& total_subpaths , NULL ,
& total_partitioned_rels ,
flatten_partitioned_rels ) ;
& total_subpaths , NULL ) ;
}
}
@ -1900,7 +1837,6 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
NULL ,
0 ,
false ,
startup_partitioned_rels ,
- 1 ) ) ;
if ( startup_neq_total )
add_path ( rel , ( Path * ) create_append_path ( root ,
@ -1911,7 +1847,6 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
NULL ,
0 ,
false ,
total_partitioned_rels ,
- 1 ) ) ;
}
else
@ -1921,15 +1856,13 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
rel ,
startup_subpaths ,
pathkeys ,
NULL ,
startup_partitioned_rels ) ) ;
NULL ) ) ;
if ( startup_neq_total )
add_path ( rel , ( Path * ) create_merge_append_path ( root ,
rel ,
total_subpaths ,
pathkeys ,
NULL ,
total_partitioned_rels ) ) ;
NULL ) ) ;
}
}
}
@ -2008,54 +1941,6 @@ get_cheapest_parameterized_child_path(PlannerInfo *root, RelOptInfo *rel,
return cheapest ;
}
/*
* accumulate_partitioned_rels
* Record ' sub_partitioned_rels ' in the ' partitioned_rels ' list ,
* flattening as appropriate .
*/
static List *
accumulate_partitioned_rels ( List * partitioned_rels ,
List * sub_partitioned_rels ,
bool flatten )
{
if ( flatten )
{
/*
* We ' re only called with flatten = = true when the partitioned_rels
* list has at most 1 element . So we can just add the members from
* sub list ' s first element onto the first element of
* partitioned_rels . Only later in planning when doing UNION ALL
* Append processing will we see flatten = = false . partitioned_rels
* may end up with more than 1 element then , but we never expect to be
* called with flatten = = true again after that , so we needn ' t bother
* doing anything here for anything but the initial element .
*/
if ( partitioned_rels ! = NIL & & sub_partitioned_rels ! = NIL )
{
Relids partrels = ( Relids ) linitial ( partitioned_rels ) ;
Relids subpartrels = ( Relids ) linitial ( sub_partitioned_rels ) ;
/* Ensure the above comment holds true */
Assert ( list_length ( partitioned_rels ) = = 1 ) ;
Assert ( list_length ( sub_partitioned_rels ) = = 1 ) ;
linitial ( partitioned_rels ) = bms_add_members ( partrels , subpartrels ) ;
}
}
else
{
/*
* Handle UNION ALL to partitioned tables . This always occurs after
* we ' ve done the accumulation for sub - partitioned tables , so there ' s
* no need to consider how adding multiple elements to the top level
* list affects the flatten = = true case above .
*/
partitioned_rels = list_concat ( partitioned_rels , sub_partitioned_rels ) ;
}
return partitioned_rels ;
}
/*
* accumulate_append_subpath
* Add a subpath to the list being built for an Append or MergeAppend .
@ -2076,24 +1961,9 @@ accumulate_partitioned_rels(List *partitioned_rels,
* children to subpaths and the rest to special_subpaths . If the latter is
* NULL , we don ' t flatten the path at all ( unless it contains only partial
* paths ) .
*
* When pulling up sub - Appends and sub - Merge Appends , we also gather the
* path ' s list of partitioned tables and store in ' partitioned_rels ' . The
* exact behavior here depends on the value of ' flatten_partitioned_rels ' .
*
* When ' flatten_partitioned_rels ' is true , ' partitioned_rels ' will contain at
* most one element which is a Relids of the partitioned relations which there
* are subpaths for . In this case , we just add the RT indexes for the
* partitioned tables for the subpath we ' re pulling up to the single entry in
* ' partitioned_rels ' . When ' flatten_partitioned_rels ' is false we
* concatenate the path ' s partitioned rel list onto the top - level list . This
* done for UNION ALLs which could have a partitioned table in each union
* branch .
*/
static void
accumulate_append_subpath ( Path * path , List * * subpaths , List * * special_subpaths ,
List * * partitioned_rels ,
bool flatten_partitioned_rels )
accumulate_append_subpath ( Path * path , List * * subpaths , List * * special_subpaths )
{
if ( IsA ( path , AppendPath ) )
{
@ -2102,9 +1972,6 @@ accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths,
if ( ! apath - > path . parallel_aware | | apath - > first_partial_path = = 0 )
{
* subpaths = list_concat ( * subpaths , apath - > subpaths ) ;
* partitioned_rels = accumulate_partitioned_rels ( * partitioned_rels ,
apath - > partitioned_rels ,
flatten_partitioned_rels ) ;
return ;
}
else if ( special_subpaths ! = NULL )
@ -2120,9 +1987,6 @@ accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths,
apath - > first_partial_path ) ;
* special_subpaths = list_concat ( * special_subpaths ,
new_special_subpaths ) ;
* partitioned_rels = accumulate_partitioned_rels ( * partitioned_rels ,
apath - > partitioned_rels ,
flatten_partitioned_rels ) ;
return ;
}
}
@ -2131,9 +1995,6 @@ accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths,
MergeAppendPath * mpath = ( MergeAppendPath * ) path ;
* subpaths = list_concat ( * subpaths , mpath - > subpaths ) ;
* partitioned_rels = accumulate_partitioned_rels ( * partitioned_rels ,
mpath - > partitioned_rels ,
flatten_partitioned_rels ) ;
return ;
}
@ -2195,7 +2056,7 @@ set_dummy_rel_pathlist(RelOptInfo *rel)
/* Set up the dummy path */
add_path ( rel , ( Path * ) create_append_path ( NULL , rel , NIL , NIL ,
NIL , rel - > lateral_relids ,
0 , false , NIL , - 1 ) ) ;
0 , false , - 1 ) ) ;
/*
* We set the cheapest - path fields immediately , just in case they were