From cfd71ab1d1971f6ae1d7040b8ffcfbd1f10960cc Mon Sep 17 00:00:00 2001 From: amit Date: Mon, 25 Mar 2019 17:14:02 +0900 Subject: [PATCH v37 4/5] Fix inheritance_planner to avoid useless work When running adjust_appendrel_attrs() on the query, there's no need for its range table to contain child target RTEs, because they don't need to be translated. Trimming those off the range table makes range_table_mutator() finish much quicker, because now it doesn't have to crawl through potentially many RTEs essentially just copying them. Note that copying the child target RTEs is unnecessary as they won't be modified across different planning cycles. The (sub-) list they are contained still must copied with list_copy(), because more entries may be added to individual child query's range table. Furthermore, in a few places where the code iterates over the range table to first locate and later modify subquery RTEs, it's OK to ignore the child target RTEs, because there won't be any subquery RTEs among them and also they won't contain any references to subquery RTEs that are found. --- src/backend/optimizer/plan/planner.c | 61 +++++++++++++++++------------------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index dbb9531d6c..92f506fef9 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -1188,7 +1188,6 @@ inheritance_planner(PlannerInfo *root) Query *parse = root->parse; int top_parentRTindex = parse->resultRelation; Bitmapset *subqueryRTindexes; - Bitmapset *modifiableARIindexes; int nominalRelation = -1; Index rootRelation = 0; List *final_rtable = NIL; @@ -1209,6 +1208,7 @@ inheritance_planner(PlannerInfo *root) Query *parent_parse; Bitmapset *parent_relids = bms_make_singleton(top_parentRTindex); PlannerInfo **parent_roots = NULL; + List *orig_rtable = list_copy(root->parse->rtable); List *orig_append_rel_list = list_copy(root->append_rel_list); Assert(parse->commandType != CMD_INSERT); @@ -1253,10 +1253,12 @@ inheritance_planner(PlannerInfo *root) * management of the rowMarks list. * * To begin with, generate a bitmapset of the relids of the subquery RTEs. + * We use orig_rtable, not parse->rtable, because we wouldn't need to + * consider any newly added RTEs as they all must be RTE_RELATION entries. */ subqueryRTindexes = NULL; rti = 1; - foreach(lc, parse->rtable) + foreach(lc, orig_rtable) { RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc); @@ -1266,32 +1268,6 @@ inheritance_planner(PlannerInfo *root) } /* - * Next, we want to identify which AppendRelInfo items contain references - * to any of the aforesaid subquery RTEs. These items will need to be - * copied and modified to adjust their subquery references; whereas the - * other ones need not be touched. It's worth being tense over this - * because we can usually avoid processing most of the AppendRelInfo - * items, thereby saving O(N^2) space and time when the target is a large - * inheritance tree. We can identify AppendRelInfo items by their - * child_relid, since that should be unique within the list. - */ - modifiableARIindexes = NULL; - if (subqueryRTindexes != NULL) - { - foreach(lc, root->append_rel_list) - { - AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc); - - if (bms_is_member(appinfo->parent_relid, subqueryRTindexes) || - bms_is_member(appinfo->child_relid, subqueryRTindexes) || - bms_overlap(pull_varnos((Node *) appinfo->translated_vars), - subqueryRTindexes)) - modifiableARIindexes = bms_add_member(modifiableARIindexes, - appinfo->child_relid); - } - } - - /* * If the parent RTE is a partitioned table, we should use that as the * nominal target relation, because the RTEs added for partitioned tables * (including the root parent) as child members of the inheritance set do @@ -1327,6 +1303,7 @@ inheritance_planner(PlannerInfo *root) RangeTblEntry *child_rte; RelOptInfo *sub_final_rel; Path *subpath; + List *parent_rtable; /* append_rel_list contains all append rels; ignore others */ if (!bms_is_member(appinfo->parent_relid, parent_relids)) @@ -1362,11 +1339,30 @@ inheritance_planner(PlannerInfo *root) * adjust_appendrel_attrs, which copies the Query and changes * references to the parent RTE to refer to the current child RTE, * then fool around with subquery RTEs. + * + * In order to avoid range_table_mutator() uselessly spending time on + * the child target RTEs that were added to query at the beginning of + * this function, we swap the query's range table with the copy of the + * range table before they were added (orig_table). */ + parent_rtable = parent_parse->rtable; + parent_parse->rtable = orig_rtable; subroot->parse = (Query *) adjust_appendrel_attrs(parent_root, (Node *) parent_parse, 1, &appinfo); + /* + * We do however need to add those child target RTEs to the range + * table so that query_planner can find this child RTE. Other target + * RTEs will not be accessed during this planning cycle, but we can't + * just skip them. + */ + subroot->parse->rtable = + list_concat(subroot->parse->rtable, + list_copy_tail(parent_rtable, + list_length(orig_rtable))); + /* Put it back for the next child's planning. */ + parent_parse->rtable = parent_rtable; /* * If there are securityQuals attached to the parent, move them to the @@ -1451,17 +1447,16 @@ inheritance_planner(PlannerInfo *root) /* * If this isn't the first child Query, generate duplicates of all * subquery RTEs, and adjust Var numbering to reference the - * duplicates. To simplify the loop logic, we scan the original rtable - * not the copy just made by adjust_appendrel_attrs; that should be OK - * since subquery RTEs couldn't contain any references to the target - * rel. + * duplicates. Note that we scan the original rtable before any + * child target relations were added, which is OK, because no other + * RTEs would contain references to subquery rels being modified. */ if (final_rtable != NIL && subqueryRTindexes != NULL) { ListCell *lr; rti = 1; - foreach(lr, parent_parse->rtable) + foreach(lr, orig_rtable) { RangeTblEntry *rte = lfirst_node(RangeTblEntry, lr); -- 2.11.0