Como podemos passar o agrupamento para uma função definida pelo usuário?
por exemplo, eu posso usar um agrupamento codificado (por exemplo "de-AT-x-icu"
) assim:
CREATE OR REPLACE FUNCTION test(agg_1 jsonb, agg_2 jsonb) RETURNS jsonb
LANGUAGE SQL
AS
$$
SELECT jsonb_build_object(
'count', (agg_1 -> 'count')::int8 + (agg_2 -> 'count')::int8
, 'max', greatest(agg_1 ->> 'max' collate "de-AT-x-icu", agg_2 ->> 'max' collate "de-AT-x-icu")
)
$$;
e o teste funciona:
select test(
jsonb_build_object('count', 2 , 'max', 'H'),
jsonb_build_object('count', 0, 'max', 'i')
);
Tentamos usar um argumento-texto,
CREATE OR REPLACE FUNCTION test2(agg_1 jsonb, agg_2 jsonb, text_collation text) RETURNS jsonb
LANGUAGE SQL
AS
$$
SELECT jsonb_build_object(
'count', (agg_1 -> 'count')::int8 + (agg_2 -> 'count')::int8
, 'max', greatest(agg_1 ->> 'max' collate text_collation, agg_2 ->> 'max' collate text_collation)
)
$$;
mas isso falha com:
ERROR: collation "text_collation" for encoding "UTF8" does not exist
Qual é a melhor maneira de passar/usar um agrupamento em uma UDF nesse caso?
Os agrupamentos são objetos de banco de dados, portanto, seu nome é um identificador.
Você não pode usar um parâmetro para um identificador, você teria que usar SQL dinâmico em uma função PL/pgSQL:
graças à resposta de @Laurenz Albe, criei uma versão funcional:
Exemplo de chamadas:
No entanto, lembre-se de que criar dinamicamente a consulta para cada chamada de função afetará o desempenho.
Como alternativa, consideramos codificar algumas localidades - ou talvez até usar apenas a
und-x-icu
localidade (consulte 23.2.2.2.2. Agrupamentos ICU nos postgres-docs ):