There are some situations where I would like to set up some constraints in a table that depend on values in another table.
For example, I can define two tables as:
CREATE TABLE foo (
foo_id serial PRIMARY KEY,
max_bar integer
);
CREATE TABLE bar (
foo_id integer REFERENCES foo(foo_id),
bar_id integer CHECK (bar_id >= 0),
PRIMARY KEY (foo_id, bar_id)
);
I would like to go a little further to ensure that all bar.bar_id values are lower that the “corresponding” foo.max_bar.
Is there a way I can set up such a constraint?
To go a little further, I’ve found that an EXCLUDE constraint using a GiST index is a great way to set up UNIQUE-like (but more generic) constraints. For example I can define the following tables:
CREATE TABLE foo (
foo_id integer NOT NULL,
foo_validity tstzrange NOT NULL,
EXCLUDE USING gist (foo_id WITH =, foo_validity WITH &&)
);
CREATE TABLE bar (
foo_id integer NOT NULL,
bar_validity tstzrange NOT NULL,
EXCLUDE USING gist (foo_id WITH =, bar_validity WITH &&)
);
Then I would like each row in bar to reference a row in foo with foo.foo_id = bar.foo_id AND foo.foo_validity @> bar.bar_validity. It looks to me like it should be feasible with gist indices, but I can’t find a syntax to declare such a constraint…
foo.max_barin tablebar. This would require anASSERTIONwhich is a generalization ofCHECKconstraint, but not yet implemented. The only thing that could work now is if you addmax_barin bar as well and modify the FK to include both columns. – ypercubeᵀᴹ Sep 25 '20 at 14:56CREATE ASSERTION; I did not know about that. Looks powerful but complex to implement (especially where performance is needed). Your proposal to addmax_barinbaris an interesting idea, but it looks quite hackish to me, and would make it more complex to change its value in thefootable… – user2233709 Sep 25 '20 at 15:20NOT VALID)CHECKconstraint in both tables, each making use of a fake immutable function like outlined in the last chapter of this related answer: https://dba.stackexchange.com/a/124019/3684. It's not safe against concurrent writes, though. (Don't have time to flesh it out ATM.) – Erwin Brandstetter Sep 25 '20 at 22:47foo) to prevent removal (or modification) of a tuple that is referred by the other table (bar)… Any hint? – user2233709 Sep 28 '20 at 09:45