@@ -326,46 +326,43 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
326326 int i ;
327327
328328 /*
329- * Construct a temporary array to map from planner relids to index of the
330- * partitioned_rel. For convenience, we use 1-based indexes here, so that
331- * zero can represent an un-filled array entry.
329+ * Examine each partitioned rel, constructing a temporary array to map
330+ * from planner relids to index of the partitioned rel, and building a
331+ * PartitionedRelPruneInfo for each partitioned rel.
332+ *
333+ * In this phase we discover whether runtime pruning is needed at all; if
334+ * not, we can avoid doing further work.
332335 */
333336 relid_subpart_map = palloc0 (sizeof (int ) * root -> simple_rel_array_size );
334337
335- /*
336- * relid_subpart_map maps relid of a non-leaf partition to the index in
337- * 'partitioned_rels' of that rel (which will also be the index in the
338- * returned PartitionedRelPruneInfo list of the info for that partition).
339- */
340338 i = 1 ;
341339 foreach (lc , partitioned_rels )
342- {
343- Index rti = lfirst_int (lc );
344-
345- Assert (rti < root -> simple_rel_array_size );
346- /* No duplicates please */
347- Assert (relid_subpart_map [rti ] == 0 );
348-
349- relid_subpart_map [rti ] = i ++ ;
350- }
351-
352- /* We now build a PartitionedRelPruneInfo for each partitioned rel */
353- foreach (lc , partitioned_rels )
354340 {
355341 Index rti = lfirst_int (lc );
356342 RelOptInfo * subpart = find_base_rel (root , rti );
357343 PartitionedRelPruneInfo * pinfo ;
358- Bitmapset * present_parts ;
359- int nparts = subpart -> nparts ;
360344 int partnatts = subpart -> part_scheme -> partnatts ;
361- int * subplan_map ;
362- int * subpart_map ;
363- Oid * relid_map ;
364345 List * partprunequal ;
365346 List * pruning_steps ;
366347 bool contradictory ;
367348
368349 /*
350+ * Fill the mapping array.
351+ *
352+ * relid_subpart_map maps relid of a non-leaf partition to the index
353+ * in 'partitioned_rels' of that rel (which will also be the index in
354+ * the returned PartitionedRelPruneInfo list of the info for that
355+ * partition). We use 1-based indexes here, so that zero can
356+ * represent an un-filled array entry.
357+ */
358+ Assert (rti < root -> simple_rel_array_size );
359+ /* No duplicates please */
360+ Assert (relid_subpart_map [rti ] == 0 );
361+ relid_subpart_map [rti ] = i ++ ;
362+
363+ /*
364+ * Translate pruning qual, if necessary, for this partition.
365+ *
369366 * The first item in the list is the target partitioned relation.
370367 */
371368 if (!targetpart )
@@ -411,6 +408,7 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
411408 targetpart -> relids );
412409 }
413410
411+ /* Convert pruning qual to pruning steps. */
414412 pruning_steps = gen_partprune_steps (subpart , partprunequal ,
415413 & contradictory );
416414
@@ -428,6 +426,47 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
428426 return NIL ;
429427 }
430428
429+ /* Begin constructing the PartitionedRelPruneInfo for this rel */
430+ pinfo = makeNode (PartitionedRelPruneInfo );
431+ pinfo -> rtindex = rti ;
432+ pinfo -> pruning_steps = pruning_steps ;
433+ /* Remaining fields will be filled in the next loop */
434+
435+ pinfolist = lappend (pinfolist , pinfo );
436+
437+ /*
438+ * Determine which pruning types should be enabled at this level. This
439+ * also records paramids relevant to pruning steps in 'pinfo'.
440+ */
441+ doruntimeprune |= analyze_partkey_exprs (pinfo , pruning_steps ,
442+ partnatts );
443+ }
444+
445+ if (!doruntimeprune )
446+ {
447+ /* No run-time pruning required. */
448+ pfree (relid_subpart_map );
449+ return NIL ;
450+ }
451+
452+ /*
453+ * Run-time pruning will be required, so initialize other information.
454+ * That includes two maps -- one needed to convert partition indexes of
455+ * leaf partitions to the indexes of their subplans in the subplan list,
456+ * another needed to convert partition indexes of sub-partitioned
457+ * partitions to the indexes of their PartitionedRelPruneInfo in the
458+ * PartitionedRelPruneInfo list.
459+ */
460+ foreach (lc , pinfolist )
461+ {
462+ PartitionedRelPruneInfo * pinfo = lfirst (lc );
463+ RelOptInfo * subpart = find_base_rel (root , pinfo -> rtindex );
464+ Bitmapset * present_parts ;
465+ int nparts = subpart -> nparts ;
466+ int * subplan_map ;
467+ int * subpart_map ;
468+ Oid * relid_map ;
469+
431470 /*
432471 * Construct the subplan and subpart maps for this partitioning level.
433472 * Here we convert to zero-based indexes, with -1 for empty entries.
@@ -459,30 +498,16 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
459498 present_parts = bms_add_member (present_parts , i );
460499 }
461500
462- pinfo = makeNode (PartitionedRelPruneInfo );
463- pinfo -> rtindex = rti ;
464- pinfo -> pruning_steps = pruning_steps ;
501+ /* Record the maps and other information. */
465502 pinfo -> present_parts = present_parts ;
466503 pinfo -> nparts = nparts ;
467504 pinfo -> subplan_map = subplan_map ;
468505 pinfo -> subpart_map = subpart_map ;
469506 pinfo -> relid_map = relid_map ;
470-
471- /* Determine which pruning types should be enabled at this level */
472- doruntimeprune |= analyze_partkey_exprs (pinfo , pruning_steps ,
473- partnatts );
474-
475- pinfolist = lappend (pinfolist , pinfo );
476507 }
477508
478509 pfree (relid_subpart_map );
479510
480- if (!doruntimeprune )
481- {
482- /* No run-time pruning required. */
483- return NIL ;
484- }
485-
486511 * matchedsubplans = subplansfound ;
487512
488513 return pinfolist ;
@@ -2907,6 +2932,9 @@ pull_exec_paramids_walker(Node *node, Bitmapset **context)
29072932 *
29082933 * Returns true if any executor partition pruning should be attempted at this
29092934 * level. Also fills fields of *pinfo to record how to process each step.
2935+ *
2936+ * Note: when this is called, not much of *pinfo is valid; but that's OK
2937+ * since we only use it as an output area.
29102938 */
29112939static bool
29122940analyze_partkey_exprs (PartitionedRelPruneInfo * pinfo , List * steps ,
0 commit comments