Re: Review: Non-inheritable check constraints

Поиск
Список
Период
Сортировка
От Nikhil Sontakke
Тема Re: Review: Non-inheritable check constraints
Дата
Msg-id CANgU5ZcHrm+LvqvPObeJUR8J17C8XPFjpoHyZV30rUNYAceKNQ@mail.gmail.com
обсуждение исходный текст
Ответ на Re: Review: Non-inheritable check constraints  (Robert Haas <robertmhaas@gmail.com>)
Ответы Re: Review: Non-inheritable check constraints  (Robert Haas <robertmhaas@gmail.com>)
Список pgsql-hackers
Hi Robert,

First of all, let me state that this "ONLY" feature has not messed around with existing inheritance semantics. It allows attaching a constraint to any table (which can be part of any hierarchy) without the possibility of it ever playing any part in future or existing inheritance hierarchies. It is specific to that table, period.

It's not just that.  Suppose that C inherits from B which inherits
from A.  We add an "only" constraint to B and a non-"only" constraint
to "A".   Now, what happens in each of the following scenarios?


An example against latest HEAD should help here:

create table A(ff1 int);
create table B () inherits (A);
create table C () inherits (B);

alter table A add constraint Achk check (ff1 > 10);

       The above will attach Achk to A, B and C

alter table only B add constraint Bchk check (ff1 > 0);

      The above will attach Bchk ONLY to table B

1. We drop the constraint from "B" without specifying ONLY.

postgres=# alter table B drop constraint Achk;
ERROR:  cannot drop inherited constraint "achk" of relation "b"

      The above is existing inheritance based behaviour.

Now let's look at the ONLY constraint:

postgres=# alter table B drop constraint Bchk;
ALTER TABLE

     Since this constraint is not part of any hierarchy, it can be removed.

postgres=# alter table only B add constraint bchk check (ff1 > 0);
ALTER TABLE
postgres=# alter table only B drop constraint Bchk;
ALTER TABLE

    So "only" constraints do not need the "only B" qualification to be deleted. They work both ways and can always be deleted without any issues.

2. We drop the constraint from "B" *with* ONLY.


postgres=# alter table only B drop constraint Achk;
ERROR:  cannot drop inherited constraint "achk" of relation "b"

      The above is existing inheritance based behavior. So regardless of ONLY an inherited constraint cannot be removed from the middle of the hierarchy.
 
3. We drop the constraint from "A" without specifying ONLY.

postgres=# alter table A drop constraint Achk;
ALTER TABLE

    This removes the constraint from the entire hierarchy across A, B and C. Again existing inheritance behavior.
 
4. We drop the constraint from "A" *with* ONLY.


postgres=# alter table only A drop constraint Achk;
ALTER TABLE

    This converts the Achk constraints belonging to B into a local one. C still has it as an inherited constraint from B. We can now delete those constraints as per existing inheritance semantics. However I hope the difference between these and ONLY constraints are clear. The Achk constraint associated with B can get inherited in the future whereas "only" constraints will not be.
 
Off the top of my head, I suspect that #1 should be an error;

It's an error for inherited constraints, but not for "only" constraints.
 
#2
should succeed, leaving only the inherited version of the constraint
on B;

Yeah, only constraints removal succeeds, whereas inherited constraints cannot be removed.
 
#3 should remove the constraint from A and leave it on B but I'm
not sure what should happen to C,
 
This removes the entire hierarchy.
 
and I have no clear vision of what
#4 should do.


This removes the constraint from A, but maintains the inheritance relationship between B and C. Again standard existing inheritance semantics.

As a followup question, if we do #2 followed by #4, or #4 followed by
#2, do we end up with the same final state in both cases?


Yeah. #2 is not able to do much really because we do not allow inherited constraints to be removed from the mid of the hierarchy.
 
Here's another scenario.  B inherits from A.  We a constraint to A
using ONLY, and then drop it without ONLY.  Does that work or fail?

The constraint gets added to A and since it is an "only" constraint, its removal both with and without "only A" works just fine.
 
Also, what happens we add matching constraints to B and A, in each
case using ONLY, and then remove the constraint from A without using
ONLY?  Does anything happen to B's constraint?  Why or why not?


Again the key differentiation here is that "only" constraints are bound to that table and wont be inherited ever. So this works just fine.

postgres=# alter table only A add constraint A2chk check (ff1 > 10);
ALTER TABLE
postgres=# alter table only B add constraint A2chk check (ff1 > 10);
ALTER TABLE

Just to be clear, I like the feature.  But I've done some work on this
code before, and it is amazingly easy for to screw it up and end up
with bugs... so I think lots of careful thought is in order.


Agreed. I just tried out the scenarios laid out by you both with and without the committed patch and AFAICS, normal inheritance semantics have been preserved properly even after the commit.

Regards,
Nikhils

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Tom Lane
Дата:
Сообщение: Re: [PATCH] Fix ScalarArrayOpExpr estimation for GIN indexes
Следующее
От: Alexander Korotkov
Дата:
Сообщение: Re: GiST for range types (was Re: Range Types - typo + NULL string constructor)