I am using a postgres with daterange field called valid_period
in thing_thing
table.
The query I use to add the constraint
CREATE EXTENSION IF NOT EXISTS btree_gist;
ALTER TABLE thing_thing
ADD CONSTRAINT prevent_overlapping_valid_periods_by_team
EXCLUDE USING gist(team_id WITH =, valid_period WITH &&)
DEFERRABLE INITIALLY DEFERRED;
This works well.
- row with same
team_id
and overlappingvalid_period
=> blocked - row with different
team_id
and overlappingvalid_period
=> allowed ✅ - row with same
team_id
and NOT overlappingvalid_period
=> allowed ✅
What I need but not sure how to do
But I only want the constraint to kick in IF
- the field
is_removed
(a boolean field) is also false OR - the field
state
(a varchar field) contains one of any possible values such asCANCELLED
,REJECTED
So the following are not working:
- row with same
team_id
and overlappingvalid_period
but existing rowis_removed
is True => expected allowed ✅ but blocked - row with same
team_id
and overlappingvalid_period
but existing rowstate
isCANCELLED
=> expected allowed ✅ but blocked - row with same
team_id
and overlappingvalid_period
but existing rowstate
isREJECTED
=> expected allowed ✅ but blocked
How do I alter the constraints to allow the exceptions? In other words, a bit like partial unique index.
I am a bit pessimistic because I understand there's no such thing as a partial constraint from another SO answer here
But at the same time, I think not possible to use partial unique index to prevent illegal overlapping daterange.