Re: Using random() in update produces same random value for all

From: Olleg Samoylov <splarv(at)ya(dot)ru>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Jeff Janes <jeff(dot)janes(at)gmail(dot)com>
Cc: "pgsql-general(at)lists(dot)postgresql(dot)org" <pgsql-general(at)lists(dot)postgresql(dot)org>
Subject: Re: Using random() in update produces same random value for all
Date: 2018-01-23 10:15:41
Message-ID: 3643511516702541@web17j.yandex.ru
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On 2018-01-22 23:15, Tom Lane wrote:
>
> It is honored as volatile: it will be re-evaluated every time the
> sub-select is re-evaluated. It's just that there's no cause to
> re-evaluate the sub-select.
>
> I poked through the SQL standard to see if it spells out the semantics
> of uncorrelated subqueries anywhere, and couldn't find anything relevant
> at all. But this is how Postgres has understood the behavior of
> sub-selects for a very long time (~20 years). I'm pretty certain
> that there are people depending on it to behave this way.
>
> regards, tom lane

The cause exists, the function is volatile and according to definition
it must be recalculated every time. But well, one more example.

=> select generate_series,(select random+generate_series from random())
from generate_series(1,10);
 generate_series |     ?column?
-----------------+------------------
               1 | 1.94367738347501
               2 | 2.94367738347501
               3 | 3.94367738347501
               4 | 4.94367738347501
               5 | 5.94367738347501
               6 | 6.94367738347501
               7 | 7.94367738347501
               8 | 8.94367738347501
               9 | 9.94367738347501
              10 |  10.943677383475
(10 rows)

As you can see, sub-select is indeed recalculated, but not random(). And
this is may be right, because random() is used as source off data.
Another example.

=> select generate_series,(select random()+generate_series) from
generate_series(1,10);
 generate_series |     ?column?
-----------------+------------------
               1 | 1.37678202055395
               2 |  2.5316761219874
               3 | 3.33511888468638
               4 |  4.0293406387791
               5 | 5.69305071979761
               6 | 6.33374964864925
               7 | 7.14478175388649
               8 |  8.1831739502959
               9 |  9.4472619513981
              10 | 10.2977624684572
(10 rows)

Here random() is recalculated as sub-select.

But in

=> select *,(select random()) from generate_series(1,10);
 generate_series |      random
-----------------+-------------------
               1 | 0.487761380150914
               2 | 0.487761380150914
               3 | 0.487761380150914
               4 | 0.487761380150914
               5 | 0.487761380150914
               6 | 0.487761380150914
               7 | 0.487761380150914
               8 | 0.487761380150914
               9 | 0.487761380150914
              10 | 0.487761380150914
(10 rows)

is not.

IMHO all this behavior may be not bad, but it must be well documented in
manual in section about sub-selects. All sub-select must be documented
as "stable" in terms of function definition. And thus will not be surprise.

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Adrian Klaver 2018-01-23 14:03:37 Re: Changing locale/charset
Previous Message Thiemo Kellner, NHC Barhufpflege 2018-01-23 07:36:07 Re: FW: Setting up streaming replication problems