Lists: | pgsql-bugs |
---|
From: | hubert depesz lubaczewski <depesz(at)depesz(dot)com> |
---|---|
To: | pgsql-bugs(at)postgresql(dot)org |
Subject: | misleading error message in 8.5, and bad (?) way deferred uniqueness works |
Date: | 2009-08-11 11:14:46 |
Message-ID: | 20090811111446.GA25965@depesz.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-bugs |
While testing deferred unique constraints I found this:
# CREATE TABLE test (
i INT4 PRIMARY KEY
);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_pkey" for table "test"
CREATE TABLE
# set constraints test_pkey deferred;
ERROR: constraint "test_pkey" does not exist
The constraint definitely exists:
# select * from pg_constraint where conname = 'test_pkey';
-[ RECORD 1 ]-+----------
conname | test_pkey
connamespace | 2200
contype | p
condeferrable | f
condeferred | f
conrelid | 17533
contypid | 0
conindid | 17536
confrelid | 0
confupdtype |
confdeltype |
confmatchtype |
conislocal | t
coninhcount | 0
conkey | {1}
confkey | [null]
conpfeqop | [null]
conppeqop | [null]
conffeqop | [null]
conbin | [null]
consrc | [null]
This (set ... deferred) works perfectly if i define the table like this:
# CREATE TABLE test (
i INT4 PRIMARY KEY DEFERRABLE INITIALLY IMMEDIATE
);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_pkey" for table "test"
CREATE TABLE
# set constraints test_pkey deferred;
SET CONSTRAINTS
Also.
As I understand (I might be wrong, so please clarify if I am), when I
create table with primary key that is "deferrable initially immediate",
it will act as immediate unless i will set it to deferred with "set
constraints".
If that's true, then why it works:
# INSERT INTO test (i) values (1), (2), (3);
INSERT 0 3
# update test set i = i + 1;
UPDATE 3
shouldn't it raise exception? and work *only* if i set the constraint to
deferred?
depesz
--
Linkedin: http://www.linkedin.com/in/depesz / blog: http://www.depesz.com/
jid/gtalk: depesz(at)depesz(dot)com / aim:depeszhdl / skype:depesz_hdl / gg:6749007
From: | Dean Rasheed <dean(dot)a(dot)rasheed(at)googlemail(dot)com> |
---|---|
To: | depesz(at)depesz(dot)com |
Cc: | pgsql-bugs(at)postgresql(dot)org |
Subject: | Re: misleading error message in 8.5, and bad (?) way deferred uniqueness works |
Date: | 2009-08-11 12:21:25 |
Message-ID: | 8e2dbb700908110521w9e2b735sfceb93f41d17b100@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-bugs |
2009/8/11 hubert depesz lubaczewski <depesz(at)depesz(dot)com>:
> While testing deferred unique constraints I found this:
>
> # CREATE TABLE test (
> i INT4 PRIMARY KEY
> );
> NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_pkey" for table "test"
> CREATE TABLE
>
> # set constraints test_pkey deferred;
> ERROR: constraint "test_pkey" does not exist
>
The constraint needs to be declared DEFERRABLE before you can defer
it, but yes, I agree this is not a helpful error message.
[The reason is that it actually searches for the trigger enforcing the
constraint, and there isn't one if it's not deferrable. So the current
code can't distinguish between a non-existent unique constraint and a
non-deferrable one.]
> As I understand (I might be wrong, so please clarify if I am), when I
> create table with primary key that is "deferrable initially immediate",
> it will act as immediate unless i will set it to deferred with "set
> constraints".
>
> If that's true, then why it works:
> # INSERT INTO test (i) values (1), (2), (3);
> INSERT 0 3
> # update test set i = i + 1;
> UPDATE 3
>
> shouldn't it raise exception? and work *only* if i set the constraint to
> deferred?
>
"Immediate" actually means at the end of the statement rather than
after each row for deferrable constraints. See
http://developer.postgresql.org/pgdocs/postgres/sql-createtable.html
- Dean
From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Dean Rasheed <dean(dot)a(dot)rasheed(at)googlemail(dot)com> |
Cc: | depesz(at)depesz(dot)com, pgsql-bugs(at)postgresql(dot)org |
Subject: | Re: misleading error message in 8.5, and bad (?) way deferred uniqueness works |
Date: | 2009-08-11 16:40:30 |
Message-ID: | 10730.1250008830@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-bugs |
Dean Rasheed <dean(dot)a(dot)rasheed(at)googlemail(dot)com> writes:
> The constraint needs to be declared DEFERRABLE before you can defer
> it, but yes, I agree this is not a helpful error message.
> [The reason is that it actually searches for the trigger enforcing the
> constraint, and there isn't one if it's not deferrable. So the current
> code can't distinguish between a non-existent unique constraint and a
> non-deferrable one.]
Yeah. Is it worth searching pg_constraint first, just so that we can
give a better error message?
Actually, it strikes me that if we did it that way, we could search
pg_trigger using the constraint OID instead of name, which would permit
replacing the index on tgconstrname with a presumably much smaller one
on tgconstraint. And the bogus rechecks on namespace in
AfterTriggerSetState could probably be simplified too ...
regards, tom lane
From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Dean Rasheed <dean(dot)a(dot)rasheed(at)googlemail(dot)com> |
Cc: | depesz(at)depesz(dot)com, pgsql-bugs(at)postgresql(dot)org |
Subject: | Re: misleading error message in 8.5, and bad (?) way deferred uniqueness works |
Date: | 2009-08-11 17:00:30 |
Message-ID: | 19283.1250010030@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | Postg메이저 토토 사이트SQL : Postg메이저 토토 사이트SQL 메일 링리스트 : 2009-08-11 이후 PGSQL-BUGS |
I wrote:
> Dean Rasheed <dean(dot)a(dot)rasheed(at)googlemail(dot)com> writes:
>> [The reason is that it actually searches for the trigger enforcing the
>> constraint, and there isn't one if it's not deferrable. So the current
>> code can't distinguish between a non-existent unique constraint and a
>> non-deferrable one.]
> Yeah. Is it worth searching pg_constraint first, just so that we can
> give a better error message?
Actually, a bit more digging reminded me of why the code does it that
way:
Note: When tgconstraint is nonzero, tgisconstraint must be true,
and tgconstrname, tgconstrrelid, tgconstrindid, tgdeferrable,
tginitdeferred are redundant with the referenced pg_constraint
entry. The reason we keep these fields is that we support
"stand-alone" constraint triggers with no corresponding
pg_constraint entry.
I'm sure somebody would complain if we removed the user-level constraint
trigger facility :-(. It might be worth the trouble to change things so
that there actually is a pg_constraint entry associated with a user
constraint trigger; and then we could do the search as suggested above.
In principle we could also remove the redundant columns from pg_trigger,
but that would mean an extra catalog search each time we set up a
trigger, so I dunno if that would be a good step or not.
Anyway it's looking like a slightly nontrivial project. Maybe we should
just rephrase the error message Hubert is complaining about.
regards, tom lane
From: | Andres Freund <andres(at)anarazel(dot)de> |
---|---|
To: | pgsql-bugs(at)postgresql(dot)org |
Cc: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Dean Rasheed <dean(dot)a(dot)rasheed(at)googlemail(dot)com>, depesz(at)depesz(dot)com |
Subject: | Re: misleading error message in 8.5, and bad (?) way deferred uniqueness works |
Date: | 2009-08-11 19:05:05 |
Message-ID: | 200908112105.07357.andres@anarazel.de |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-bugs |
On Tuesday 11 August 2009 19:00:30 Tom Lane wrote:
> I wrote:
> > Dean Rasheed <dean(dot)a(dot)rasheed(at)googlemail(dot)com> writes:
> >> [The reason is that it actually searches for the trigger enforcing the
> >> constraint, and there isn't one if it's not deferrable. So the current
> >> code can't distinguish between a non-existent unique constraint and a
> >> non-deferrable one.]
> >
> > Yeah. Is it worth searching pg_constraint first, just so that we can
> > give a better error message?
>
> Actually, a bit more digging reminded me of why the code does it that
> way:
>
> Note: When tgconstraint is nonzero, tgisconstraint must be true,
> and tgconstrname, tgconstrrelid, tgconstrindid, tgdeferrable,
> tginitdeferred are redundant with the referenced pg_constraint
> entry. The reason we keep these fields is that we support
> "stand-alone" constraint triggers with no corresponding
> pg_constraint entry.
> I'm sure somebody would complain if we removed the user-level constraint
> trigger facility :-(.
I know of several people using them - out of the simple reason its the only
possibility to get deferred triggers atm... (Which in those cases are used to
update materialized views)
Actually I plan to check (and possibly discuss here) how complex statement
level deferred triggers would be somewhat soon...
Andres
From: | Dean Rasheed <dean(dot)a(dot)rasheed(at)googlemail(dot)com> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | depesz(at)depesz(dot)com, pgsql-bugs(at)postgresql(dot)org |
Subject: | Re: misleading error message in 8.5, and bad (?) way deferred uniqueness works |
Date: | 2009-08-11 19:20:23 |
Message-ID: | 8e2dbb700908111220u73a93f63habb0c3b6017a6a4c@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-bugs |
2009/8/11 Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>:
> Anyway it's looking like a slightly nontrivial project. Maybe we should
> just rephrase the error message Hubert is complaining about.
>
Yeah, I can't think of any simple way of distinguishing the 2 error
conditions in that code. Perhaps adding a suitable hint would help, as
well as re-wording the error message:
ERROR: deferrable constraint "foo" does not exist
HINT: You must specify the name of a constraint declared with the
DEFERRABLE option.
- Dean