A partir da versão V3.1, o Hologres oferece suporte a chamadas remotas para funções definidas pelo usuário no Function Compute (FC), permitindo processar lógicas de negócios complexas ou executar operações avançadas de dados. Este tópico descreve como utilizar Remote UDFs no Hologres.
Visão geral
As funções remotas ampliam as capacidades de processamento e análise de dados do Hologres ao integrar funções externas de serviços como o Alibaba Cloud Function Compute (FC). Essa integração permite chamar dinamicamente funções do FC durante consultas aos dados do Hologres para processar lógicas de negócios complexas ou executar operações avançadas.
Funções remotas atendem aos seguintes casos de uso:
Processamento de dados em tempo real: invoque funções externas durante consultas para limpar dados, converter formatos ou realizar cálculos complexos.
Integração com serviços de terceiros: utilize o Function Compute para interagir com outros serviços da Alibaba Cloud ou APIs externas usando seus dados do Hologres.
Análises avançadas: execute algoritmos sofisticados no Function Compute, como inferência de modelos e machine learning, e grave os resultados diretamente no Hologres.
Pré-requisitos
Tenha uma instância do Hologres na versão V3.1 ou superior. Para mais informações, consulte Comprar uma instância do Hologres.
Ative o Function Compute e utilize uma instância V3.0. Para ativar o serviço, faça login no console do Function Compute.
-
Autorize a função vinculada ao serviço
AliyunServiceRoleForHologresRemoteUDF.Faça login no console do Hologres. No painel de navegação à esquerda, clique em Create a Service-linked Role.
Selecione
AliyunServiceRoleForHologresRemoteUDFe clique em Authorize Now.
A instância do Hologres e o serviço Function Compute devem estar na mesma região.
Ative o Alibaba Cloud Function Compute, desenvolva e implante a função que o Hologres chamará. Para detalhes, consulte Visão geral do desenvolvimento de código.
Limitações
O Hologres oferece suporte apenas a UDFs escalares e funções com valor de tabela definidas pelo usuário (UDTFs). Funções agregadas definidas pelo usuário (UDAFs) não são suportadas.
Apenas os seguintes tipos de dados e seus respectivos tipos de array são aceitos:
BOOLEAN,INTEGER,BIGINT,REAL,DOUBLE PRECISIONeTEXT.Funções remotas não aceitam parâmetros de entrada constantes.
Este recurso gera custos no Function Compute (FC). Para mais informações, consulte Faturamento.
Não há custos adicionais no Hologres para o uso deste recurso.
-
Remote UDFs só podem ser executadas no mecanismo de consulta do Hologres (HQE). Elas não podem ser usadas na mesma instrução SQL com funções internas exclusivas do mecanismo de consulta compatível com PostgreSQL (PQE), como as funções da extensão de criptografia e descriptografia (PGCRYPTO). O uso combinado causa conflito de execução entre mecanismos e retorna o seguinte erro.
ERROR: ORCA failed to produce a plan : No plan has been computed for required propertiesPara usar uma Remote UDF e uma função interna exclusiva do PQE simultaneamente, divida as operações em instruções SQL separadas e execute-as individualmente.
Gerencie Remote UDFs
Crie uma extensão
Para utilizar funções remotas, crie primeiro uma extensão executando o seguinte comando:
CREATE EXTENSION [ IF NOT EXISTS ] function_compute;
Crie uma função
Sintaxe
CREATE [ OR REPLACE ] FUNCTION <function_name>
( [ [ argmode ] [ argname ] <argtype> [ { DEFAULT | = } default_expr ] [, ...] ] )
[ RETURNS [SETOF] rettype | RETURNS TABLE ( column_name column_type) ]
LANGUAGE function_compute
AS '<fc_endpoint>/<func_name>'
{
{ CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
| SET function_compute.qualifier TO <qualifier>
| SET function_compute.compression TO <compression>
| SET function_compute.max_batch_size TO <max_batch_size>
} ...
Parâmetros
|
Categoria |
Parâmetro |
Obrigatório |
Descrição |
|
Nome da função |
function_name |
Sim |
Nome da função.
|
|
Parâmetros da função |
argtype |
Sim |
Tipo de dados do parâmetro. |
|
argmode |
Não |
Valores válidos: IN, OUT e INOUT. O padrão é IN. Para evitar ambiguidades, recomenda-se não utilizar INOUT. Uma função pode ter apenas um parâmetro OUT ou INOUT. |
|
|
argname |
Não |
Nome do parâmetro.
|
|
|
default_expr |
Não |
Valor padrão. Aplica-se apenas a parâmetros de entrada. Se um parâmetro tiver valor padrão, todos os parâmetros subsequentes também deverão ter valores padrão. |
|
|
Endpoint do FC |
LANGUAGE function_compute |
Sim |
Especifica que a função utiliza o serviço Function Compute. |
|
fc_endpoint |
Sim |
Endpoint interno do Function Compute. Para mais informações, consulte Endpoints. |
|
|
func_name |
Sim |
Nome da função alvo, que deve ser criada previamente no console do Function Compute. |
|
|
Tipo de retorno |
rettype |
Não |
Tipo de dados do valor de retorno. Se utilizar parâmetros OUT ou INOUT, a cláusula RETURNS pode ser omitida. Caso especificada, essa cláusula deve ser consistente com o tipo de resultado implícito nos parâmetros de saída. |
|
column_name |
Não |
Na sintaxe RETURNS TABLE, representa o nome de uma coluna de saída. Trata-se de outra forma de declarar parâmetros OUT nomeados. A diferença é que RETURNS TABLE também implica RETURNS SETOF, indicando que a função retorna um conjunto. |
|
|
column_type |
Não |
Na sintaxe RETURNS TABLE, representa o tipo de dados de uma coluna de saída. |
|
|
Política de tratamento de nulos |
CALLED ON NULL INPUT |
Não |
Comportamento padrão. A função é chamada mesmo quando há entradas NULL e deve tratar a lógica de nulos internamente. |
|
RETURNS NULL ON NULL INPUT |
Não |
Retorna NULL imediatamente se qualquer entrada for NULL. |
|
|
STRICT |
Não |
Um alias para RETURNS NULL ON NULL INPUT. |
|
|
Controle de versão da função |
qualifier |
Não |
Especifica a versão ou alias da função a ser chamada. O valor padrão é |
|
Algoritmo de compressão de requisição |
compression |
Não |
Define o algoritmo de compressão para a requisição e resposta da chamada da função. Valores válidos:
|
|
Tamanho máximo do lote por requisição |
max_batch_size |
Não |
Define o número máximo de linhas a serem enviadas ao FC em cada lote. Utilize esta configuração para limitar o tamanho do lote em funções do FC que possuem restrições de memória ou outros limites. Se este parâmetro não for especificado, o Hologres calcula automaticamente o tamanho ideal de lote. Na maioria dos casos, não é necessário definir este parâmetro. |
Exemplos
-
Crie uma UDF escalar.
CREATE OR REPLACE FUNCTION rf_add ( a INTEGER, b INTEGER DEFAULT 1 ) RETURNS BIGINT LANGUAGE function_compute AS 'xxxxxxxxxxxxx.cn-shanghai-internal.fc.aliyuncs.com/add' ; -
Crie uma UDTF.
-- Method 1 CREATE OR REPLACE FUNCTION rf_unnest(TEXT []) RETURNS TABLE (item TEXT ) LANGUAGE function_compute AS 'xxxxxxxxxxxxxx.cn-hangzhou-internal.fc.aliyuncs.com/unnest' STRICT SET function_compute.max_batch_size TO 1024; -- Method 2 CREATE OR REPLACE FUNCTION rf_unnest(TEXT []) RETURNS SETOF TEXT LANGUAGE function_compute AS 'xxxxxxxxxxxxxx.cn-hangzhou-internal.fc.aliyuncs.com/unnest' STRICT SET function_compute.max_batch_size TO 1024;
Visualize funções
Visualize as funções remotas criadas.
SELECT
CASE
WHEN p.proretset = 'f' THEN 'scalar UDF'
WHEN p.proretset = 't' THEN 'UDTF'
END AS function_type,
n.nspname AS schema_name,
p.proname AS function_name,
pg_get_function_arguments(p.oid) AS arguments,
pg_get_function_result(p.oid) AS return_type,
p.proisstrict AS is_strict,
p.proconfig AS config,
pg_get_functiondef(p.oid) AS definition
FROM
pg_proc p
JOIN pg_language l ON p.prolang = l.oid
JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE
l.lanname = 'function_compute'
AND p.prokind != 'p'
ORDER BY
function_type,
schema_name,
function_name;
Exclua uma função
Sintaxe
DROP FUNCTION [ IF EXISTS ] <function_name> [ ( [ [ argmode ] [ argname ] <argtype> [, ...] ] ) ] [, ...]
Parâmetros
|
Parâmetro |
Obrigatório |
Descrição |
|
function_name |
Sim |
Nome da função a ser excluída. |
|
argtype |
Sim |
Tipo de dados do parâmetro. |
|
argmode |
Não |
Valores válidos: IN, OUT e INOUT. O padrão é IN. Para evitar ambiguidades, recomenda-se não utilizar INOUT. Uma função pode ter apenas um parâmetro OUT ou INOUT. |
|
argname |
Não |
Nome do parâmetro. Para parâmetros de entrada, o nome serve apenas para fins de documentação. Para parâmetros de saída, o nome define o nome da coluna no conjunto de resultados. Se omitido, o sistema gera um nome padrão. |
Exemplo
DROP FUNCTION rf_add(INTEGER, INTEGER);
Formato de troca de dados
Formato da requisição: Hologres para FC
O Hologres chama a API InvokeFunction do Function Compute enviando uma requisição POST. O corpo da requisição é um objeto JSON contendo uma única chave chamada data. Seu valor é um array bidimensional, onde cada array interno representa uma linha de dados no lote e contém os parâmetros para a chamada da função.
Regras de serialização de dados
BOOLEANé serializado como um booleano JSON.INTEGEReBIGINTsão serializados como números JSON.REALeDOUBLE PRECISIONsão serializados como números JSON.TEXTé serializado como uma string JSON.Um valor SQL
NULLé serializado comonullem JSON.
Exemplo
O código abaixo mostra um exemplo de requisição serializada para uma função remota com a assinatura rf_demo(TEXT, INTEGER, BOOLEAN).
{
"data": [
["foo", 100, true],
[null, null, false],
["bar", 200, false]
]
}
Formato da resposta: FC para Hologres
Após processar um lote de dados, o Function Compute deve retornar os resultados ao Hologres no formato JSON conforme descrito abaixo:
-
UDF Escalar
O objeto de nível superior deve conter um campo
results. Seu valor deve ser um array, onde cada elemento corresponde ao resultado de uma linha de dados de entrada.O resultado de cada linha deve ser um array, e a ordem dos resultados deve corresponder à ordem das linhas de entrada. Por exemplo, o enésimo elemento no array de resultados corresponde à enésima linha de entrada.
O código a seguir apresenta um exemplo de resposta para um lote de quatro linhas:
{ "results": [ ["Beijing"], ["Shanghai"], ["Shenzhen"], ["Guangzhou"] ] } -
Uma função com valor de tabela definida pelo usuário (UDTF) aceita entrada de linha única para gerar saída de múltiplas linhas. Um número de linha (row_num) é necessário para identificar a relação com a linha de entrada original.
O objeto de nível superior deve conter um campo
results. Seu valor deve ser um array, onde cada elemento corresponde a uma linha de dados de saída.-
O resultado de cada linha deve ser um array contendo dois elementos:
row_num(primeiro elemento): Índice baseado em zero da linha de entrada original, usado para associar entrada e saída. Os valores de row_num devem ser retornados em ordem crescente.result (segundo elemento): Valor de uma única linha de saída.
Exemplo:
{ "results": [ [0, "Beijing"], [1, "Shanghai"], [3, "Shenzhen"], [3, "Guangzhou"], ] }
Exemplo
Este exemplo utiliza a função unnest.
-
Ative o Function Compute.
Faça login no console do Function Compute. Você também pode solicitar um pacote de recursos gratuito seguindo as instruções na tela. Para mais informações, consulte Free Tier.
-
Crie uma Função de Evento do FC.
No painel de navegação à esquerda, clique em Functions. Mude para a região onde sua instância do Hologres está localizada.
Na página Functions, clique em Create Function. A página Create Function será aberta.
-
Selecione Event Function e configure os parâmetros a seguir. Mantenha as configurações padrão para os demais parâmetros. Para mais informações, consulte Criar uma função acionada por evento.
Parâmetro
Descrição
Nome da função
Um nome personalizado. Por exemplo,
unnest.Runtime
Selecione Built-in Runtimes / Python / Python 3.10.
Método de upload de código
Selecione Upload ZIP.
Pacote de código
Faça o upload do pacote de código.
Salve o código abaixo como unnest.py e compacte-o em um arquivo chamado unnest.zip.
import json def unnest(event, context): evt = json.loads(event) data = evt.get('data', None) if data is None: raise ValueError('no "data" key in event.') if not isinstance(data, list): raise ValueError('data is not a list.') res = list() for i in range(len(data)): if len(data[i]) != 1 or not isinstance(data[i], list): raise ValueError('the item in data is not a list.') for item in data[i][0]: res.append([i, item]) return json.dumps({'results': res})Handler
Insira
unnest.unnest.
-
Crie uma função remota no Hologres.
NotaExecute as etapas a seguir no HoloWeb. Para mais informações, consulte Conectar ao HoloWeb.
CREATE EXTENSION IF NOT EXISTS function_compute; CREATE OR REPLACE FUNCTION rf_unnest(INTEGER []) RETURNS SETOF INTEGER STRICT LANGUAGE function_compute AS 'xxxxxxxxxxxxxxxxx.cn-shanghai-internal.fc.aliyuncs.com/unnest'; -
Prepare os dados de teste.
CREATE TABLE test_array ( numbers INTEGER[] ); INSERT INTO test_array (numbers) VALUES (ARRAY[1, 3]), (ARRAY[2, 4]), ('{}'), (ARRAY[]::INTEGER[]), (NULL); -
Chame a função remota.
SELECT numbers, rf_unnest(numbers) FROM test_array; numbers | rf_unnest ---------+----------- {2,4} | 2 {2,4} | 4 {1,3} | 1 {1,3} | 3 (4 rows)