diff options
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 15 | ||||
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 30 |
2 files changed, 37 insertions, 8 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 2560e9cbc1e..7fed5e97945 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -4702,16 +4702,16 @@ make_result(PlannerInfo *root, * Build a ModifyTable plan node * * Currently, we don't charge anything extra for the actual table modification - * work, nor for the RETURNING expressions if any. It would only be window - * dressing, since these are always top-level nodes and there is no way for - * the costs to change any higher-level planning choices. But we might want - * to make it look better sometime. + * work, nor for the WITH CHECK OPTIONS or RETURNING expressions if any. It + * would only be window dressing, since these are always top-level nodes and + * there is no way for the costs to change any higher-level planning choices. + * But we might want to make it look better sometime. */ ModifyTable * make_modifytable(PlannerInfo *root, CmdType operation, bool canSetTag, - List *resultRelations, - List *subplans, List *returningLists, + List *resultRelations, List *subplans, + List *withCheckOptionLists, List *returningLists, List *rowMarks, int epqParam) { ModifyTable *node = makeNode(ModifyTable); @@ -4723,6 +4723,8 @@ make_modifytable(PlannerInfo *root, int i; Assert(list_length(resultRelations) == list_length(subplans)); + Assert(withCheckOptionLists == NIL || + list_length(resultRelations) == list_length(withCheckOptionLists)); Assert(returningLists == NIL || list_length(resultRelations) == list_length(returningLists)); @@ -4759,6 +4761,7 @@ make_modifytable(PlannerInfo *root, node->resultRelations = resultRelations; node->resultRelIndex = -1; /* will be set correctly in setrefs.c */ node->plans = subplans; + node->withCheckOptionLists = withCheckOptionLists; node->returningLists = returningLists; node->rowMarks = rowMarks; node->epqParam = epqParam; diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index d80c26420fa..01e2fa32a3c 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -294,6 +294,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse, int num_old_subplans = list_length(glob->subplans); PlannerInfo *root; Plan *plan; + List *newWithCheckOptions; List *newHaving; bool hasOuterJoins; ListCell *l; @@ -421,6 +422,18 @@ subquery_planner(PlannerGlobal *glob, Query *parse, preprocess_expression(root, (Node *) parse->targetList, EXPRKIND_TARGET); + newWithCheckOptions = NIL; + foreach(l, parse->withCheckOptions) + { + WithCheckOption *wco = (WithCheckOption *) lfirst(l); + + wco->qual = preprocess_expression(root, wco->qual, + EXPRKIND_QUAL); + if (wco->qual != NULL) + newWithCheckOptions = lappend(newWithCheckOptions, wco); + } + parse->withCheckOptions = newWithCheckOptions; + parse->returningList = (List *) preprocess_expression(root, (Node *) parse->returningList, EXPRKIND_TARGET); @@ -559,12 +572,19 @@ subquery_planner(PlannerGlobal *glob, Query *parse, /* If it's not SELECT, we need a ModifyTable node */ if (parse->commandType != CMD_SELECT) { + List *withCheckOptionLists; List *returningLists; List *rowMarks; /* - * Set up the RETURNING list-of-lists, if needed. + * Set up the WITH CHECK OPTION and RETURNING lists-of-lists, if + * needed. */ + if (parse->withCheckOptions) + withCheckOptionLists = list_make1(parse->withCheckOptions); + else + withCheckOptionLists = NIL; + if (parse->returningList) returningLists = list_make1(parse->returningList); else @@ -585,6 +605,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse, parse->canSetTag, list_make1_int(parse->resultRelation), list_make1(plan), + withCheckOptionLists, returningLists, rowMarks, SS_assign_special_param(root)); @@ -770,6 +791,7 @@ inheritance_planner(PlannerInfo *root) RelOptInfo **save_rel_array = NULL; List *subplans = NIL; List *resultRelations = NIL; + List *withCheckOptionLists = NIL; List *returningLists = NIL; List *rowMarks; ListCell *lc; @@ -930,7 +952,10 @@ inheritance_planner(PlannerInfo *root) /* Build list of target-relation RT indexes */ resultRelations = lappend_int(resultRelations, appinfo->child_relid); - /* Build list of per-relation RETURNING targetlists */ + /* Build lists of per-relation WCO and RETURNING targetlists */ + if (parse->withCheckOptions) + withCheckOptionLists = lappend(withCheckOptionLists, + subroot.parse->withCheckOptions); if (parse->returningList) returningLists = lappend(returningLists, subroot.parse->returningList); @@ -979,6 +1004,7 @@ inheritance_planner(PlannerInfo *root) parse->canSetTag, resultRelations, subplans, + withCheckOptionLists, returningLists, rowMarks, SS_assign_special_param(root)); |