CREATE [ TRUSTED ] PROCEDURAL LANGUAGE 'langname' HANDLER call_handler LANCOMPILER 'comment' |
TRUSTED spécifie que le lanceur d'appel pour le langage est sûr; ainsi, il ne permet pas à un utilisateur non privilégié d'outrepasser les restrictions d'accès. Si ce mot-clé est omis lors de l'enregistrement du langage, seuls les utilisateurs avec les privilèges de superuser pourront utiliser ce langage pour créer de nouvelles fonctions (comme le langage 'C').
nom du nouveau langage procédural. Le nom de langage est pris en compte. Un langage procédural ne peut pas outrepasser un des langages natifs de Postgres.
call_handler est le nom de la fonction antérieurement enregistrée qui sera appelée pour exécuter les procédures PL.
l'argument LANCOMPILER est la chaîne qui sera insérée dans l'attribut LANCOMPILER du nouveau pg_language. À présent Postgres n'utilise pas cet attribut d'aucune façon.
message retourné lorsque le langage est créé correctement.
erreur retournée si la fonction funcname() n'est pas trouvée.
En utilisant CREATE LANGUAGE, un utilisateur peut créer un nouveau langage avec Postgres. En conséquence, les fonctions et les procédures déclencheurs peuvent être définies dans ce nouveau langage. L'utilisateur doit avoir les privilèges du superuser pour enregistrer un nouveau langage.
Le lanceur d'appel pour un langage procédural doit être écrit dans un langage compilé comme le 'C' et enregistré avec Postgres comme une fonction ne prenant pas d'arguments et retournant le type opaque, un espace de stockage pour les types non spécifiés et non définis... Ceci évite au lanceur d'appel d'être créé directement comme une fonction depuis les requêtes.
Cependant, les arguments doivent être fournis sur l'appel actuel quand une fonction PL ou une procédure déclencheur dans le langage fournit par le handler est exécutée.
quand elle est appelée depuis le trigger manager, le seul argument est l'objet ID depuis l'entrée de la procédure pg_proc. Toute autre information depuis le trigger manager est trouvée dans le global CurrentTriggerData pointer.
quand elles sont appelées depuis le fonction manager, les arguments sont l'objet ID de la procedure pg_proc, le nombre d'arguments donnés à la fonction PL, les arguments dans la structure FmgrValues et un pointeur vers un booléen où la fonction indique au caller si la valeur de retour est la valeur SQL NULL.
C'est au lanceur d'appel de rechercher l'entrée de pg_proc entryet d'analyser l'argument et les types de retour de la procédure appelée. La clause AS de CREATE FUNCTION de la procédure sera trouvée dans l'attribut prosrc de l'entrée de table pg_proc. Ceci peut être le source text dans le langage procédural lui-même (comme pour PL/Tcl), un chemin vers un fichier ou n'importe quoi d'autre qui indique au call handler quoi faire en détail.
Utilisez CREATE FUNCTION pour créer une fonction.
Utilisez DROP LANGUAGE pour supprimer des langages procéduraux.
Voir la table pg_language pour plus d'informations :
Table = pg_language +--------------------------+--------------------------+-------+ | Field | Type | Length| +--------------------------+--------------------------+-------+ | lanname | name | 32 | | lancompiler | text | var | +--------------------------+--------------------------+-------+ lanname |lancompiler --------+-------------- internal|n/a lisp |/usr/ucb/liszt C |/bin/cc sql |postgres |
Depuis que le call handler, pour un langage procédural, doit être enregistré avec Postgres en langage 'C', il hérite de toutes les possibilités et restrictions des fonctions 'C'.
À présent, les définitions pour un langage procédural ne peuvent être changées une fois qu'elles ont été créées.
Ceci est un modèle pour un PL handler écrit en 'C' :
#include "executor/spi.h" #include "commands/trigger.h" #include "utils/elog.h" #include "fmgr.h" /* for FmgrValues struct */ #include "access/heapam.h" #include "utils/syscache.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" Datum plsample_call_handler( Oid prooid, int pronargs, FmgrValues *proargs, bool *isNull) { Datum retval; TriggerData *trigdata; if (CurrentTriggerData == NULL) { /* * Called as a function */ retval = ... } else { /* * Called as a trigger procedure */ trigdata = CurrentTriggerData; CurrentTriggerData = NULL; retval = ... } *isNull = false; return retval; } |
Seulement quelques milliers de lignes de code ont été ajoutées à la place des points pour compléter le PL call handler. Voir, CREATE FUNCTION pour la compilation en module chargeable.
Les commandes suivantes montrent un exemple de langage procédural :
CREATE FUNCTION plsample_call_handler () RETURNS opaque AS '/usr/local/pgsql/lib/plsample.so' LANGUAGE 'C'; CREATE PROCEDURAL LANGUAGE 'plsample' HANDLER plsample_call_handler LANCOMPILER 'PL/Sample'; |