Skip to content

Commit 734308a

Browse files
committed
Rearrange make_partitionedrel_pruneinfo to avoid work when we can't prune.
Postpone most of the effort of constructing PartitionedRelPruneInfos until after we have found out whether run-time pruning is needed at all. This costs very little duplicated effort (basically just an extra find_base_rel() call per partition) and saves quite a bit when we can't do run-time pruning. Also, merge the first loop (for building relid_subpart_map) into the second loop, since we don't need the map to be valid during that loop. Amit Langote Discussion: https://postgr.es/m/9d7c5112-cb99-6a47-d3be-cf1ee6862a1d@lab.ntt.co.jp
1 parent 09963ce commit 734308a

File tree

1 file changed

+68
-40
lines changed

1 file changed

+68
-40
lines changed

src/backend/partitioning/partprune.c

Lines changed: 68 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
29112939
static bool
29122940
analyze_partkey_exprs(PartitionedRelPruneInfo *pinfo, List *steps,

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