From 7828f62949c4d57c176059dda910ccf1f7deaf96 Mon Sep 17 00:00:00 2001 From: amit Date: Fri, 22 Mar 2019 15:09:45 +0900 Subject: [PATCH v34 8/9] Rearrange the code in make_partitionedrel_pruneinfo for efficiency The current code will loop over all partitions to create maps that will be put into the PartitionedRelPruneInfo of a given partitioned table, *before* checking if run-time pruning will be needed at all. This commit rearranges the code such that maps are created *after* we've determined that run-time will be needed. --- src/backend/partitioning/partprune.c | 84 ++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c index e766555a9f..6004ae37f3 100644 --- a/src/backend/partitioning/partprune.c +++ b/src/backend/partitioning/partprune.c @@ -333,39 +333,24 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, */ 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 */ + i = 1; 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; + /* Map the table's RT index to its position in partitioned_rels. */ + Assert(rti < root->simple_rel_array_size); + /* No duplicates please */ + Assert(relid_subpart_map[rti] == 0); + relid_subpart_map[rti] = i++; + /* * The first item in the list is the target partitioned relation. */ @@ -429,6 +414,45 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, return NIL; } + /* Other information will be set in the following loop. */ + pinfo = makeNode(PartitionedRelPruneInfo); + pinfo->rtindex = rti; + pinfo->pruning_steps = pruning_steps; + + /* + * 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); + + pinfolist = lappend(pinfolist, pinfo); + } + + if (!doruntimeprune) + { + /* No run-time pruning required. */ + 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 +483,16 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, subplansfound = bms_add_member(subplansfound, subplanidx); } - 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; -- 2.11.0