aboutsummaryrefslogtreecommitdiff
path: root/src/backend/nodes/nodeFuncs.c
diff options
context:
space:
mode:
authorDean Rasheed <dean.a.rasheed@gmail.com>2024-03-17 13:58:59 +0000
committerDean Rasheed <dean.a.rasheed@gmail.com>2024-03-17 13:58:59 +0000
commitc649fa24a42ba89bf5460c7110e4fc8eeca65959 (patch)
treede7d51489c6c6fff56fddad66c0ced2aa427d6a5 /src/backend/nodes/nodeFuncs.c
parent6a004f1be87d34cfe51acf2fe2552d2b08a79273 (diff)
downloadpostgresql-c649fa24a42ba89bf5460c7110e4fc8eeca65959.tar.gz
postgresql-c649fa24a42ba89bf5460c7110e4fc8eeca65959.zip
Add RETURNING support to MERGE.
This allows a RETURNING clause to be appended to a MERGE query, to return values based on each row inserted, updated, or deleted. As with plain INSERT, UPDATE, and DELETE commands, the returned values are based on the new contents of the target table for INSERT and UPDATE actions, and on its old contents for DELETE actions. Values from the source relation may also be returned. As with INSERT/UPDATE/DELETE, the output of MERGE ... RETURNING may be used as the source relation for other operations such as WITH queries and COPY commands. Additionally, a special function merge_action() is provided, which returns 'INSERT', 'UPDATE', or 'DELETE', depending on the action executed for each row. The merge_action() function can be used anywhere in the RETURNING list, including in arbitrary expressions and subqueries, but it is an error to use it anywhere outside of a MERGE query's RETURNING list. Dean Rasheed, reviewed by Isaac Morland, Vik Fearing, Alvaro Herrera, Gurjeet Singh, Jian He, Jeff Davis, Merlin Moncure, Peter Eisentraut, and Wolfgang Walther. Discussion: http://postgr.es/m/CAEZATCWePEGQR5LBn-vD6SfeLZafzEm2Qy_L_Oky2=qw2w3Pzg@mail.gmail.com
Diffstat (limited to 'src/backend/nodes/nodeFuncs.c')
-rw-r--r--src/backend/nodes/nodeFuncs.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 6ba8e732569..5b702809aec 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -66,6 +66,9 @@ exprType(const Node *expr)
case T_WindowFunc:
type = ((const WindowFunc *) expr)->wintype;
break;
+ case T_MergeSupportFunc:
+ type = ((const MergeSupportFunc *) expr)->msftype;
+ break;
case T_SubscriptingRef:
type = ((const SubscriptingRef *) expr)->refrestype;
break;
@@ -809,6 +812,9 @@ exprCollation(const Node *expr)
case T_WindowFunc:
coll = ((const WindowFunc *) expr)->wincollid;
break;
+ case T_MergeSupportFunc:
+ coll = ((const MergeSupportFunc *) expr)->msfcollid;
+ break;
case T_SubscriptingRef:
coll = ((const SubscriptingRef *) expr)->refcollid;
break;
@@ -1084,6 +1090,9 @@ exprSetCollation(Node *expr, Oid collation)
case T_WindowFunc:
((WindowFunc *) expr)->wincollid = collation;
break;
+ case T_MergeSupportFunc:
+ ((MergeSupportFunc *) expr)->msfcollid = collation;
+ break;
case T_SubscriptingRef:
((SubscriptingRef *) expr)->refcollid = collation;
break;
@@ -1342,6 +1351,9 @@ exprLocation(const Node *expr)
/* function name should always be the first thing */
loc = ((const WindowFunc *) expr)->location;
break;
+ case T_MergeSupportFunc:
+ loc = ((const MergeSupportFunc *) expr)->location;
+ break;
case T_SubscriptingRef:
/* just use container argument's location */
loc = exprLocation((Node *) ((const SubscriptingRef *) expr)->refexpr);
@@ -2034,6 +2046,7 @@ expression_tree_walker_impl(Node *node,
case T_RangeTblRef:
case T_SortGroupClause:
case T_CTESearchClause:
+ case T_MergeSupportFunc:
/* primitive node types with no expression subnodes */
break;
case T_WithCheckOption:
@@ -2868,6 +2881,7 @@ expression_tree_mutator_impl(Node *node,
case T_RangeTblRef:
case T_SortGroupClause:
case T_CTESearchClause:
+ case T_MergeSupportFunc:
return (Node *) copyObject(node);
case T_WithCheckOption:
{
@@ -3832,6 +3846,7 @@ raw_expression_tree_walker_impl(Node *node,
case T_ParamRef:
case T_A_Const:
case T_A_Star:
+ case T_MergeSupportFunc:
/* primitive node types with no subnodes */
break;
case T_Alias:
@@ -4052,6 +4067,8 @@ raw_expression_tree_walker_impl(Node *node,
return true;
if (WALK(stmt->mergeWhenClauses))
return true;
+ if (WALK(stmt->returningList))
+ return true;
if (WALK(stmt->withClause))
return true;
}