Thread: Can't use subselect in check constraint

Can't use subselect in check constraint

From
"Ian Harding"
Date:
Is this something that will change anytime soon?  I could not find anything about it in the todo...

Thanks!

Ian A. Harding
Programmer/Analyst II
Tacoma-Pierce County Health Department
(253) 798-3549
mailto: iharding@tpchd.org


Re: Can't use subselect in check constraint

From
Bruce Momjian
Date:
> Is this something that will change anytime soon?  I could not find anything about it in the todo...

My understanding is that check constraints can't be queries;  at least I
have never seen them.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Re: Can't use subselect in check constraint

From
Tom Lane
Date:
"Ian Harding" <ianh@tpchd.org> writes:
> Is this something that will change anytime soon?

It's not high-priority in my mind.  The difficulty is the lack of a
planning step for constraint expressions.  Maybe we could fix this
when we redesign querytrees; right now I think there's too much cruft
in the way (memory leaks, state kept in the querytree, etc etc)

            regards, tom lane

Re: Can't use subselect in check constraint

From
Stephan Szabo
Date:
On Wed, 19 Dec 2001, Tom Lane wrote:

> "Ian Harding" <ianh@tpchd.org> writes:
> > Is this something that will change anytime soon?
>
> It's not high-priority in my mind.  The difficulty is the lack of a
> planning step for constraint expressions.  Maybe we could fix this
> when we redesign querytrees; right now I think there's too much cruft
> in the way (memory leaks, state kept in the querytree, etc etc)

Also, AFAICS, check constraints with subselects are constraints on the
other tables named in the subselect as well and it could be on a
case which the current check constraints don't fire (for example
on delete from a table where a set value function is used, like
check (select count(*) from foo)>col1) or something like that).



Re: Can't use subselect in check constraint

From
"Gregory Wood"
Date:
> > Is this something that will change anytime soon?  I could not find
anything about it in the todo...
>
> My understanding is that check constraints can't be queries;  at least I
> have never seen them.

Considering that you could potentially have to reevaluate each CHECK
constraint every time you updated any table in the database, I would think
it would be a *real* bad idea to allow that. There is no way to
automatically create the triggers needed to satisfy "When should I check the
constraint?"

If it can't be constructed as a check against a literal value or values, or
a foreign key constraint, it should be up to the user to maintain that
consistency check with the appropriate triggers.

Greg


Re: Can't use subselect in check constraint

From
Bruce Momjian
Date:
>
> On Wed, 19 Dec 2001, Tom Lane wrote:
>
> > "Ian Harding" <ianh@tpchd.org> writes:
> > > Is this something that will change anytime soon?
> >
> > It's not high-priority in my mind.  The difficulty is the lack of a
> > planning step for constraint expressions.  Maybe we could fix this
> > when we redesign querytrees; right now I think there's too much cruft
> > in the way (memory leaks, state kept in the querytree, etc etc)
>
> Also, AFAICS, check constraints with subselects are constraints on the
> other tables named in the subselect as well and it could be on a
> case which the current check constraints don't fire (for example
> on delete from a table where a set value function is used, like
> check (select count(*) from foo)>col1) or something like that).

It this a TODO item.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Re: Can't use subselect in check constraint

From
"Gregory Wood"
Date:
> I assumed check constraints are checked on insert/update, so they would
not need to be re-checked when the tables referenced in the check constraint
were updated If people could live with that, then it seems that it would be
possible.

Well, if you work with the assumption that a constraint is used to guarantee
some sort of consistency, then checking on insert/update wouldn't work. If
you modify the values in the underlying check constraint, you could end up
with an inconsistent state in the database.

Take for example a foreign key... when you insert a record into table B
which has a foreign key into table A, the constraint is checked to insure
that the value in B is also in A. Now you delete that value from A.
According to how the tables were designed, the foreign key value should
either prevent the deletion in A, NULL the foreign key value in B, or set
the foreign key value to a default value. Otherwise, the deletion from A
would create an inconsistent database (an orphaned foreign key).

Foreign keys solve this by creating not only triggers on the table with the
foreign key, but the table referenced by the foreign key. The problem with
doing this for subqueries in a check constraint is that you have to figure
out which tables need these new triggers. What's makes it nigh impossible is
that you can use a function in a subquery, and that function can reference
still more tables. I would say the only good way to implement this would be
for the one who designed the database to create the appropriate triggers to
maintain a consistent state.

> However, it seems like this is the system telling me what I am trying to
do is a bad idea.  I have put a bunch of validation codes in one table with
descriptive names so I don't have to have a whole bunch of little tables for
validation codes.

A lookup table then... not a bad idea.

> Different types of codes may have the same value, so I can't have a unique
index on the code, although I do have one on the type+code combination.  I
thought I could use a check with a subselect so codes could be added in the
future without dropping and reloading the table.

Is the type in the validation codes lookup table, or in the table that you
want the check constraint on? If so, you can just do a foreign key that
references both columns (codetype and codecol).

> Come to think of it, I wonder if I couldn't just to a foreign key
relationship like:
> constraint thistable_fkey foreign key ('codetype', codecol) references
mycodetable (codetype, codecol)
> Can you use a constant in a foreign key?

Hmmm, I don't know if you can use a constant in a foreign key, but there's
nothing preventing you from creating a table with constant values (you can
even add some triggers to keep them constant). But ideally, your validation
codes table would have type and code columns that can be used for a foreign
key.

Greg