diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2014-06-18 13:22:25 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2014-06-18 13:22:34 -0400 |
commit | 8f889b1083f38f4f5b3bd3512008a3f60e939244 (patch) | |
tree | 68c2e242c88245ea0d3b9329e1e27c78a8e70eaf /src/backend/nodes/equalfuncs.c | |
parent | 230ba02d855de7fac31bfb6af25ebd4ae052640b (diff) | |
download | postgresql-8f889b1083f38f4f5b3bd3512008a3f60e939244.tar.gz |
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))".
Diffstat (limited to 'src/backend/nodes/equalfuncs.c')
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 2407cb73a3..e7b49f680c 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -382,6 +382,7 @@ static bool _equalSubLink(const SubLink *a, const SubLink *b) { COMPARE_SCALAR_FIELD(subLinkType); + COMPARE_SCALAR_FIELD(subLinkId); COMPARE_NODE_FIELD(testexpr); COMPARE_NODE_FIELD(operName); COMPARE_NODE_FIELD(subselect); @@ -2095,6 +2096,16 @@ _equalResTarget(const ResTarget *a, const ResTarget *b) } static bool +_equalMultiAssignRef(const MultiAssignRef *a, const MultiAssignRef *b) +{ + COMPARE_NODE_FIELD(source); + COMPARE_SCALAR_FIELD(colno); + COMPARE_SCALAR_FIELD(ncolumns); + + return true; +} + +static bool _equalTypeName(const TypeName *a, const TypeName *b) { COMPARE_NODE_FIELD(names); @@ -3029,6 +3040,9 @@ equal(const void *a, const void *b) case T_ResTarget: retval = _equalResTarget(a, b); break; + case T_MultiAssignRef: + retval = _equalMultiAssignRef(a, b); + break; case T_TypeCast: retval = _equalTypeCast(a, b); break; |