@ -326,46 +326,43 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
int i ;
/*
* Construct a temporary array to map from planner relids to index of the
* partitioned_rel . For convenience , we use 1 - based indexes here , so that
* zero can represent an un - filled array entry .
* Examine each partitioned rel , constructing a temporary array to map
* from planner relids to index of the partitioned rel , and building a
* PartitionedRelPruneInfo for each partitioned rel .
*
* In this phase we discover whether runtime pruning is needed at all ; if
* not , we can avoid doing further work .
*/
relid_subpart_map = palloc0 ( sizeof ( int ) * root - > simple_rel_array_size ) ;
/*
* relid_subpart_map maps relid of a non - leaf partition to the index in
* ' partitioned_rels ' of that rel ( which will also be the index in the
* returned PartitionedRelPruneInfo list of the info for that partition ) .
*/
i = 1 ;
foreach ( lc , partitioned_rels )
{
Index rti = lfirst_int ( lc ) ;
Assert ( rti < root - > simple_rel_array_size ) ;
/* No duplicates please */
Assert ( relid_subpart_map [ rti ] = = 0 ) ;
relid_subpart_map [ rti ] = i + + ;
}
/* We now build a PartitionedRelPruneInfo for each partitioned rel */
foreach ( lc , partitioned_rels )
{
Index rti = lfirst_int ( lc ) ;
RelOptInfo * subpart = find_base_rel ( root , rti ) ;
PartitionedRelPruneInfo * pinfo ;
Bitmapset * present_parts ;
int nparts = subpart - > nparts ;
int partnatts = subpart - > part_scheme - > partnatts ;
int * subplan_map ;
int * subpart_map ;
Oid * relid_map ;
List * partprunequal ;
List * pruning_steps ;
bool contradictory ;
/*
* Fill the mapping array .
*
* relid_subpart_map maps relid of a non - leaf partition to the index
* in ' partitioned_rels ' of that rel ( which will also be the index in
* the returned PartitionedRelPruneInfo list of the info for that
* partition ) . We use 1 - based indexes here , so that zero can
* represent an un - filled array entry .
*/
Assert ( rti < root - > simple_rel_array_size ) ;
/* No duplicates please */
Assert ( relid_subpart_map [ rti ] = = 0 ) ;
relid_subpart_map [ rti ] = i + + ;
/*
* Translate pruning qual , if necessary , for this partition .
*
* The first item in the list is the target partitioned relation .
*/
if ( ! targetpart )
@ -411,6 +408,7 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
targetpart - > relids ) ;
}
/* Convert pruning qual to pruning steps. */
pruning_steps = gen_partprune_steps ( subpart , partprunequal ,
& contradictory ) ;
@ -428,6 +426,47 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
return NIL ;
}
/* Begin constructing the PartitionedRelPruneInfo for this rel */
pinfo = makeNode ( PartitionedRelPruneInfo ) ;
pinfo - > rtindex = rti ;
pinfo - > pruning_steps = pruning_steps ;
/* Remaining fields will be filled in the next loop */
pinfolist = lappend ( pinfolist , pinfo ) ;
/*
* Determine which pruning types should be enabled at this level . This
* also records paramids relevant to pruning steps in ' pinfo ' .
*/
doruntimeprune | = analyze_partkey_exprs ( pinfo , pruning_steps ,
partnatts ) ;
}
if ( ! doruntimeprune )
{
/* No run-time pruning required. */
pfree ( relid_subpart_map ) ;
return NIL ;
}
/*
* Run - time pruning will be required , so initialize other information .
* That includes two maps - - one needed to convert partition indexes of
* leaf partitions to the indexes of their subplans in the subplan list ,
* another needed to convert partition indexes of sub - partitioned
* partitions to the indexes of their PartitionedRelPruneInfo in the
* PartitionedRelPruneInfo list .
*/
foreach ( lc , pinfolist )
{
PartitionedRelPruneInfo * pinfo = lfirst ( lc ) ;
RelOptInfo * subpart = find_base_rel ( root , pinfo - > rtindex ) ;
Bitmapset * present_parts ;
int nparts = subpart - > nparts ;
int * subplan_map ;
int * subpart_map ;
Oid * relid_map ;
/*
* Construct the subplan and subpart maps for this partitioning level .
* Here we convert to zero - based indexes , with - 1 for empty entries .
@ -459,30 +498,16 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
present_parts = bms_add_member ( present_parts , i ) ;
}
pinfo = makeNode ( PartitionedRelPruneInfo ) ;
pinfo - > rtindex = rti ;
pinfo - > pruning_steps = pruning_steps ;
/* Record the maps and other information. */
pinfo - > present_parts = present_parts ;
pinfo - > nparts = nparts ;
pinfo - > subplan_map = subplan_map ;
pinfo - > subpart_map = subpart_map ;
pinfo - > relid_map = relid_map ;
/* Determine which pruning types should be enabled at this level */
doruntimeprune | = analyze_partkey_exprs ( pinfo , pruning_steps ,
partnatts ) ;
pinfolist = lappend ( pinfolist , pinfo ) ;
}
pfree ( relid_subpart_map ) ;
if ( ! doruntimeprune )
{
/* No run-time pruning required. */
return NIL ;
}
* matchedsubplans = subplansfound ;
return pinfolist ;
@ -2907,6 +2932,9 @@ pull_exec_paramids_walker(Node *node, Bitmapset **context)
*
* Returns true if any executor partition pruning should be attempted at this
* level . Also fills fields of * pinfo to record how to process each step .
*
* Note : when this is called , not much of * pinfo is valid ; but that ' s OK
* since we only use it as an output area .
*/
static bool
analyze_partkey_exprs ( PartitionedRelPruneInfo * pinfo , List * steps ,