Função de criação de caso usando
CREATE OR REPLACE FUNCTION public.icase(
cond1 boolean, res1 anyelement,
cond2 boolean, res2 anyelement,
conddefault anyelement)
RETURNS anyelement LANGUAGE 'sql' IMMUTABLE PARALLEL UNSAFE AS $BODY$
SELECT CASE WHEN $1 THEN $2 WHEN $3 THEN $4 ELSE $5 END;
$BODY$;
select
icase( false, 0, false, 0.,0.)
gera erro
function icase(boolean, integer, boolean, numeric, numeric) does not exist
Como permitir que o icase aceite parâmetros mistos inteiros/numéricos?
De acordo com o link:
https://www.postgresql.org/docs/current/xfunc-sql.html#XFUNC-SQL-POLYMORPHIC-FUNCTIONS
Então:
Que quando executado faz:
Embora, como você pode ver, isso forçará a saída para um tipo comum adequado.
Tipos polimórficos levam a um tipo de dados comum e uniforme.
Anyelement
atuará como um espaço reservado para 4x o mesmo tipo e, se você passar 3 coisas diferentes (a quarta é o tipo de resultado que será ajustado para os 3 parâmetros), ele simplesmente desistirá .Anycompatible
não desistirá, mas tentará converter as 3 coisas diferentes para um tipo comum, se for possível, e somente se houver apenas uma maneira única de converter todas elas. Ele permitirá que você invoque a rotina usando uma mistura de tipos, mas todos eles acabarão convertidos .Sobrecarregue sua função se quiser mais controle (e planeja permanecer na v12):
demonstração em db<>fiddle
Com as 5 definições acima, qualquer uma das 8 combinações possíveis de
int
enumeric
em qualquer uma das 3 posições é resolvida corretamente:Se você quisesse misturar tipos de parâmetros entre diferentes chamadas, não dentro de uma única invocação, sua definição já funcionaria, desde que você usasse conversões de tipo explícitas e uniformes:
demo em db<>fiddle