CREATE OR REPLACE FUNCTION enum_array_to_bitmask(anyarray)
RETURNS bigint AS $$
DECLARE
    result bigint := 0;
    val text;
    enum_vals text[];
    i int;
BEGIN
    -- Get all possible values of the enum type
    EXECUTE format('SELECT enum_range(NULL::%s)', pg_typeof($1[1])::text) INTO enum_vals;

    -- Loop through input array and compute the bitmask
    FOREACH val IN ARRAY $1 LOOP
        FOR i IN 1 .. array_length(enum_vals, 1) LOOP
            IF enum_vals[i] = val THEN
                result := result + (1::bigint << (i - 1));
                EXIT;
            END IF;
        END LOOP;
    END LOOP;

    RETURN result;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
--> statement-breakpoint
CREATE OR REPLACE FUNCTION enum_to_bitmask(anyenum)
RETURNS bigint AS $$
DECLARE
    enum_vals text[];
    val text := $1::text;
    i int;
BEGIN
    -- Get all possible enum values of the input type
    EXECUTE format('SELECT enum_range(NULL::%s)', pg_typeof($1)::text) INTO enum_vals;

    -- Find the position of the value
    FOR i IN 1 .. array_length(enum_vals, 1) LOOP
        IF enum_vals[i] = val THEN
            RETURN i;
        END IF;
    END LOOP;

    -- If not found return 0
    RETURN 0;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
