Обсуждение: BUG #5606: DEFERRABLE and DEFERRABLE INITIALLY DEFERRED are the same

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

BUG #5606: DEFERRABLE and DEFERRABLE INITIALLY DEFERRED are the same

От
"Frank Heikens"
Дата:
The following bug has been logged online:

Bug reference:      5606
Logged by:          Frank Heikens
Email address:      f.heikens@anva.nl
PostgreSQL version: PostgreSQL9.0b4
Operating system:   WinXP
Description:        DEFERRABLE and  DEFERRABLE INITIALLY DEFERRED are the
same
Details:

Today I checked out the wiki and did some tests using the deferrable unique
constraints described at:
http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.0#DEFERRABLE_UN
IQUE_CONSTRAINTS

I copied/pasted the examples and to my surprise, DEFERRABLE and DEFERRABLE
INITIALLY DEFERRED work exactly the same, there is no need to use
CONSTRAINTS ALL DEFERRED; at all. The wiki and manual describe the need for
this, but no matter what, it always works the same. (see tests and results
below)

It's tested on a local machine, Windows XP, 32bit, using the
EnterpriseDB-installer:
PostgreSQL 9.0beta4, compiled by Visual C++ build 1500, 32-bit

-- Test 1
CREATE TABLE test (a int primary key);
INSERT INTO test values (1), (2);
UPDATE test set a = a+1;
-- Result: Error: duplicate key value violates unique constraint
"test_pkey"
-- This is Ok.

-- Test 2
CREATE TABLE test (a int primary key deferrable);
INSERT INTO test values (1),(2);
UPDATE test set a = a+1;
-- Result: Query returned successfully: 2 rows affected, 15 ms execution
time.
-- Not Ok, see the manual and wiki, should result in the same error as test
1.

-- Test 3
CREATE TABLE test (a int PRIMARY KEY DEFERRABLE INITIALLY DEFERRED);
INSERT INTO test values (1),(2);
UPDATE test set a = a+1;
-- Result: Query returned successfully: 2 rows affected, 31 ms execution
time.
-- This is Ok.

Each test was executed using it's own connection.

If you need more information, just let me know.

Kind regards,

Frank Heikens
PostgreSQL DBA

ANVA
Postbus 190, 3800 AD Amersfoort
Stadsring 201, 3817 BA Amersfoort
T: +31 (0)33 479 82 00
F: +31 (0)33 472 78 22
www.anva.nl

Re: BUG #5606: DEFERRABLE and DEFERRABLE INITIALLY DEFERRED are the same

От
Tom Lane
Дата:
"Frank Heikens" <f.heikens@anva.nl> writes:
> Description:        DEFERRABLE and  DEFERRABLE INITIALLY DEFERRED are the
> same

This test proves no such thing.  You are supposing that a deferrable
unique index has the exact same behavior as a nondeferrable one.
Actually, a DEFERRABLE IMMEDIATE index enforces its checks as of the end
of the statement, which is per spec.

            regards, tom lane

Re: BUG #5606: DEFERRABLE and DEFERRABLE INITIALLY DEFERRED are the same

От
Tom Lane
Дата:
Frank Heikens <f.heikens@anva.nl> writes:
> The wikipage says
>> a deferrable constraint CAN be checked at the end of a
>> transaction. You still have to ask PostgreSQL to defer it.
> http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.0#DEFERRABLE_UNIQUE_CONSTRAINTS

> I don't have to ask PostgreSQL to defer, it works in the second test
as well in the third test without any changes. I guess the example in
the wiki isn't correct, right?

No, not even a little bit :-(.  I hadn't seen that text; it needs to be
corrected.  Will hack on it in a moment.

> A single UPDATE touching all records will check the uniqueness after the complete update, not right after each update
ofa row as it does on non-deferrable constraints. 

Right.
non-deferrable -> uniqueness is enforced after each row change
DEFERRABLE IMMEDIATE -> uniqueness is enforced at end of statement
DEFERRABLE DEFERRED -> uniqueness is enforced at end of transaction

> Maybe someone could make this clear in the manual and wiki?

AFAIK the manual is OK; do you see a place where it gets this wrong?

            regards, tom lane

Re: BUG #5606: DEFERRABLE and DEFERRABLE INITIALLY DEFERRED are the same

От
Tom Lane
Дата:
Frank Heikens <f.heikens@anva.nl> writes:
>> http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.0#DEFERRABLE_UNIQUE_CONSTRAINTS

>> I don't have to ask PostgreSQL to defer, it works in the second test
>> as well in the third test without any changes. I guess the example in
>> the wiki isn't correct, right?

> No, not even a little bit :-(.  I hadn't seen that text; it needs to be
> corrected.  Will hack on it in a moment.

I edited that wiki section, see what you think.

            regards, tom lane

Re: BUG #5606: DEFERRABLE and DEFERRABLE INITIALLY DEFERRED are the same

От
Dean Rasheed
Дата:
On 6 August 2010 16:25, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Frank Heikens <f.heikens@anva.nl> writes:
>>> http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.0#DEFERRAB=
LE_UNIQUE_CONSTRAINTS
>
>>> I don't have to ask PostgreSQL to defer, it works in the second test
>>> as well in the third test without any changes. I guess the example in
>>> the wiki isn't correct, right?
>
>> No, not even a little bit :-(. =A0I hadn't seen that text; it needs to be
>> corrected. =A0Will hack on it in a moment.
>
> I edited that wiki section, see what you think.
>

Yes, that's much better. I didn't read this page until just now.

I did, however, read the release notes, and I didn't spot a similar error t=
here:

"""
This allows UPDATE tab SET col =3D col + 1 to work on columns that have
a unique indexes or are marked as primary key, but DEFERRABLE
INITIALLY DEFERRED must be used to mark the constraint as deferred.
"""

Perhaps this should be something like

"""
This allows UPDATE tab SET col =3D col + 1 to work on columns that have
unique indexes or are marked as primary keys. If the constraint is
specified as DEFERRABLE it will be checked at the end of the statement
rather than as each row is updated. The constraint check may also be
DEFERRED until the end of the current transaction allowing updates to
be spread over multiple SQL commands.
"""

Regards,
Dean

Re: BUG #5606: DEFERRABLE and DEFERRABLE INITIALLY DEFERRED are the same

От
Tom Lane
Дата:
Dean Rasheed <dean.a.rasheed@gmail.com> writes:
> On 6 August 2010 16:25, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> I edited that wiki section, see what you think.

> Yes, that's much better. I didn't read this page until just now.

> I did, however, read the release notes, and I didn't spot a similar error there:

> """
> This allows UPDATE tab SET col = col + 1 to work on columns that have
> a unique indexes or are marked as primary key, but DEFERRABLE
> INITIALLY DEFERRED must be used to mark the constraint as deferred.
> """

Hum, maybe that's where the wiki author's mistake came from :-(.  Will fix.

            regards, tom lane

Re: BUG #5606: DEFERRABLE and DEFERRABLE INITIALLY DEFERRED are the same

От
Frank Heikens
Дата:
Hi Tom,

The wikipage says
> a deferrable constraint CAN be checked at the end of a
> transaction. You still have to ask PostgreSQL to defer it.
http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.0#DEFERRABLE_U=
NIQUE_CONSTRAINTS

I don't have to ask PostgreSQL to defer, it works in the second test as wel=
l in the third test without any changes. I guess the example in the wiki is=
n't correct, right? A single UPDATE touching all records will check the uni=
queness after the complete update, not right after each update of a row as =
it does on non-deferrable constraints.

This one fails, as it should:
CREATE TABLE test (a int primary key deferrable, b int )
INSERT INTO test values (1,1),(2,2);

BEGIN;
        UPDATE test SET a =3D a+1 WHERE b =3D 1;    -- FAIL: ERROR:  duplic=
ate key value violates unique constraint "test_pkey"
        UPDATE test SET a =3D a+1 WHERE b =3D 2;
COMMIT;


And this one works fine, as it should:
CREATE TABLE test (a int primary key deferrable, b int )
INSERT INTO test values (1,1),(2,2);

BEGIN;
        SET constraints ALL deferred;
        UPDATE test SET a =3D a+1 WHERE b =3D 1;
        UPDATE test SET a =3D a+1 WHERE b =3D 2;
COMMIT;


And this one works fine as well, and got me confused:
CREATE TABLE test (a int primary key deferrable, b int )
INSERT INTO test values (1,1),(2,2);
UPDATE test set a =3D a+1; -- single UPDATE statement, only checks after al=
l updates, didn't see it coming.

Maybe someone could make this clear in the manual and wiki?

Regards,
Frank Heikens



-----Oorspronkelijk bericht-----
Van: Tom Lane [mailto:tgl@sss.pgh.pa.us]
Verzonden: vrijdag 6 augustus 2010 16:14
Aan: Frank Heikens
CC: pgsql-bugs@postgresql.org
Onderwerp: Re: [BUGS] BUG #5606: DEFERRABLE and DEFERRABLE INITIALLY DEFERR=
ED are the same

"Frank Heikens" <f.heikens@anva.nl> writes:
> Description:        DEFERRABLE and  DEFERRABLE INITIALLY DEFERRED are the
> same

This test proves no such thing.  You are supposing that a deferrable
unique index has the exact same behavior as a nondeferrable one.
Actually, a DEFERRABLE IMMEDIATE index enforces its checks as of the end
of the statement, which is per spec.

                        regards, tom lane

***************************DISCLAIMER***********************************
Deze e-mail is uitsluitend bestemd voor de geadresseerde(n). Verstrekking a=
an en gebruik door anderen is niet toegestaan. ANVA bv sluit iedere aanspra=
kelijkheid uit die voortvloeit uit electronische verzending.

This e-mail is intended exclusively for the addressee(s), and may not be pa=
ssed on to, or made available for use by any person other than the addresse=
e(s). ANVA bv rules out any and every liability resulting from any electron=
ic transmission.
***************************************************************************=
***

Re: BUG #5606: DEFERRABLE and DEFERRABLE INITIALLY DEFERRED are the same

От
Frank Heikens
Дата:
The manual looks fine, I found the information as well. I started using the=
 wiki, that's why I got confused.

Thanks!

Frank

-----Oorspronkelijk bericht-----
Van: Tom Lane [mailto:tgl@sss.pgh.pa.us]
Verzonden: vrijdag 6 augustus 2010 17:04
Aan: Frank Heikens
CC: pgsql-bugs@postgresql.org
Onderwerp: Re: [BUGS] BUG #5606: DEFERRABLE and DEFERRABLE INITIALLY DEFERR=
ED are the same

Frank Heikens <f.heikens@anva.nl> writes:
> The wikipage says
>> a deferrable constraint CAN be checked at the end of a
>> transaction. You still have to ask PostgreSQL to defer it.
> http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.0#DEFERRABLE=
_UNIQUE_CONSTRAINTS

> I don't have to ask PostgreSQL to defer, it works in the second test
as well in the third test without any changes. I guess the example in
the wiki isn't correct, right?

No, not even a little bit :-(.  I hadn't seen that text; it needs to be
corrected.  Will hack on it in a moment.

> A single UPDATE touching all records will check the uniqueness after the =
complete update, not right after each update of a row as it does on non-def=
errable constraints.

Right.
non-deferrable -> uniqueness is enforced after each row change
DEFERRABLE IMMEDIATE -> uniqueness is enforced at end of statement
DEFERRABLE DEFERRED -> uniqueness is enforced at end of transaction

> Maybe someone could make this clear in the manual and wiki?

AFAIK the manual is OK; do you see a place where it gets this wrong?

                        regards, tom lane

***************************DISCLAIMER***********************************
Deze e-mail is uitsluitend bestemd voor de geadresseerde(n). Verstrekking a=
an en gebruik door anderen is niet toegestaan. ANVA bv sluit iedere aanspra=
kelijkheid uit die voortvloeit uit electronische verzending.

This e-mail is intended exclusively for the addressee(s), and may not be pa=
ssed on to, or made available for use by any person other than the addresse=
e(s). ANVA bv rules out any and every liability resulting from any electron=
ic transmission.
***************************************************************************=
***