UPDATE using query; per-row function calling problem
I'm doing an UPDATE something like this:
UPDATE
slots
SET
a = 'a'
,b = (SELECT uuid_generate_v1())
WHERE
c = TRUE;
Each updated row in slots is getting the same value for b. Is there a
way of getting a per-row value from uuid_generate_v1() without doing a
PL loop?
Regards
Rory
Rory Campbell-Lange <rory@campbell-lange.net> writes:
I'm doing an UPDATE something like this:
UPDATE
slots
SET
a = 'a'
,b = (SELECT uuid_generate_v1())
WHERE
c = TRUE;
Each updated row in slots is getting the same value for b.
That's Postgres' interpretation of an uncorrelated sub-SELECT: there's
no reason to do it more than once, so it doesn't.
Is there a way of getting a per-row value from uuid_generate_v1()
without doing a PL loop?
Drop the word "SELECT". Why did you put that in in the first place?
regards, tom lane
On 02/09/11, Tom Lane (tgl@sss.pgh.pa.us) wrote:
Rory Campbell-Lange <rory@campbell-lange.net> writes:
I'm doing an UPDATE something like this:
UPDATE
slots
SET
a = 'a'
,b = (SELECT uuid_generate_v1())
WHERE
c = TRUE;Each updated row in slots is getting the same value for b.
That's Postgres' interpretation of an uncorrelated sub-SELECT: there's
no reason to do it more than once, so it doesn't.Is there a way of getting a per-row value from uuid_generate_v1()
without doing a PL loop?Drop the word "SELECT". Why did you put that in in the first place?
Hi Tom
Good question to which I don't know the answer. Thanks very much for the
advice.
I was able to force a per-row call to uuid_generate_v1 by using this
pattern
UPDATE
r_slots
SET b = (SELECT
y.x
FROM
(select -1 as n, uuid_generate_v1() as x )y
WHERE
y.n != r_slots.id)
...
But
b = uuid_generate_v1()
is a lot simpler!
In my "-1" example, am I right in assuming that I created a correlated
subquery rather than an correlated one? I'm confused about the
difference.
Many thanks
Rory
In my "-1" example, am I right in assuming that I created a correlated
subquery rather than an correlated one? I'm confused about the
difference.
Correlated: has a where clause that references the outer query
Un-correlated: not correlated
Because of the where clause a correlated sub-query will return a different record for each row whereas an un-correlated sub-query will return the same record for all rows since the where clause (if any) is constant.
David J.
That's interpretation of subselect is ok, when it contains only stable
functions.
Maybe add a warning when subselect contains volatile function.
2011/9/2, Rory Campbell-Lange <rory@campbell-lange.net>:
On 02/09/11, Tom Lane (tgl@sss.pgh.pa.us) wrote:
Rory Campbell-Lange <rory@campbell-lange.net> writes:
I'm doing an UPDATE something like this:
UPDATE
slots
SET
a = 'a'
,b = (SELECT uuid_generate_v1())
WHERE
c = TRUE;Each updated row in slots is getting the same value for b.
That's Postgres' interpretation of an uncorrelated sub-SELECT: there's
no reason to do it more than once, so it doesn't.Is there a way of getting a per-row value from uuid_generate_v1()
without doing a PL loop?Drop the word "SELECT". Why did you put that in in the first place?
Hi Tom
Good question to which I don't know the answer. Thanks very much for the
advice.I was able to force a per-row call to uuid_generate_v1 by using this
patternUPDATE
r_slots
SET b = (SELECT
y.x
FROM
(select -1 as n, uuid_generate_v1() as x )y
WHERE
y.n != r_slots.id)
...But
b = uuid_generate_v1()
is a lot simpler!In my "-1" example, am I right in assuming that I created a correlated
subquery rather than an correlated one? I'm confused about the
difference.Many thanks
Rory--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general
--
------------
pasman
=?ISO-8859-2?Q?pasman_pasma=F1ski?= <pasman.p@gmail.com> writes:
That's interpretation of subselect is ok, when it contains only stable
functions.
Maybe add a warning when subselect contains volatile function.
We're not likely to do that, because this sort of notation is actually
fairly commonly used to hide the volatility of non-stable functions.
regards, tom lane
On 02/09/11, David Johnston (polobo@yahoo.com) wrote:
In my "-1" example, am I right in assuming that I created a correlated
subquery rather than an correlated one? I'm confused about the
difference.Correlated: has a where clause that references the outer query
Un-correlated: not correlatedBecause of the where clause a correlated sub-query will return a
different record for each row whereas an un-correlated sub-query will
return the same record for all rows since the where clause (if any) is
constant.
Hi David -- thanks for the clarification. However I'm still a little
confused. As I understand it the following is a un-correlated sub-query:
UPDATE
slots
SET
a = 'a'
,b = (SELECT uuid_generate_v1())
WHERE
c = TRUE;
and the following, without a 'WHERE', is a correlated sub-query:
UPDATE
slots
SET
a = 'a'
,b = uuid_generate_v1()
WHERE
c = TRUE;
Is the point that the lower is not a sub-query at all?
Regards
Rory
-----Original Message-----
From: pgsql-general-owner@postgresql.org
[mailto:pgsql-general-owner@postgresql.org] On Behalf Of Rory Campbell-Lange
Sent: Monday, September 05, 2011 4:55 PM
To: David Johnston
Cc: Tom Lane; pgsql-general@postgresql.org
Subject: Re: [GENERAL] UPDATE using query; per-row function calling problem
On 02/09/11, David Johnston (polobo@yahoo.com) wrote:
In my "-1" example, am I right in assuming that I created a
correlated subquery rather than an correlated one? I'm confused
about the difference.Correlated: has a where clause that references the outer query
Un-correlated: not correlatedBecause of the where clause a correlated sub-query will return a
different record for each row whereas an un-correlated sub-query will
return the same record for all rows since the where clause (if any) is
constant.
Hi David -- thanks for the clarification. However I'm still a little
confused. As I understand it the following is a un-correlated sub-query:
UPDATE
slots
SET
a = 'a'
,b = (SELECT uuid_generate_v1())
WHERE
c = TRUE;
and the following, without a 'WHERE', is a correlated sub-query:
UPDATE
slots
SET
a = 'a'
,b = uuid_generate_v1()
WHERE
c = TRUE;
Is the point that the lower is not a sub-query at all?
----------------------------------------------------------------------------
--------------------------
Correct, the second query uses a simple function call to set the value of
"b"; Using your example you would need to do something like:
UPDATE
slots
SET
a = 'a'
,b = (SELECT something FROM somewhere WHERE somewhere.a = slots.a)
WHERE
c = TRUE;
to use a correlated sub-query. Since "uuid_generate_v1()" doesn't naturally
link to slots (or anything else) there isn't any meaningful way to use a
correlated sub-query in this situation. Since you are using a function (as
opposed to a direct TABLE/VIEW) the use of a sub-query is pointless and,
apparently, results in optimizations that are undesirable.
David J.