Add hint about not qualifying UPDATE...SET target with relation name.
authorTom Lane
Sat, 20 Jan 2024 22:54:14 +0000 (17:54 -0500)
committerTom Lane
Sat, 20 Jan 2024 22:54:14 +0000 (17:54 -0500)
Target columns in UPDATE ... SET must not be qualified with the target
table; we disallow this because it'd create ambiguity about which name
is the column name in case of field-qualified names.  However, newbies
have been seen to expect that they could qualify a target name just
like other names.  The error message when they do is confusing:
"column "foo" of relation "foo" does not exist".  To improve matters,
issue a HINT if the invalid name is qualified and matches the
relation's alias.

James Coleman (editorialized a bit by me)

Discussion: https://postgr.es/m/CAAaqYe8S2Qa060UV-YF5GoSd5PkEhLV94x-fEi3=TOtpaXCV+w@mail.gmail.com

src/backend/parser/analyze.c
src/test/regress/expected/insert_conflict.out
src/test/regress/expected/update.out
src/test/regress/sql/insert_conflict.sql
src/test/regress/sql/update.sql

index 06fc8ce98b5afa2556995a17d488302d009a71a5..dbdf6bf8964bc619adf23750d2eb1ef54f2ef978 100644 (file)
@@ -2518,6 +2518,9 @@ transformUpdateTargetList(ParseState *pstate, List *origTlist)
                     errmsg("column \"%s\" of relation \"%s\" does not exist",
                            origTarget->name,
                            RelationGetRelationName(pstate->p_target_relation)),
+                    (origTarget->indirection != NIL &&
+                     strcmp(origTarget->name, pstate->p_target_nsitem->p_names->aliasname) == 0) ?
+                    errhint("SET target columns cannot be qualified with the relation name.") : 0,
                     parser_errposition(pstate, origTarget->location)));
 
        updateTargetListEntry(pstate, tle, origTarget->name,
index 9e9e3bd00cd13fd02d9114c2ceb604bb24bbf72a..563c5eb52ac75489900b9343924b3bb2d5b3216e 100644 (file)
@@ -272,6 +272,12 @@ ERROR:  invalid reference to FROM-clause entry for table "insertconflicttest"
 LINE 1: ...onfruit') on conflict (key) do update set fruit = insertconf...
                                                              ^
 HINT:  Perhaps you meant to reference the table alias "ict".
+-- Check helpful hint when qualifying set column with target table
+insert into insertconflicttest values (3, 'Kiwi') on conflict (key, fruit) do update set insertconflicttest.fruit = 'Mango';
+ERROR:  column "insertconflicttest" of relation "insertconflicttest" does not exist
+LINE 1: ...3, 'Kiwi') on conflict (key, fruit) do update set insertconf...
+                                                             ^
+HINT:  SET target columns cannot be qualified with the relation name.
 drop index key_index;
 --
 -- Composite key tests
index c809f88f5461f41d94a7aee86936bd1d4512c9dd..cb0b033da61e3c8cf6a8e0a1aed9f28080129e3b 100644 (file)
@@ -44,6 +44,12 @@ SELECT * FROM update_test;
  10 | 20 | 
 (2 rows)
 
+-- error, you're not supposed to qualify the target column
+UPDATE update_test t SET t.b = t.b + 10 WHERE t.a = 10;
+ERROR:  column "t" of relation "update_test" does not exist
+LINE 1: UPDATE update_test t SET t.b = t.b + 10 WHERE t.a = 10;
+                                 ^
+HINT:  SET target columns cannot be qualified with the relation name.
 --
 -- Test VALUES in FROM
 --
index 23d5778b821e03acc55fedecc812ab679f7ce773..653f9baf98e39d18a8533382222264c36f828388 100644 (file)
@@ -118,6 +118,9 @@ insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (ke
 insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = ict.fruit; -- ok, alias
 insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = insertconflicttest.fruit; -- error, references aliased away name
 
+-- Check helpful hint when qualifying set column with target table
+insert into insertconflicttest values (3, 'Kiwi') on conflict (key, fruit) do update set insertconflicttest.fruit = 'Mango';
+
 drop index key_index;
 
 --
index 7a7bee77b92602baafb2dd7133e63297182b162b..8b4707eb9c337d1a254c08e0b6906e620a42cfb1 100644 (file)
@@ -31,6 +31,9 @@ UPDATE update_test t SET b = t.b + 10 WHERE t.a = 10;
 
 SELECT * FROM update_test;
 
+-- error, you're not supposed to qualify the target column
+UPDATE update_test t SET t.b = t.b + 10 WHERE t.a = 10;
+
 --
 -- Test VALUES in FROM
 --