Проблемът с обикновения опит е, че имате актьорски състав, който се обажда на актьорския състав, вика актьорския състав, вика актьорския състав...
Трябва по някакъв начин да се измъкнете от varchar->enum във вашия актьорски състав. Най-простият (най-разбираем) начин е просто ръчно конвертиране. Обърнете внимание, че низовите литерали, преобразувани в оператора case, не са текст, те са цитирани от неизвестен тип, което заобикаля безкрайната рекурсия.
BEGIN;
CREATE TYPE t_tl AS ENUM ('red', 'amber', 'green');
CREATE FUNCTION dummy_cast(varchar) RETURNS t_tl AS $$
SELECT CASE $1
WHEN 'red' THEN 'red'::t_tl
WHEN 'amber' THEN 'amber'::t_tl
WHEN 'green' THEN 'green'::t_tl
END;
$$ LANGUAGE SQL;
CREATE CAST (varchar AS t_tl) WITH FUNCTION dummy_cast(varchar) AS ASSIGNMENT;
CREATE TABLE t (x t_tl);
INSERT INTO t VALUES ('red');
INSERT INTO t VALUES ('green'::varchar);
SELECT * FROM t;
ROLLBACK;