Re: Atomicity of UPDATE, interchanging values in unique

From: daniel alvarez <d-alvarez(at)gmx(dot)de>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: rbt(at)rbt(dot)ca, pgsql-sql(at)postgresql(dot)org
Subject: Re: Atomicity of UPDATE, interchanging values in unique
Date: 2003-03-08 23:21:37
Message-ID: 23176.1047165697@www5.gmx.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-sql

> >> There must be a better solution than the additional dummy update.
>
> How about swapping all the other columns, and preserving the identity of
> the primary key? Arguably, swapping primary keys is a violation of the
> relational model to begin with.

You misunderstood what I'm saying. Of course updating a primary key would
be a cardinal sin. But this is not about primary keys. I did not even
mention it.
It is about exchanging unique values in an ordinary data column having a
unique
index on it. I observed that an update is not completely atomic, because the
constraints are validated as the indexes are accessed (probably once per
row)
and a single UPDATE swapping the values will fail. Observe:

UPDATE sometable SET unique_col =
CASE WHEN unique_col = firstvalue THEN secondvalue
ELSE firstvalue
END
WHERE unique_col = firstvalue
OR unique_col = secondvalue

ERROR: Cannot insert a duplicate key into unique index
sometable_unique_col_idx

The question is how to perform the swapping without having to use an
additional dummy
update. This approach works, but is ugly:

BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

UPDATE sometable SET someuniquecol = (SELECT MAX(someuniquecol) FROM
sometable) + 1
WHERE someuniquecol = 1;

UPDATE sometable SET someuniquecol = 2 WHERE someuniquecol = 1;
UPDATE sometable SET someuniquecol = 1
WHERE someuniquecol = (SELECT MAX(someuniquecol) FROM sometable) + 1;

COMMIT;

Regards, Daniel Alvarez <d-alvarez(at)gmx(dot)de>

--
+++ GMX - Mail, Messaging & more http://www.gmx.net +++
Bitte lächeln! Fotogalerie online mit GMX ohne eigene Homepage!

In response to

Browse pgsql-sql by date

  From Date Subject
Next Message jack 2003-03-09 03:33:44 pl/pgsql how to return multiple values from a function
Previous Message Björn Lundin 2003-03-08 23:20:57 Re: Beginner needs help