Thread: Why the "UPDATE tab SET tab.col" is invalid?

Why the "UPDATE tab SET tab.col" is invalid?

From
"postgres_sure"
Date:
Hi,
 
I found "Do not include the table's name in the specification of a target column
                 — for example, UPDATE tab SET tab.col = 1 is invalid." in the documentation.
 
Some people usually like to update table by alias. They want to add this feature.
So I get the source in the gram.y, and I found that they just take the alias as the name of column.
So I think we could analyze whether the "indirection" is alias or other.
 
The attachment is my patch to support - update table by alias:
 
CREATE TABLE update_test1 (
    a   INT, b   INT, c   TEXT
);
INSERT INTO update_test1 VALUES (1, 10, 'aa'),(2, 11, 'bb'),(3, 12, 'cc'),(4, 13, 'dd');
SELECT * FROM update_test1;
 a | b  | c 
---+----+----
 1 | 10 | aa
 2 | 11 | bb
 3 | 12 | cc
 4 | 13 | dd
(4 rows)
 
UPDATE update_test1 SET tb1.a = 4 WHERE a = 1;
ERROR:  column "a" of relation "tb1" does not exist
LINE 1: UPDATE update_test1 SET tb1.a = 4 WHERE a = 1;
                                ^
UPDATE update_test1 tb1 SET tb1.f = 4 WHERE tb1.a = 1;
ERROR:  column "f" of relation "tb1" does not exist
LINE 1: UPDATE update_test1 tb1 SET tb1.f = 4 WHERE tb1.a = 1;
                                    ^
UPDATE update_test1 tb SET tb1.a = 4 WHERE tb.a = 1;
ERROR:  Perhaps you meant to reference the table alias "tb".
UPDATE update_test1 tb SET tb1.f = 4 WHERE tb.a = 1;
ERROR:  Perhaps you meant to reference the table alias "tb".
UPDATE update_test1 tb1 SET tb1.a = 5 WHERE tb1.a = 1;
UPDATE update_test1 tb1 SET update_test1.a = 6 WHERE tb1.a = 2;
UPDATE update_test1 SET update_test1.a = 7 WHERE a = 3;
UPDATE update_test1 tb1 SET a = 8 WHERE a = 4;
SELECT * FROM update_test1;
 a | b  | c 
---+----+----
 5 | 10 | aa
 6 | 11 | bb
 7 | 12 | cc
 8 | 13 | dd
(4 rows)
 
2016-04-07

WANGSHUO
A PGer
Attachment

Re: Why the "UPDATE tab SET tab.col" is invalid?

From
Merlin Moncure
Date:
On Thu, Apr 7, 2016 at 4:39 AM, postgres_sure <postgres_sure@163.com> wrote:
> Hi,
>
> I found "Do not include the table's name in the specification of a target
> column
>                  — for example, UPDATE tab SET tab.col = 1 is invalid." in
> the documentation.
>
> Some people usually like to update table by alias. They want to add this
> feature.

Is this syntax described in the SQL standard?

merlin



Re: Why the "UPDATE tab SET tab.col" is invalid?

From
Geoff Winkless
Date:
On 7 April 2016 at 14:48, Merlin Moncure <mmoncure@gmail.com> wrote:
>
> On Thu, Apr 7, 2016 at 4:39 AM, postgres_sure <postgres_sure@163.com> wrote:
> > Hi,
> >
> > I found "Do not include the table's name in the specification of a target
> > column
> >                  — for example, UPDATE tab SET tab.col = 1 is invalid." in
> > the documentation.
> >
> > Some people usually like to update table by alias. They want to add this
> > feature.
>
> Is this syntax described in the SQL standard?

Given that the SQL standard has no concept of UPDATEs against a query
with multiple tables, and that's where this could bring the most
clarity, I'm not sure that it's reasonable to object on that basis.

As far as I can see the SQL standard doesn't let you alias tables in
an UPDATE (for the same reason, I imagine) but we allow _that_ even in
a single-table UPDATE.

<update statement: positioned> ::=             UPDATE <table name>               SET <set clause list>
WHERECURRENT OF <cursor name> 


Geoff



Re: Why the "UPDATE tab SET tab.col" is invalid?

From
Geoff Winkless
Date:
On 7 April 2016 at 15:51, I wrote:
> <update statement: positioned> ::=
>               UPDATE <table name>
>                 SET <set clause list>
>                   WHERE CURRENT OF <cursor name>

I grabbed the wrong section of the doc; I should of course have pasted
the searched version:

<update statement: searched> ::=             UPDATE <table name>               SET <set clause list>               [
WHERE<search condition> ]
 

My point is still the same though :)

Geoff



Re: Why the "UPDATE tab SET tab.col" is invalid?

From
Tom Lane
Date:
Geoff Winkless <pgsqladmin@geoff.dj> writes:
> I grabbed the wrong section of the doc; I should of course have pasted
> the searched version:

> <update statement: searched> ::=
>               UPDATE <table name>
>                 SET <set clause list>
>                 [ WHERE <search condition> ]

> My point is still the same though :)

Don't know which version of the SQL spec you're looking at, but SQL:2008
has

<update statement: searched> ::= UPDATE <target table> [ [ AS ] <correlation name> ]     SET <set clause list>     [
WHERE<search condition> ]
 

Note the [ [ AS ] <correlation name> ] bit.  However, they do NOT
allow the correlation name to appear in <set target>:

<set clause list> ::= <set clause> [ { <comma> <set clause> }... ]

<set clause> ::=   <multiple column assignment> | <set target> <equals operator> <update source>

<set target> ::=   <update target> | <mutated set clause>

<multiple column assignment> ::= <set target list> <equals operator> <assigned row>

<set target list> ::= <left paren> <set target> [ { <comma> <set target> }... ] <right paren>

<assigned row> ::= <contextually typed row value expression>

<update target> ::=   <object column> | <object column>     <left bracket or trigraph> <simple value specification>
<rightbracket or trigraph>
 

<object column> ::= <column name>

<mutated set clause> ::= <mutated target> <period> <method name>

<mutated target> ::=   <object column> | <mutated set clause>

<update source> ::=   <value expression> | <contextually typed value specification>

<column name> is elsewhere defined as just <identifier>, if you were
hoping there was more there than meets the eye.  The "mutated target"
business is some overly complex version of composite-type columns.

The reason why SQL doesn't allow an optional correlation name, and
probably never will, is the same as the reason why we don't, and probably
never will: it introduces an ambiguity as to whether you meant a dotted
set-clause target name to be a reference to a field of a composite column
or just a noise-word reference to the table's correlation name.  If there
were any functional value in specifying the correlation name, it might be
worth dealing with the ambiguity; but there isn't.
        regards, tom lane



Re: Why the "UPDATE tab SET tab.col" is invalid?

From
Geoff Winkless
Date:
On 7 April 2016 at 16:45, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Don't know which version of the SQL spec you're looking at,

It was the draft 95 version, cos (being text file) it's easiest to
read :). I'll learn my lesson next time and expand the 2008 one.

> but SQL:2008 has
>
> <update statement: searched> ::=
>   UPDATE <target table> [ [ AS ] <correlation name> ]
>       SET <set clause list>
>       [ WHERE <search condition> ]
[snip]
> The reason why SQL doesn't allow an optional correlation name, and
> probably never will, is the same as the reason why we don't, and probably
> never will: it introduces an ambiguity as to whether you meant a dotted
> set-clause target name to be a reference to a field of a composite column
> or just a noise-word reference to the table's correlation name.

I stand (comprehensively :) ) corrected, thanks for clarifying.

Geoff



Re: Why the "UPDATE tab SET tab.col" is invalid?

From
Tom Lane
Date:
"postgres_sure"<postgres_sure@163.com> writes:
> I found "Do not include the table's name in the specification of a target column
>                  — for example, UPDATE tab SET tab.col = 1 is invalid." in the documentation. 

> Some people usually like to update table by alias. They want to add this feature.

Sorry, but we aren't ever going to accept such a patch, because it would
introduce an unavoidable ambiguity: is "SET a.b = " meant to be an
assignment to column b of table a, or is it meant to be an assignment to
sub-field b of composite column a?

Yeah, we could invent some resolution rules to deal with that, but
better to just not add the nonstandard syntax (and it IS nonstandard,
SQL:2011 has nothing about it) in the first place.
        regards, tom lane