summaryrefslogtreecommitdiff
path: root/src/pl/plpgsql
diff options
context:
space:
mode:
authorDean Rasheed2024-03-17 13:58:59 +0000
committerDean Rasheed2024-03-17 13:58:59 +0000
commitc649fa24a42ba89bf5460c7110e4fc8eeca65959 (patch)
treede7d51489c6c6fff56fddad66c0ced2aa427d6a5 /src/pl/plpgsql
parent6a004f1be87d34cfe51acf2fe2552d2b08a79273 (diff)
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/pl/plpgsql')
-rw-r--r--src/pl/plpgsql/src/pl_exec.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index ed51694428a..6947575b949 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -4267,9 +4267,9 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
/*
* If we have INTO, then we only need one row back ... but if we have INTO
* STRICT or extra check too_many_rows, ask for two rows, so that we can
- * verify the statement returns only one. INSERT/UPDATE/DELETE are always
- * treated strictly. Without INTO, just run the statement to completion
- * (tcount = 0).
+ * verify the statement returns only one. INSERT/UPDATE/DELETE/MERGE are
+ * always treated strictly. Without INTO, just run the statement to
+ * completion (tcount = 0).
*
* We could just ask for two rows always when using INTO, but there are
* some cases where demanding the extra row costs significant time, eg by
@@ -4307,10 +4307,11 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
case SPI_OK_INSERT:
case SPI_OK_UPDATE:
case SPI_OK_DELETE:
+ case SPI_OK_MERGE:
case SPI_OK_INSERT_RETURNING:
case SPI_OK_UPDATE_RETURNING:
case SPI_OK_DELETE_RETURNING:
- case SPI_OK_MERGE:
+ case SPI_OK_MERGE_RETURNING:
Assert(stmt->mod_stmt);
exec_set_found(estate, (SPI_processed != 0));
break;
@@ -4489,10 +4490,11 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate,
case SPI_OK_INSERT:
case SPI_OK_UPDATE:
case SPI_OK_DELETE:
+ case SPI_OK_MERGE:
case SPI_OK_INSERT_RETURNING:
case SPI_OK_UPDATE_RETURNING:
case SPI_OK_DELETE_RETURNING:
- case SPI_OK_MERGE:
+ case SPI_OK_MERGE_RETURNING:
case SPI_OK_UTILITY:
case SPI_OK_REWRITTEN:
break;