DROP DOMAIN a_year CASCADE; -- a simple domain CREATE DOMAIN a_year AS INTEGER CHECK (VALUE BETWEEN 1 AND 3000); -- ok SELECT 1::a_year; SELECT CAST('2000' AS a_year); -- fails as expected SELECT 0::a_year; CREATE FUNCTION date2year(DATE) RETURNS a_year IMMUTABLE STRICT AS $$ SELECT EXTRACT(YEAR FROM $1)::a_year; $$ LANGUAGE sql; -- ok SELECT date2year(CURRENT_DATE); -- fails as expected SELECT date2year(DATE '3001-01-01'); CREATE CAST (DATE AS a_year) WITH FUNCTION date2year(DATE); -- fails, I would expect 1970 SELECT (DATE '1970-03-20')::a_year; -- fails, I would expect the current year SELECT CURRENT_DATE::a_year; SELECT CAST(CURRENT_DATE AS a_year);