aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planner.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-08-12 02:52:06 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-08-12 02:52:06 +0000
commit7a3e30e608a25800a1f7fdfaaca4da3f0ac0fb07 (patch)
tree215adabe95d76123f6120fc22e4b51b5a1baf4cd /src/backend/optimizer/plan/planner.c
parent5c9e9c0c42904648af5a03fe90db8050e31d603f (diff)
downloadpostgresql-7a3e30e608a25800a1f7fdfaaca4da3f0ac0fb07.tar.gz
postgresql-7a3e30e608a25800a1f7fdfaaca4da3f0ac0fb07.zip
Add INSERT/UPDATE/DELETE RETURNING, with basic docs and regression tests.
plpgsql support to come later. Along the way, convert execMain's SELECT INTO support into a DestReceiver, in order to eliminate some ugly special cases. Jonah Harris and Tom Lane
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r--src/backend/optimizer/plan/planner.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 0eeaff064ff..f8eb95baf43 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.207 2006/08/05 17:21:52 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.208 2006/08/12 02:52:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -280,6 +280,10 @@ subquery_planner(Query *parse, double tuple_fraction,
preprocess_expression(root, (Node *) parse->targetList,
EXPRKIND_TARGET);
+ parse->returningList = (List *)
+ preprocess_expression(root, (Node *) parse->returningList,
+ EXPRKIND_TARGET);
+
preprocess_qual_conditions(root, (Node *) parse->jointree);
parse->havingQual = preprocess_expression(root, parse->havingQual,
@@ -554,13 +558,13 @@ inheritance_planner(PlannerInfo *root)
Query *parse = root->parse;
int parentRTindex = parse->resultRelation;
List *subplans = NIL;
+ List *resultRelations = NIL;
+ List *returningLists = NIL;
List *rtable = NIL;
List *tlist = NIL;
PlannerInfo subroot;
ListCell *l;
- parse->resultRelations = NIL;
-
foreach(l, root->append_rel_list)
{
AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(l);
@@ -605,10 +609,20 @@ inheritance_planner(PlannerInfo *root)
subplans = lappend(subplans, subplan);
/* Build target-relations list for the executor */
- parse->resultRelations = lappend_int(parse->resultRelations,
- appinfo->child_relid);
+ resultRelations = lappend_int(resultRelations, appinfo->child_relid);
+
+ /* Build list of per-relation RETURNING targetlists */
+ if (parse->returningList)
+ {
+ Assert(list_length(subroot.parse->returningLists) == 1);
+ returningLists = list_concat(returningLists,
+ subroot.parse->returningLists);
+ }
}
+ parse->resultRelations = resultRelations;
+ parse->returningLists = returningLists;
+
/* Mark result as unordered (probably unnecessary) */
root->query_pathkeys = NIL;
@@ -1083,6 +1097,21 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
}
/*
+ * Deal with the RETURNING clause if any. It's convenient to pass the
+ * returningList through setrefs.c now rather than at top level (if
+ * we waited, handling inherited UPDATE/DELETE would be much harder).
+ */
+ if (parse->returningList)
+ {
+ List *rlist;
+
+ rlist = set_returning_clause_references(parse->returningList,
+ result_plan,
+ parse->resultRelation);
+ parse->returningLists = list_make1(rlist);
+ }
+
+ /*
* Return the actual output ordering in query_pathkeys for possible use by
* an outer query level.
*/