From: | Adrian Klaver <adrian(dot)klaver(at)aklaver(dot)com> |
---|---|
To: | "Peter J(dot) Holzer" <hjp-pgsql(at)hjp(dot)at>, pgsql-general(at)postgresql(dot)org |
Subject: | Re: Order of update |
Date: | 2025-04-20 15:28:22 |
Message-ID: | c71a961f-506d-43ad-92c6-f23831e408c5@aklaver.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
On 4/20/25 02:10, Peter J. Holzer wrote:
> I've just read Laurenz' blog post about the differences between Oracle
> and PostgreSQL[1].
>
> One of the differences is that something like
>
> UPDATE tab SET id = id + 1;
>
> tends to fail on PostgreSQL because the the primary key constraint is
> checked for every row, so it will stumble over the temporary conflicts.
>
> The solution is to define the constraint as deferrable.
>
> But that got me to thinking about different ways ...
>
> There won't be a conflict if the ids are updated in descending order.
> Is there a way to force PostgreSQL to update the rows in a specific
> order?
>
> I came up with
>
> with a as (select id from t where id > 50 order by id desc)
> update t set id = a.id+1 from a where t.id = a.id;
>
> which works in my simple test case, but it doesn't look like it's
> guaranteed to work. The implicit join in «update t ... from a» could
> produce rows in any order, especially for large tables.
My read of this is that for the duration of the query a temporary table
a is create that is ordered on `id desc` and that '... from a where t.id
= a.id' will apply that order to the selection of t.id.
As example:
create table id_update(id integer primary key);
insert into id_update select a from generate_series(1, 100000) as t(a);
INSERT 0 100000
-- id(s) are temporarily in order.
update id_update set id = id where id between 50000 and 60000;
UPDATE 10001
-- The above move the 10001 values to 'end' of id_update
with a as (select id from id_update where id > 100 order by id desc)
update id_update as t set id = a.id + 1 from a where t.id = a.id;
UPDATE 99900
-- The UPDATE works even though the t.id(s) in id_update are not ordered
-- by id
>
> So, is there a better way?
>
> hjp
>
>
> [1] https://www.cybertec-postgresql.com/en/comparison-of-the-transaction-systems-of-oracle-and-postgresql/
>
--
Adrian Klaver
adrian(dot)klaver(at)aklaver(dot)com
From | Date | Subject | |
---|---|---|---|
Next Message | Peter J. Holzer | 2025-04-21 08:47:17 | Re: Order of update |
Previous Message | Thiemo Kellner | 2025-04-20 14:52:25 | Re: Order of update |