Postgresql Исключение с мягко удаленными строками

Я пытаюсь выполнить ограничение 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?

1 ответ

Решение

Это должно сделать трюк:

    ALTER TABLE contracts ADD CONSTRAINT overlapping_contracts EXCLUDE USING GIST (
    supplier_id WITH =,
    daterange(startdate, enddate) WITH &&
    ) WHERE (NOT deleted);

Используя эту суть https://gist.github.com/fphilipe/0a2a3d50a9f3834683bf

Другие вопросы по тегам