mirror of
https://github.com/postgres/postgres.git
synced 2025-07-15 19:21:59 +03:00
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
This commit is contained in:
@ -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;
|
||||
|
||||
@ -1082,6 +1096,21 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
|
||||
count_est);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
|
Reference in New Issue
Block a user