1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-06 07:49:08 +03:00

Implement UPDATE tab SET (col1,col2,...) = (SELECT ...), ...

This SQL-standard feature allows a sub-SELECT yielding multiple columns
(but only one row) to be used to compute the new values of several columns
to be updated.  While the same results can be had with an independent
sub-SELECT per column, such a workaround can require a great deal of
duplicated computation.

The standard actually says that the source for a multi-column assignment
could be any row-valued expression.  The implementation used here is
tightly tied to our existing sub-SELECT support and can't handle other
cases; the Bison grammar would have some issues with them too.  However,
I don't feel too bad about this since other cases can be converted into
sub-SELECTs.  For instance, "SET (a,b,c) = row_valued_function(x)" could
be written "SET (a,b,c) = (SELECT * FROM row_valued_function(x))".
This commit is contained in:
Tom Lane
2014-06-18 13:22:25 -04:00
parent 230ba02d85
commit 8f889b1083
31 changed files with 805 additions and 122 deletions

View File

@@ -384,6 +384,23 @@ typedef struct ResTarget
int location; /* token location, or -1 if unknown */
} ResTarget;
/*
* MultiAssignRef - element of a row source expression for UPDATE
*
* In an UPDATE target list, when we have SET (a,b,c) = row-valued-expression,
* we generate separate ResTarget items for each of a,b,c. Their "val" trees
* are MultiAssignRef nodes numbered 1..n, linking to a common copy of the
* row-valued-expression (which parse analysis will process only once, when
* handling the MultiAssignRef with colno=1).
*/
typedef struct MultiAssignRef
{
NodeTag type;
Node *source; /* the row-valued expression */
int colno; /* column number for this target (1..n) */
int ncolumns; /* number of targets in the construct */
} MultiAssignRef;
/*
* SortBy - for ORDER BY clause
*/