Я пытаюсь выполнить ограничение PostgreSQL для следующей таблицы:
CREATE TABLE contracts
(
id bigint NOT NULL,
startdate date NOT NULL,
enddate date NOT NULL,
price numeric(19,2) NOT NULL,
deleted boolean NOT NULL,
supplier_id bigint NOT NULL,
)
Содержит контракты для поставщиков с разными ценами. Для данного времени может существовать только один контракт для данного поставщика. Я сделал следующее ограничение, чтобы обеспечить это:
ALTER TABLE contracts ADD CONSTRAINT overlaping_contracts EXCLUDE USING GIST (
supplier_id WITH =,
daterange(startdate, enddate) WITH &&
);
Это гарантирует, что нельзя вставить новый контракт, который пересекается с уже существующим контрактом. Теперь мы также поддерживаем «мягкое удаление» контрактов. Это делает недействительным старый контракт и устанавливает флаг «удаленный» в true. Теперь я хочу вставить новый контракт на тот же период, но это перекрывает срабатывание ограничения.
Я попытался объединить условный индекс unqiue с указанным выше содержимым, но не могу заставить его работать. Документация по исключающим ограничениям довольно мала.
Мой инстинкт подсказывает мне, что я должен добавить что-то вроде
deleted = false
к ограничению исключения, но я не могу найти правильный синтаксис для этого.
Как я могу объединить ограничение исключения с условным уникальным индексом, чтобы я мог применять перекрывающее ограничение только для строк, которые удалили = false?