##

CREATE EXTENSION IF NOT EXISTS btree_gist;

ALTER TABLE promotions
ADD CONSTRAINT overlapping_running_time
EXCLUDE USING gist (
  product_id WITH =,
  tsrange("start_at", "end_at", '[)') WITH &&
) WHERE ("status" = 'active');
  |> exclusion_constraint(:start_at,
    name: :overlapping_running_time,
    message: "Discount of product #{product_id} is overlapped"
  )

🚨 Only superuser role has permission to CREATE EXTENSION.