[+/-]
Para o mecanismo UDF funcionar, as funções devem estar em C ou
C++ e o seu sistema operacional deve suporta carregamento
dinâmico. A distribuição fonte do MySQL inclui um arquivo
sql/udf_example.cc
que definem 5 novas
funções. Consulte este arquivo para ver como a convenção de
chamadas UDF funciona.
Para o mysqld
estar apto a usar funções
UDF, você deve configurar o MySQL com
--with-mysqld-ldflags=-rdynamic
. A razão é
que para muitas plataformas (incluindo Linux) você pode
carregar uma biblioteca (com dlopen()
) de um
programa ligado estaticamente, que você teria se estivesse
usando --with-mysqld-ldflags=-all-static
. Se
você quiser usar uma UDF que precisa acessar símbolos do
mysqld
(como o exemplo
metaphone
em
sql/udf_example.cc
que usa
default_charset_info
), você deve ligar o
programa com -rdynamic
(veja man
dlopen
).
Se você estiver usando uma versão precompilada do servidor, use o MySQL-Max, que suporta carregamento dinâmico.
Para cada função que você deseja usar nas instruções SQL,
você deve definir funções C (ou C++) correspondente. Na
discussão abaixo, o nome ``xxx'' é usado um nome de função
exemplo. Para distinguir entre o uso de SQL e C/C++,
XXX()
(maiúscula) indica a chamada da
função SQL e xxx()
(minúscula) indica da
chamada da função C/C++.
Aa funções C/C++ que você escreve para implemmentar a
interface para XXX()
são:
xxx()
(exigido)
A função principal. É onde o resultado da função é computado. A correspondência entre o tipo SQL e o tipo retornado da sua função C/C++ é mostrada aqui:
Tipo SQL | Tipo C/C++ |
STRING |
char * |
INTEGER |
long long |
REAL |
double |
xxx_init()
(opcional)
A função de inicialização para xxx()
.
Ela pode ser usada para:
Verifica o número de argumentos para
XXX()
.
Verifica se os argumentos são de um tipo exigido ou, alternativamente, diga ao MySQL para converter os argumentos para o tipo desejado quando a função principal é chamada.
Aloca a memória exigida pela função principal.
Especifica o tamanho máximo do resultado.
Especifica (para funções REAL
) o
número máximo de decimais.
Especifica se o resultado pode ser
NULL
.
xxx_deinit()
(opicional)
A função de finalização para xxx()
.
Ela deve liberar qualquer memória alocada pela função de
inicialização.
Quando uma instrução SQL invoka XXX()
, o
MySQL chama a função de inicialização
xxx_init()
para realizar qualquer
configuração necessária, tais como verificação de
argumentos e alocação de memória. Se
xxx_init()
retorna um erro, a instrução SQL
é abortada com uma mensagem e as funções principais e de
finalização não são chamadas. Senão, a função principal
xxx()
é chamada uma vez para cada linha.
Depois de todas as linhas tiverem sido processadas, a função
de finalização xxx_deinit()
é chamada,
podendo assim realizar qualquer 'limpeza'.
Para funções agregadas (como SUM()
), você
também deve fornecer as seguintes funções:
xxx_reset()
(exigida)
Zera a soma e insere um argumento como o valor inicial para um novo grupo.
xxx_add()
(exigida)
Adiciona o argumento a soma antiga.
Quando se usa UDF's agregadas o MySQL funciona da seguinte maneira:
Chama xxx_init()
para deixar funções
agregadas alocarem a memória necessária para armazenar os
resultados.
Ordena a tabela de acordo com a expressão GROUP
BY
.
Para a primeira linha em um novo grupo, chama a função
xxx_reset()
.
Para cada nova linha que pertence ao mesmo grupo, chame a
função xxx_add()
.
Quando o grupo muda ou depois da última linha ter sido
processada, chame xxx()
para obter o
resultado para o conjunto.
Repita 3-5 até que todas as linhas tenham sido processada.
Chame xxx_deinit()
para deixar a UDF
liberar a memória alocada.
Todas as funções devem ser seguras com thread (não apenas a
função principal, mas também as funções de inicialização
e finalização). Isto significa que você não tem permissão
para alocar qualquer variável global ou estática que alterou!
Se você precisa de memória, você deve alocá-la em
xxx_init()
e liberá-la em
xxx_deinit()
.
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.