| 24.2 Ajouter des fonctions à MySQL
 24 Etendre MySQL
 Manuel de Référence MySQL 4.1 : Version Française
 
 . Syntaxe de CREATE FUNCTION/DROP FUNCTION
 . Ajouter une nouvelle fonction définie par l'utilisateur ( UDF )
 ->Ajouter de nouvelles fonctions natives
 
 
 | 
  24.2.3 Ajouter de nouvelles fonctions natives    
 
La procédure pour ajouter une nouvelle fonction native est décrite ici.
Notez que vous ne pouvez ajouter de fonctions natives à une distribution
binaire car la procédure implique la modifications du code source de MySQL.
Vous devez compiler MySQL vous-même à partir d'une distribution des sources.
Notez aussi que si vous migrez vers une autre version de MySQL (par exemple,
quand une nouvelle version est réalisée), vous devrez répéter la procédure
avec la nouvelle version.
Pour ajouter une nouvelle fonction native à MySQL, suivez les étapes suivantes : 
Ajoutez une ligne dans  
lex.h
  qui définit le nom de la fonction dans le
tableau  
sql_functions[]
 .Si le prototype de la fonction est simple (elle prend zéro, un, deux ou trois
arguments), vous devez spécifier dans  
lex.h
 
SYM(FUNC_ARG#
 ) 
(où # est le nombre d'arguments) en tant que second argument dans le 
tableau  
sql_functions[]
  
et ajouter une fonction qui crée un objet fonction dans  
item_create.cc
 .
Regardez  
"ABS"
  et  
create_funcs_abs()
  pour un exemple.
 
Si le prototype de la fonction est compliqué (par exemple, elle prend un nombre 
variable d'arguments), vous devez ajouter deux lignes à  
sql_yacc.yy
 . Une
qui indique le symbole preprocesseur que  
yacc
  doit définir (cela doit
être ajouté au début du fichier). Puis définir les paramètres de la fonction
et un ``item'' avec ces paramètres à la règle  
simple_expr
 .
Pour un exemple, vérifiez toutes les occurrences de  
ATAN
  dans  
sql_yacc.yy
 
pour voir comment cela se fait.
Dans  
item_func.h
 , déclarez une classe héritant de  
Item_num_func
  ou de
 
Item_str_func
 , selon que votre fonction retourne une nombre ou un chaîne.Dans le fichier  
item_func.cc
 , ajoutez l'une des déclaration suivantes, selon
que vous définissez une fonction numérique ou de chaîne de caractères :
 
Si vous héritez votre objet de l'un des éléments standards (comme
 
Item_num_func
 ) vous n'aurez probablement qu'à définir l'une des
fonctions décrites ci-dessus et laisser l'objet parent prendre soin des
autres fonctions.
Par exemple, la classe  
Item_str_func
  définit une fonction  
val()
 
qui exécute  
atof()
  sur la valeur retournée par  
::str()
 .| 
double   Item_func_newname::val()longlong Item_func_newname::val_int()
 String  *Item_func_newname::Str(String *str)
 | 
Vous devez aussi probablement définir la fonction objet suivante :
 
Cette fonction doit au moins calculer  
max_length
  en se basant sur les 
arguments donnés.  
max_length
  est le nombre maximal de caractères
que la fonction peut retourner. Cette fonction doit aussi définir  
maybe_null
= 0
  si la fonction principale ne peut pas retourner une valeur  
NULL
 . La 
fonction peut vérifier si l'un de ses arguments peut retourner  
NULL
  
en vérifiant la variable  
maybe_null
  des arguments. Vous pouvez regarder
 
Item_func_mod::fix_length_and_dec
  pour avoir un exemple concret.| 
void Item_func_newname::fix_length_and_dec()
 | 
 
Toutes les fonctions doivent être sûres pour les threads (en d'autres termes, n'utilisez aucune
variable statique ou globale dans la fonction sans les protéger avec mutex).
Si vous voulez retourner  
NULL
 , à partir de  
::val()
 ,  
::val_int()
 
ou  
::str()
  vous devez mettre  
null_value
  à 1 et retourner 0. 
Pour les fonctions de l'objet  
::str()
 , il y a d'autres considérations à prendre
en compte :
 
L'argument  
String *str
  fournit un tampon de chaîne qui peut être utilisé
pour contenir le résultat. (Pour plus d'informations à propos du type  
String
 ,
regardez le fichier  
sql_string.h
 .)
La fonction  
::str()
  doit retourner la chaîne contenant le résultat ou
 
(char*) 0
  si celui-ci est  
NULL
 .
Aucune des fonctions de chaînes n'essaye d'allouer de mémoire tant que ce n'est pas
nécessaire !
 |