diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-08-12 02:52:06 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-08-12 02:52:06 +0000 |
commit | 7a3e30e608a25800a1f7fdfaaca4da3f0ac0fb07 (patch) | |
tree | 215adabe95d76123f6120fc22e4b51b5a1baf4cd /src/backend/optimizer/plan/planner.c | |
parent | 5c9e9c0c42904648af5a03fe90db8050e31d603f (diff) | |
download | postgresql-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.c | 39 |
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. */ |