As the title suggests, what I'm trying is to create an EXCLUDE constraint by concatenating date + time values.
Here is a DB table called bookings:
column name | data type
----------------------
date | date
start_time | time
end_time | time
start_time and end_time aren't timestamp. They are time.
Here's a SQL query:
ALTER TABLE bookings
ADD CONSTRAINT overlapping_times
EXCLUDE USING GIST (
tsrange(date + start_time, date + end_time) WITH &&
)
The purpose for the constraint is to prevent bookings table from having multiple rows with overlapping time ranges on the same date.
tsrange is available for timestamps, not time. So, by following Postgres' doc, I concatenate date and start_time (and end_time). The doc shows the following example:
date + time → timestamp
Add a time-of-day to a date
date '2001-09-28' + time '03:00' → 2001-09-28 03:00:00
However, the SQL above results in:
error: data type integer has no default operator class for access method "gist"
What am I doing wrong?
EDIT
Thank you @Tim Otomagis. It seems that I was using an old version of Postgres which can't create timestamp by date + time
So, by following this, I tried the following:
CREATE EXTENSION btree_gist;
ALTER TABLE bookings
ADD CONSTRAINT overlapping_times
EXCLUDE USING GIST (
tsrange(
CONCAT(date::date || ' ' || start_time::time)::timestamp,
CONCAT(date::date || ' ' || end_time::time)::timestamp
) WITH &&
);
However, this results in:
functions in index expression must be marked IMMUTABLE
EDIT 2
I ended up upgrading Postgres from v12 to v14 to make the original approach work. Thanks again @Tim Otomagis