I need to port from Oracle a stored procedure that uses decode() extensively. That is, I can't use series of CASE WHEN expr THEN expr [...] ELSE as the guide suggests.
I wanted to create a variadic function, but here's the problem: in Oracle the function can accept any number of key-value pairs and the type of the key not necessarily matches the type of the value:
select decode(0 ,0,'a' ,1,'b' ,2,'c' /*,...*/ ,'dflt') from dual;
I tried to use anyarray:
create or replace function decode(VARIADIC args anyarray) RETURNS text AS $$
SELECT null::text;
$$ LANGUAGE SQL;
But this only works when all the arguments are of the same type:
select decode(0,0,0); -- ok
select decode('x'::text,'x'::text,'x'::text); -- ok
select decode(0,0,'a'::text); -- No function matches the given name and argument types
If the desired syntax is not possible please advise another way of passing the expr, the set of pairs, and the default value while keeping their positions same as in Oracle.
Limitation
It seems it is how PostgreSQL is implemented. Reading the docs:
JSON
If you find a way to export your mixed array into JSON format from Oracle, then PostgreSQL JSON type will cope with it:
This function accepts a JSON string and it can be like:
Table Type
If the tuple of arguments you want to decode matches a
TABLEtype, then you can use it:Then this call works:
Unfortunately we cannot use the generic
RECORDtype as input argument for a function.Raises:
Type
anyelementAs pointed out by @basin, type
RECORDcan be emulated usinganyelement:Returns: