Обсуждение: [GENERAL] UPDATE feature or bug?

Поиск
Список
Период
Сортировка

[GENERAL] UPDATE feature or bug?

От
Stuart Rison
Дата:
Dear all,

Consider the following table;

functions=> select * from prova order by a,b,c,d;
a|b|c|d
-+-+-+-
4|0|0|0
4|1|0|0
4|1|1|0
4|1|2|0
4|1|3|0
4|1|4|0
4|3|0|0
4|3|1|0
4|3|2|0
4|4|0|0
4|4|1|0
4|4|2|0
4|4|3|0
(13 rows)

with a unique index on (a,b,c,d)

and note that there is a gap in the continuity of b (from 4.1 to 4.3).

If I try

UPDATE prova SET b=b-1 WHERE b>2;

I get:

ERROR:  Cannot insert a duplicate key into a unique index

but if I try:

functions=> update prova set b=b-1 where b=3;
UPDATE 3
functions=> update prova set b=b-1 where b=4;
UPDATE 4

it works.

Now I've sussed this out as the update must be dealing with rows where b=4
first, trying to UPDATE them to b=3 and failing because these are already
'occupied'.

Is this a bug? is this a feature? is there a way of telling the UPDATE
what order to UPDATE in?

Regards,

Stuart.

Stuart C. G. Rison
Department of Biochemistry and Molecular Biology
6th floor, Darwin Building, University College London (UCL)
Gower Street, London, WC1E 6BT, United Kingdom
Tel. 0207 504 2303, Fax. 0207 380 7033
e-mail: rison@biochem.ucl.ac.uk



Re: [SQL] [GENERAL] UPDATE feature or bug?

От
Tom Lane
Дата:
Stuart Rison <rison@biochemistry.ucl.ac.uk> writes:
> Now I've sussed this out as the update must be dealing with rows where b=4
> first, trying to UPDATE them to b=3 and failing because these are already
> 'occupied'.

> Is this a bug? is this a feature? is there a way of telling the UPDATE
> what order to UPDATE in?

It's a bug, but I doubt it's likely to get fixed any time soon, since
unique indexes would get a LOT slower if they did this "right".  As you
say, the update must be hitting some of the b=4 rows first.  At that
point, the system has no idea that the existing b=3 rows are going to be
invalidated in the same transaction, so its uniqueness check fails.  To
do this right, the uniqueness check would have to be applied at the end
of the transaction, which would mean remembering every tuple that's been
inserted/updated in the current transaction and going back to check its
uniqueness.

There is a running discussion on the hackers list about implementing
referential integrity constraints, which have this same problem that
you can't really apply (some kinds of) checks until you see the entire
transaction results.  It'll get done but it's not simple.  I'm not
sure whether anyone is thinking of applying that mechanism to unique-
index checks...
        regards, tom lane