Sample Header Ad - 728x90

Ensure only one association record with future expiry date in Postgres

3 votes
3 answers
83 views
#### The Schema Say I have the following:
table user
id bigint

table promo_codes
user_id bigint
code string
expires_at datetime NOT NULL
invalidated_at datetime
#### The Need Each user can have only one promo code that expires in the future AND is not deactivated, i.e expires_at > NOW() AND invalidated_at IS NULL #### What I tried 1. I tried adding a partial unique index:
CREATE UNIQUE INDEX only_one_active_promo
ON promo_codes (user_id)
WHERE expires_at > NOW() AND invalidated_at IS NULL
but got: > PG::InvalidObjectDefinition: ERROR: functions in index predicate must be marked IMMUTABLE That's because NOW(), CURRENT_TIMESTAMP and pretty much any other date/time function I'm aware of is STABLE at best but none of them is IMMUTABLE which is a requirement for creating an index. 2. I looked into adding a check constraint instead. It's okay if the check is only done during promo_code creation, but I didn't figure out how to do that. 3. Rules is another option that I considered but I have too little knowledge there and am not sure this is the right path actually. 4. At the time of writing this question I'm looking into exclusion constraints which is totally new to me. Using Postgres 16.3
Asked by Tamer Shlash (145 rep)
May 25, 2025, 03:54 PM
Last activity: May 27, 2025, 11:43 PM