ParseExprKind exprKind)
{
List *p_target = NIL;
+ bool expand_star;
ListCell *o_target;
/* Shouldn't have any leftover multiassign items at start */
Assert(pstate->p_multiassign_exprs == NIL);
+ /* Expand "something.*" in SELECT and RETURNING, but not UPDATE */
+ expand_star = (exprKind != EXPR_KIND_UPDATE_SOURCE);
+
foreach(o_target, targetlist)
{
ResTarget *res = (ResTarget *) lfirst(o_target);
* "something", the star could appear as the last field in ColumnRef,
* or as the last indirection item in A_Indirection.
*/
- if (IsA(res->val, ColumnRef))
+ if (expand_star)
{
- ColumnRef *cref = (ColumnRef *) res->val;
-
- if (IsA(llast(cref->fields), A_Star))
+ if (IsA(res->val, ColumnRef))
{
- /* It is something.*, expand into multiple items */
- p_target = list_concat(p_target,
- ExpandColumnRefStar(pstate, cref,
- true));
- continue;
- }
- }
- else if (IsA(res->val, A_Indirection))
- {
- A_Indirection *ind = (A_Indirection *) res->val;
+ ColumnRef *cref = (ColumnRef *) res->val;
- if (IsA(llast(ind->indirection), A_Star))
+ if (IsA(llast(cref->fields), A_Star))
+ {
+ /* It is something.*, expand into multiple items */
+ p_target = list_concat(p_target,
+ ExpandColumnRefStar(pstate,
+ cref,
+ true));
+ continue;
+ }
+ }
+ else if (IsA(res->val, A_Indirection))
{
- /* It is something.*, expand into multiple items */
- p_target = list_concat(p_target,
- ExpandIndirectionStar(pstate, ind,
- true, exprKind));
- continue;
+ A_Indirection *ind = (A_Indirection *) res->val;
+
+ if (IsA(llast(ind->indirection), A_Star))
+ {
+ /* It is something.*, expand into multiple items */
+ p_target = list_concat(p_target,
+ ExpandIndirectionStar(pstate,
+ ind,
+ true,
+ exprKind));
+ continue;
+ }
}
}
/*
- * Not "something.*", so transform as a single expression
+ * Not "something.*", or we want to treat that as a plain whole-row
+ * variable, so transform as a single expression
*/
p_target = lappend(p_target,
transformTargetEntry(pstate,
100 | 20 |
(2 rows)
+-- fail, wrong data type:
+UPDATE update_test SET a = v.* FROM (VALUES(100, 20)) AS v(i, j)
+ WHERE update_test.b = v.j;
+ERROR: column "a" is of type integer but expression is of type record
+LINE 1: UPDATE update_test SET a = v.* FROM (VALUES(100, 20)) AS v(i...
+ ^
+HINT: You will need to rewrite or cast the expression.
--
-- Test multiple-set-clause syntax
--
| |
(4 rows)
+-- these should work, but don't yet:
+UPDATE update_test SET (a,b) = (v.*) FROM (VALUES(21, 100)) AS v(i, j)
+ WHERE update_test.a = v.i;
+ERROR: number of columns does not match number of values
+LINE 1: UPDATE update_test SET (a,b) = (v.*) FROM (VALUES(21, 100)) ...
+ ^
+UPDATE update_test SET (a,b) = ROW(v.*) FROM (VALUES(21, 101)) AS v(i, j)
+ WHERE update_test.a = v.i;
+ERROR: syntax error at or near "ROW"
+LINE 1: UPDATE update_test SET (a,b) = ROW(v.*) FROM (VALUES(21, 101...
+ ^
-- if an alias for the target table is specified, don't allow references
-- to the original table name
UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a = 10;
SELECT * FROM update_test;
+-- fail, wrong data type:
+UPDATE update_test SET a = v.* FROM (VALUES(100, 20)) AS v(i, j)
+ WHERE update_test.b = v.j;
+
--
-- Test multiple-set-clause syntax
--
UPDATE update_test SET (b,a) = (select a+1,b from update_test where a = 1000)
WHERE a = 11;
SELECT * FROM update_test;
+-- these should work, but don't yet:
+UPDATE update_test SET (a,b) = (v.*) FROM (VALUES(21, 100)) AS v(i, j)
+ WHERE update_test.a = v.i;
+UPDATE update_test SET (a,b) = ROW(v.*) FROM (VALUES(21, 101)) AS v(i, j)
+ WHERE update_test.a = v.i;
-- if an alias for the target table is specified, don't allow references
-- to the original table name