[+/-]
Pour que le mécanisme UDF
fonctionne, les
fonctions doivent êtres écrites en C ou C++ et votre système
doit supporter le chargement dynamique. Les sources de MySQL
incluent un fichier sql/udf_example.cc
qui
définit 5 nouvelles fonctions. Consultez ce fichier pour voir
comment marchent les conventions d'appels des
UDF
.
Pour que mysqld
puisse utiliser les fonctions
UDF
, vous devez configurer MySQL avec
l'option --with-mysqld-ldflags=-rdynamic
. La
raison est que sur diverses plates-formes, (Linux inclus) vous
pouvez charger une bibliothèque dynamique (avec
dlopen()
) depuis un programme statique lié,
que vous pouvez obtenir si vous utilisez l'option
--with-mysql-ldflags=-all-static
. Si vous
voulez utiliser une UDF
qui nécessite un
accès aux symboles de mysqld
(comme
l'exemple methaphone
dans
sql/udf_example.cc
qui utilise
default_charset_info
), vous devez lier le
programme avec -rdynamic
(voir man
dlopen
).
Pour chaque fonction que vous voulez utiliser dans SQL, vous
devez définir les fonctions correspondantes en C (ou C++). Dans
la discussion ci-dessous, le nom ``xxx
'' est
utilisé comme un exemple de nom de fonction. Pour faire la
différence entre l'usage de SQL et de C/C++,
XXX()
(majuscules) indique l'appel d'une
fonction SQL et xxx()
(minuscules) indique
l'appel d'une fonction C/C++.
Les fonctions C/C++ que vous écrivez pour l'implémentation de
l'interface de XXX()
sont :
xxx()
(requis)
La fonction principale. C'est là où le résultat de la fonction est calculé. La correspondance entre le type de SQL et le type retourné par votre fonction C/C++ est affiché ci-dessous :
SQL type | C/C++ type |
STRING |
char * |
INTEGER |
long long |
REAL |
double |
xxx_init()
(optionnel)
La fonction d'initialisation de xxx()
.
Elle peut-être utilisée pour :
Vérifier le nombre d'arguments de
XXX()
.
Vérifier que les arguments correspondent aux types requis ou indiquer à MySQL de contraindre des arguments aux types que vous voulez quand la fonction principale est appelée.
Allouer la mémoire requise pour la fonction principale.
Spécifier la longueur maximale de la sortie.
Spécifier (pour les fonctions REAL
)
le nombre maximal de décimales.
Spécifier si le résultat peut-être
NULL
.
xxx_deinit()
(optionnel)
La terminaison de la fonction xxx()
. Elle
doit libérer toute la mémoire allouée par
l'initialisation de la fonction.
Quand une requête SQL fait appel à XXX()
,
MySQL appelle l'initialisation de la fonction
xxx_init()
, pour laisser exécuter n'importe
quelle action exigée, telle que la vérification d'arguments ou
l'allocation de mémoire.
Si xxx_init()
retourne une erreur, la
requête SQL est annulée avec un message d'erreur et la
fonction principale et la fonction de terminaison ne sont pas
appelées. Autrement, la fonction principale
xxx()
est appelée une fois pour chaque
ligne. Après que toutes les lignes aient été traitées, la
fonction de terminaison xxx_deinit()
est
appelée pour procéder aux nettoyages requis.
Pour les fonctions d'agrégat (comme SUM()
),
vous pouvez également ajouter les fonctions suivantes :
xxx_reset()
(requise)
Remet la somme à zéro et insère l'argument en tant que valeur initiale pour un nouveau groupe.
xxx_add()
(requise)
Ajoute l'argument à l'ancienne somme.
Quand vous utilisez les UDF
d'agrégat, MySQL
opère comme suit :
Toutes les fonctions doivent être compatibles avec les threads
(et non pas simplement la fonction principale, mais aussi les
fonctions d'initialisation et de terminaison). Cela signifie que
vous ne pouvez pas allouer de variables globales ou statiques.
Si vous avez besoin de mémoire, allouez-la avec la fonction
xxx_init()
et libérez la avec
xxx_deinit()
.
Appeler xxx_init()
pour laisser la
fonction d'agrégat allouer la mémoire dont elle aura
besoin pour stocker les résultats.
Trier la table en accord avec la clause GROUP
BY
.
Pour la première ligne dans un nouveau groupe, appeler la
fonction xxx_reset()
.
Pour chaque ligne appartenant à un même groupe, appeler la
fonction xxx_add()
.
Quand le groupe change ou lorsque la dernière ligne a été
traitée, appeler xxx()
pour obtenir le
résultat de l'agrégat.
Répéter les étapes de 3 à 5 tant que toutes les lignes n'ont pas été traitées.
Appeler xxx_deinit()
pour libérer la
mémoire allouée.
Toutes les fonctions doivent être sûrs pour les threads (pas
seulement la fonction principale, mais les fonctions
d'initialisation et de terminaison également). Cela signifie
que vous n'êtes pas autorisés à allouer une variable globale
ou statique qui change ! Si vous avez besoin de mémoire, vous
devez l'allouer avec la fonction xxx_init()
et la libérer avec 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.