In Postgres, how do you restrict possible values for a particular column?
Solution 1:
You could add a CHECK CONSTRAINT:
ALTER TABLE distributors
ADD CONSTRAINT check_types
CHECK (element_type = 'lesson' OR element_type = 'quiz');
Although IMO the cleaner option would be to create an ENUM
:
CREATE TYPE element_type AS ENUM ('lesson', 'quiz');
Solution 2:
A shorcut syntax is :
ALTER TABLE distributors
ADD CONSTRAINT check_types
CHECK (element_type IN ('lesson', 'quiz') );
This translates automaticolly to :
CONSTRAINT check_types CHECK (element_type::text = ANY (ARRAY['lesson'::character varying, 'quiz'::character varying) )
Enjoy ;-)
Solution 3:
This trigger throws an exception whenever someone try to insert or update a row with an invalid element_type.
CREATE OR REPLACE FUNCTION check_discussion_element_type() RETURNS TRIGGER AS $$
DECLARE new_element_type varchar(25);
BEGIN
SELECT element_type into new_element_type
FROM discussion
WHERE discussion.element_id = NEW.element_id;
IF new_element_type != 'lesson' AND new_element_type != 'quiz'
THEN RAISE EXCEPTION 'Unexpected discussion type';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
create trigger t_check_discussion_element_type after update or insert on discussion for each row execute procedure check_discussion_element_type();
If you want to remove the hard-coded types you can adapt it to check if the new type exists in a type table.