In one of my projects I have a table that holds information on firmware updates of some sort of device. Initially any firmware update process is in ENQUEUED state. An update process may have other state values, e.g. ONGOING, COMPLETED, FAILED. For a single device multiple rows in state COMPLETED and FAILED may exist (finished update processes, final state!). But at anytime there must only be 1 update process for each device in state ENQUEUED or ONGOING - new firmware rollouts should only be possible for devices that have no 'active/non-final' update processes. I tried to implement this constraint with Postgres' partial indexing but it didn't work as I had expected.
Here's a simplified version of that table:
CREATE TABLE firmware_update_processes
(
id uuid DEFAULT uuid_generate_v1(),
device VARCHAR(10) NOT NULL,
state VARCHAR (10) NOT NULL DEFAULT 'ENQUEUED',
PRIMARY KEY (id)
);
Here's the unique partial index:
CREATE UNIQUE INDEX unique_non_final_firmware_updates_processes
ON firmware_update_processes (device, state)
WHERE state IN ('ENQUEUED', 'ONGOING');
I then validated this constraint but I was still able to insert multiple 'active/non-final' update processes for a given device...
INSERT INTO firmware_update_processes (device, state) VALUES ('device1', 'ENQUEUED');
INSERT INTO firmware_update_processes (device, state) VALUES ('device1', 'ONGOING');
Is there any - maybe other - way to accomplish this on database level ? Any help is appreciated.