summaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/plan/createplan.c15
-rw-r--r--src/backend/optimizer/plan/planner.c30
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));