Question

When I run this query:

UPDATE myTable SET x = (SELECT round(random()*100));

All records have the same value for x. This makes sense.

When I run this query:

UPDATE myTable SET x = round(random()*100);

It updates all records in the table and for each record the value of x is different.

I would like to know whats happening in the background for the second query. Is it running a update query for each record id(1....n)?

I am guessing it works similar to triggers, where for each row before updating

  1. the trigger intercepts
  2. calls the function and sets value of x
  3. executes query

What is actually happening?

Was it helpful?

Solution

It's rather simple, really. The function random() is defined VOLATILE.

If you put it into a subquery, you generate a derived table with a single row. Postgres can materialize the result and reuse it in the outer query many times.

Otherwise Postgres calls the function for every row. That's how VOLATILE functions have to be treated. Per documentation on function volatility:

A VOLATILE function can do anything, including modifying the database. It can return different results on successive calls with the same arguments. The optimizer makes no assumptions about the behavior of such functions. A query using a volatile function will re-evaluate the function at every row where its value is needed.

Bold emphasis mine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top