2

Given two integers, start and end, and a foreign key, how do I define a unique constraint on the interval start:end inclusive, and the foreign_key

Given I have the following entries in my table:

+-------+-----+--------------------------------------+
| start | end | foreign_key                          |
+-------+-----+--------------------------------------+
| 10    | 20  | 04ef8258-917c-46d6-8db3-9c704d3f4fbd |
+-------+-----+--------------------------------------+
| 40    | 60  | 04ef8258-917c-46d6-8db3-9c704d3f4fbd |
+-------+-----+--------------------------------------+

Then, the following inserts should fail:

+-------+-----+--------------------------------------+
| start | end | foreign_key                          |
+-------+-----+--------------------------------------+
| 30    | 50  | 04ef8258-917c-46d6-8db3-9c704d3f4fbd |
+-------+-----+--------------------------------------+
| 12    | 18  | 04ef8258-917c-46d6-8db3-9c704d3f4fbd |
+-------+-----+--------------------------------------+

What I have tried thus far:

alter table some_table
  add constraint unique_interval_to_foreign_key_constraint
    unique (start, end, foreign_key)

This does not work as it only defines the unique constraint on discrete points and the foreign key, and not the range.

Any help would be appreciated.

5
  • you might be able to use a CHECK constraint with a subquery checking that no records exist overlapping the range, i.e., stackoverflow.com/a/13000715/8887313. Not sure that this is the most efficient way or even whether it will work... Commented Jul 13, 2020 at 16:41
  • 3
    Please see this solution: dba.stackexchange.com/a/110583/211987 Commented Jul 13, 2020 at 16:45
  • 2
    You want an exclusion constraint Commented Jul 13, 2020 at 16:46
  • Thank you for pointing me in the right direction Commented Jul 13, 2020 at 17:00
  • Additional question: How would I query such a table with the exclusion constraint i.e. how do I handle the ON CONFLICT UPDATE RETURNINg id case? Commented Jul 13, 2020 at 17:53

1 Answer 1

4

Adding answer for completeness:

CREATE EXTENSION btree_gist;

ALTER TABLE some_table
    ADD CONSTRAINT unique_interval_to_foreign_key_constraint
        EXCLUDE USING gist
        (foreign_key WITH =,
         int4range(start, end, '[]') WITH &&
        );
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.