diff options
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 7f1f962f60a..bbf355dbf2c 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -1570,34 +1570,58 @@ inheritance_planner(PlannerInfo *root) * to get control here. */ - /* - * If we managed to exclude every child rel, return a dummy plan; it - * doesn't even need a ModifyTable node. - */ if (subpaths == NIL) { - set_dummy_rel_pathlist(final_rel); - return; - } + /* + * We managed to exclude every child rel, so generate a dummy path + * representing the empty set. Although it's clear that no data will + * be updated or deleted, we will still need to have a ModifyTable + * node so that any statement triggers are executed. (This could be + * cleaner if we fixed nodeModifyTable.c to support zero child nodes, + * but that probably wouldn't be a net win.) + */ + List *tlist; + Path *dummy_path; - /* - * Put back the final adjusted rtable into the master copy of the Query. - * (We mustn't do this if we found no non-excluded children.) - */ - parse->rtable = final_rtable; - root->simple_rel_array_size = save_rel_array_size; - root->simple_rel_array = save_rel_array; - root->append_rel_array = save_append_rel_array; + /* tlist processing never got done, either */ + tlist = root->processed_tlist = preprocess_targetlist(root); + final_rel->reltarget = create_pathtarget(root, tlist); - /* Must reconstruct master's simple_rte_array, too */ - root->simple_rte_array = (RangeTblEntry **) - palloc0((list_length(final_rtable) + 1) * sizeof(RangeTblEntry *)); - rti = 1; - foreach(lc, final_rtable) + /* Make a dummy path, cf set_dummy_rel_pathlist() */ + dummy_path = (Path *) create_append_path(NULL, final_rel, NIL, NIL, + NULL, 0, false, NIL, -1); + + /* These lists must be nonempty to make a valid ModifyTable node */ + subpaths = list_make1(dummy_path); + subroots = list_make1(root); + resultRelations = list_make1_int(parse->resultRelation); + if (parse->withCheckOptions) + withCheckOptionLists = list_make1(parse->withCheckOptions); + if (parse->returningList) + returningLists = list_make1(parse->returningList); + } + else { - RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc); + /* + * Put back the final adjusted rtable into the master copy of the + * Query. (We mustn't do this if we found no non-excluded children, + * since we never saved an adjusted rtable at all.) + */ + parse->rtable = final_rtable; + root->simple_rel_array_size = save_rel_array_size; + root->simple_rel_array = save_rel_array; + root->append_rel_array = save_append_rel_array; + + /* Must reconstruct master's simple_rte_array, too */ + root->simple_rte_array = (RangeTblEntry **) + palloc0((list_length(final_rtable) + 1) * sizeof(RangeTblEntry *)); + rti = 1; + foreach(lc, final_rtable) + { + RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc); - root->simple_rte_array[rti++] = rte; + root->simple_rte_array[rti++] = rte; + } } /* |