Thread: 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-querywill 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 > 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 > > > > > -- > 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 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. 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 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. 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.