As funções definidas pelo usuário (UDFs) no PolarDB-X são funções armazenadas baseadas em SQL que estendem a lógica de consulta com computação personalizada.
O PolarDB-X 5.4.16 e versões posteriores oferecem suporte a UDFs.
Funcionamento

Após a criação de uma UDF, o PolarDB-X a persiste no meta center e a carrega nos nós de computação para execução. A execução divide-se conforme o tipo de lógica:
Lógica SQL: enviada ao mecanismo SQL.
Lógica de fluxo de controle: executada no mecanismo PL.
Antes da execução, o sistema registra cada UDF no centro de gerenciamento de funções de runtime. Durante a execução, o uso de memória por consulta segue limites rigorosos.
Pushdown de função
O PolarDB-X verifica o campo SQL DATA ACCESS da UDF para decidir se deve registrá-la nos nós de dados. Apenas UDFs com SQL DATA ACCESS definido como NO SQL são registradas nos nós de dados e podem sofrer pushdown.
Para manter a compatibilidade com MySQL, o PolarDB-X registra as UDFs elegíveis para pushdown na biblioteca MySQL do nó de dados.
Não é possível modificar o campo SQL DATA ACCESS , pois ele controla a lógica de pushdown da UDF.
Pushdown após dimensionamento
Após o dimensionamento, execute pushdown udf para registrar as UDFs elegíveis para pushdown no novo nó de dados (DN).
Diferenças em relação ao MySQL
As UDFs do PolarDB-X diferem das funções armazenadas do MySQL em três aspectos:
|
Diferença |
MySQL |
PolarDB-X |
|
Operações suportadas |
DQL, DML, DDL |
Apenas DQL — não há suporte para DML e DDL dentro de uma UDF |
|
Escopo de armazenamento |
Nível de banco de dados |
Nível de instância |
|
Campo |
Modificável com |
Imutável — controla o comportamento de pushdown |
Sintaxe
Crie uma UDF
CREATE
[DEFINER = user]
FUNCTION sp_name ([func_parameter[,...]])
RETURNS type
[characteristic ...] routine_body
func_parameter:
param_name type
characteristic:
COMMENT 'string'
| LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
routine_body:
Valid SQL routine statement
Principais características:
|
Característica |
Descrição |
|||
|
|
Marca a função como determinística: mesmas entradas sempre retornam a mesma saída. Use |
|||
|
|
|
|
|
Defina o campo |
|
|
INVOKER` |
Determina se a função executa com os privilégios do criador ( |
Exemplo:
CREATE FUNCTION my_mul(x int, y int)
RETURNS int
LANGUAGE SQL
DETERMINISTIC
COMMENT 'my multiply function'
RETURN x*y*31;
Chamar uma UDF
Chame uma UDF da mesma forma que uma função integrada:
SELECT my_mul(2, 2);
+--------------+
| my_mul(2, 2) |
+--------------+
| 124 |
+--------------+
Modifique uma UDF
O comando ALTER FUNCTION permite modificar COMMENT, LANGUAGE SQL e SQL SECURITY. Ele não suporta a alteração de SQL DATA ACCESS.
ALTER FUNCTION func_name [characteristic ...]
characteristic: {
COMMENT 'string'
| LANGUAGE SQL
| SQL SECURITY { DEFINER | INVOKER }
}
Exclua uma UDF
DROP FUNCTION [IF EXISTS] FUNCTION_NAME;
Visualize UDFs
Visualize todas as UDFs:
SELECT * FROM information_schema.Routines WHERE ROUTINE_TYPE = 'FUNCTION';
Visualize uma UDF específica:
SHOW FUNCTION STATUS [LIKE 'pattern' | WHERE expr]
SHOW CREATE FUNCTION function_name;
SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME = 'function_name';
Visualize UDFs com pushdown:
SELECT * FROM information_schema.pushed_function;
Cancele uma UDF em execução
Execute a instrução KILL para encerrar uma consulta que esteja executando uma UDF:
KILL {QUERY | CONNECTION} connection_id;
Gerenciamento de cache
Os metadados da UDF (existência da função) residem sempre no cache. O corpo da função é carregado sob demanda, apenas na primeira chamada.
Comandos de cache
|
Comando |
Descrição |
|
|
Lista as UDFs em cache e seus tamanhos carregados |
|
|
Exibe o tamanho de cache utilizado e total por nó |
|
|
Defina o tamanho do cache |
|
|
Limpa o cache |
|
|
Recarrega todas as UDFs e redefine o cache |
Exemplo de ciclo de vida do cache
O exemplo a seguir demonstra todo o ciclo de vida do cache para my_mul.
-- Create the UDF.
CREATE FUNCTION my_mul(x int, y int)
RETURNS int
LANGUAGE SQL
DETERMINISTIC
COMMENT 'my multiply function'
RETURN x*y*31;
-- The function exists in cache, but the body is not loaded yet (SIZE = 0).
SELECT * FROM information_schema.function_cache;
+--------------------+--------------+------+
| ID | FUNCTION | SIZE |
+--------------------+--------------+------+
| xx.xx.xx.xx:3000 | mysql.my_mul | 0 |
| yy.yy.yy.yy:3100 | mysql.my_mul | 0 |
+--------------------+--------------+------+
-- Call the UDF. This triggers the function body to load on one node.
SELECT my_mul(2, 2);
+--------------+
| my_mul(2, 2) |
+--------------+
| 124 |
+--------------+
-- The body is now loaded on the node that executed the call (SIZE = 79).
SELECT * FROM information_schema.function_cache;
+--------------------+--------------+------+
| ID | FUNCTION | SIZE |
+--------------------+--------------+------+
| xx.xx.xx.xx:3000 | mysql.my_mul | 0 |
| yy.yy.yy.yy:3100 | mysql.my_mul | 79 |
+--------------------+--------------+------+
SELECT * FROM information_schema.function_cache_capacity;
+--------------------+-----------+-------------+
| ID | USED_SIZE | TOTAL_SIZE |
+--------------------+-----------+-------------+
| xx.xx.xx.xx:3000 | 0 | 15139759718 |
| yy.yy.yy.yy:3100 | 79 | 15139759718 |
+--------------------+-----------+-------------+
-- Reload the UDF to reset the cache on all nodes.
RELOAD FUNCTIONS;
-- All nodes show SIZE = 0 again.
SELECT * FROM information_schema.function_cache;
+--------------------+--------------+------+
| ID | FUNCTION | SIZE |
+--------------------+--------------+------+
| xx.xx.xx.xx:3000 | mysql.my_mul | 0 |
| yy.yy.yy.yy:3100 | mysql.my_mul | 0 |
+--------------------+--------------+------+
Gerenciamento de recursos
Limites de memória
Durante a execução da UDF, os cursores consomem a maior parte da memória. Use os parâmetros abaixo para definir limites de memória:
|
Parâmetro |
Descrição |
|
|
Memória máxima para um único cursor. Se ultrapassado, os dados transbordam para o disco. Defina no mínimo 128 KB (131072). |
|
|
Memória máxima para uma UDF. Deve ser maior ou igual a |
A memória destinada a toda a consulta que chama a UDF também possui limitação.
Limite de profundidade de chamada
Use o parâmetro MAX_PL_DEPTH para limitar a profundidade de chamadas da UDF. Pilhas de chamadas profundas dificultam a depuração e consomem recursos significativos.