-- migrate:up -- A reservation names either a unit we know (Whiskey group, `unit_id`) or a -- free text the requester typed (`unit_label`). Typing a name must never create -- a `units` row, so the two are exclusive rather than the second being a -- fallback name for the first. ALTER TABLE reservations ALTER COLUMN unit_id DROP NOT NULL; ALTER TABLE reservations ADD COLUMN unit_label TEXT; ALTER TABLE reservations ADD CONSTRAINT reservations_unit_xor CHECK ( (unit_id IS NULL) <> (unit_label IS NULL) ); -- A free label is a name, not an empty string ALTER TABLE reservations ADD CONSTRAINT reservations_unit_label_not_blank CHECK ( unit_label IS NULL OR btrim(unit_label) <> '' ); -- migrate:down ALTER TABLE reservations DROP CONSTRAINT reservations_unit_label_not_blank; ALTER TABLE reservations DROP CONSTRAINT reservations_unit_xor; -- The rows that only had a free label have no unit to point at any more DELETE FROM reservations WHERE unit_id IS NULL; ALTER TABLE reservations DROP COLUMN unit_label; ALTER TABLE reservations ALTER COLUMN unit_id SET NOT NULL;