summaryrefslogtreecommitdiff
path: root/src/include/nodes/parsenodes.h
diff options
context:
space:
mode:
authorDean Rasheed <dean.a.rasheed@gmail.com>2025-01-16 14:57:35 +0000
committerDean Rasheed <dean.a.rasheed@gmail.com>2025-01-16 14:57:35 +0000
commit80feb727c869cc0b2e12bd1543bafa449be9c8e2 (patch)
tree27fb43ef4b09067e3d725e1b918539d492a8550c /src/include/nodes/parsenodes.h
parent7407b2d48cf37bc8847ae6c47dde2164ef2faa34 (diff)
Add OLD/NEW support to RETURNING in DML queries.
This allows the RETURNING list of INSERT/UPDATE/DELETE/MERGE queries to explicitly return old and new values by using the special aliases "old" and "new", which are automatically added to the query (if not already defined) while parsing its RETURNING list, allowing things like: RETURNING old.colname, new.colname, ... RETURNING old.*, new.* Additionally, a new syntax is supported, allowing the names "old" and "new" to be changed to user-supplied alias names, e.g.: RETURNING WITH (OLD AS o, NEW AS n) o.colname, n.colname, ... This is useful when the names "old" and "new" are already defined, such as inside trigger functions, allowing backwards compatibility to be maintained -- the interpretation of any existing queries that happen to already refer to relations called "old" or "new", or use those as aliases for other relations, is not changed. For an INSERT, old values will generally be NULL, and for a DELETE, new values will generally be NULL, but that may change for an INSERT with an ON CONFLICT ... DO UPDATE clause, or if a query rewrite rule changes the command type. Therefore, we put no restrictions on the use of old and new in any DML queries. Dean Rasheed, reviewed by Jian He and Jeff Davis. Discussion: https://postgr.es/m/CAEZATCWx0J0-v=Qjc6gXzR=KtsdvAE7Ow=D=mu50AgOe+pvisQ@mail.gmail.com
Diffstat (limited to 'src/include/nodes/parsenodes.h')
-rw-r--r--src/include/nodes/parsenodes.h52
1 files changed, 48 insertions, 4 deletions
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index b191eaaecab..ffe155ee20e 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -197,6 +197,15 @@ typedef struct Query
OnConflictExpr *onConflict; /* ON CONFLICT DO [NOTHING | UPDATE] */
+ /*
+ * The following three fields describe the contents of the RETURNING list
+ * for INSERT/UPDATE/DELETE/MERGE. returningOldAlias and returningNewAlias
+ * are the alias names for OLD and NEW, which may be user-supplied values,
+ * the defaults "old" and "new", or NULL (if the default "old"/"new" is
+ * already in use as the alias for some other relation).
+ */
+ char *returningOldAlias pg_node_attr(query_jumble_ignore);
+ char *returningNewAlias pg_node_attr(query_jumble_ignore);
List *returningList; /* return-values list (of TargetEntry) */
List *groupClause; /* a list of SortGroupClause's */
@@ -1727,6 +1736,41 @@ typedef struct MergeWhenClause
} MergeWhenClause;
/*
+ * ReturningOptionKind -
+ * Possible kinds of option in RETURNING WITH(...) list
+ *
+ * Currently, this is used only for specifying OLD/NEW aliases.
+ */
+typedef enum ReturningOptionKind
+{
+ RETURNING_OPTION_OLD, /* specify alias for OLD in RETURNING */
+ RETURNING_OPTION_NEW, /* specify alias for NEW in RETURNING */
+} ReturningOptionKind;
+
+/*
+ * ReturningOption -
+ * An individual option in the RETURNING WITH(...) list
+ */
+typedef struct ReturningOption
+{
+ NodeTag type;
+ ReturningOptionKind option; /* specified option */
+ char *value; /* option's value */
+ ParseLoc location; /* token location, or -1 if unknown */
+} ReturningOption;
+
+/*
+ * ReturningClause -
+ * List of RETURNING expressions, together with any WITH(...) options
+ */
+typedef struct ReturningClause
+{
+ NodeTag type;
+ List *options; /* list of ReturningOption elements */
+ List *exprs; /* list of expressions to return */
+} ReturningClause;
+
+/*
* TriggerTransition -
* representation of transition row or table naming clause
*
@@ -2043,7 +2087,7 @@ typedef struct InsertStmt
List *cols; /* optional: names of the target columns */
Node *selectStmt; /* the source SELECT/VALUES, or NULL */
OnConflictClause *onConflictClause; /* ON CONFLICT clause */
- List *returningList; /* list of expressions to return */
+ ReturningClause *returningClause; /* RETURNING clause */
WithClause *withClause; /* WITH clause */
OverridingKind override; /* OVERRIDING clause */
ParseLoc stmt_location; /* start location, or -1 if unknown */
@@ -2060,7 +2104,7 @@ typedef struct DeleteStmt
RangeVar *relation; /* relation to delete from */
List *usingClause; /* optional using clause for more tables */
Node *whereClause; /* qualifications */
- List *returningList; /* list of expressions to return */
+ ReturningClause *returningClause; /* RETURNING clause */
WithClause *withClause; /* WITH clause */
ParseLoc stmt_location; /* start location, or -1 if unknown */
ParseLoc stmt_len; /* length in bytes; 0 means "rest of string" */
@@ -2077,7 +2121,7 @@ typedef struct UpdateStmt
List *targetList; /* the target list (of ResTarget) */
Node *whereClause; /* qualifications */
List *fromClause; /* optional from clause for more tables */
- List *returningList; /* list of expressions to return */
+ ReturningClause *returningClause; /* RETURNING clause */
WithClause *withClause; /* WITH clause */
ParseLoc stmt_location; /* start location, or -1 if unknown */
ParseLoc stmt_len; /* length in bytes; 0 means "rest of string" */
@@ -2094,7 +2138,7 @@ typedef struct MergeStmt
Node *sourceRelation; /* source relation */
Node *joinCondition; /* join condition between source and target */
List *mergeWhenClauses; /* list of MergeWhenClause(es) */
- List *returningList; /* list of expressions to return */
+ ReturningClause *returningClause; /* RETURNING clause */
WithClause *withClause; /* WITH clause */
ParseLoc stmt_location; /* start location, or -1 if unknown */
ParseLoc stmt_len; /* length in bytes; 0 means "rest of string" */