postgresql: enum and character varying, updating

前端 未结 3 1649
孤城傲影
孤城傲影 2021-01-06 17:17

I have the ENUM type in postgresql

CREATE TYPE user_state AS ENUM (\'unconfirmed\', \'locked\', \'active\');
<         


        
相关标签:
3条回答
  • 2021-01-06 17:37

    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.

    0 讨论(0)
  • 2021-01-06 17:57

    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;
    
    0 讨论(0)
  • 2021-01-06 17:57

    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;
    
    0 讨论(0)
提交回复
热议问题