I have the ENUM type in postgresql
CREATE TYPE user_state AS ENUM (\'unconfirmed\', \'locked\', \'active\');
<
Alternatively you may register equal operator instead of define cast
one. I did it for Java
+ MyBatis
in similar situation:
CREATE FUNCTION type_user_state_with_text_equals(_a user_state, _b text)
RETURNS boolean AS
$func$
SELECT _a = _b::user_state;
$func$
LANGUAGE SQL IMMUTABLE STRICT;
CREATE OPERATOR = (
leftarg = user_state,
rightarg = text,
procedure = type_user_state_with_text_equals,
COMMUTATOR = =,
NEGATOR = !=,
HASHES, MERGES
);
You may read about postgres user-defined operations in documentation and do not forget look at optimization hints.
The problem with a simple attempt is you have a cast calling the cast, calling the cast, calling the cast...
You need somehow to get away from varchar->enum in your cast. Simplest (most understandable) way is to just manually convert. Note the string literals being cast in the case statement aren't text they are quoted-unknown-type which sidesteps the infinite recursion.
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;
Very late to the party here, but I would like to add that in this specific case it is enough to simply cast the varchar
to text
to prevent recursion.
CREATE FUNCTION dummy_cast(varchar) RETURNS t_tl AS $$
SELECT ('' || $1)::t_tl;
$$ LANGUAGE SQL;