CREATE [ TRUSTED ] PROCEDURAL LANGUAGE 'langname' HANDLER call_handler LANCOMPILER 'comment' |
TRUSTED especifica que el manipulador para el lenguaje es seguro; es decir, que no ofrece a un usuario no privilegiado nuevas funcionalidades sobrepasando las restricciones de acceso. Si esta palabra es omitida entonces al registrar el lenguaje, sólo usuarios con privilegio de superusuario Postgres podrán utilizar este lenguaje para crear nuevas funciones (como el lenguaje 'C').
El nombre del nuevo lenguaje procedimental. No se diferencian mayúsculas de minúsculas en el nombre del lenguaje. Un lenguaje procedimental no puede redefinir uno de los lenguajes incorporados de Postgres. Postgres.
call_handler es el nombre de una funcion previamente registrada que será llamada para ejecutar los procedimientos PL.
El argumento LANCOMPILER es la cadena que será insertadoa en el atributo LANCOMPILER de la nueva entrada pg_language . Actualmente Postgres no utiliza este atributo para ningún fin.
Utilizando CREATE LANGUAGE, un usuario Postgres puede registrar un nuevo lenguaje en Postgres. A continuación, las funciones y procedimientos "trigger" pueden ser definidos en este nuevo lenguaje. El usuario debe tener privilegios de superusuario Postgres para registrar un nuevo lenguaje.
El manipulador de llamadas para un lenguaje procedimental debe ser escrito en un lenguaje compilado como 'C' y registrado en Postgres como una función sin argumentos y devolviendo el tipo opaque, un contenedor para tipos no definidos o especificados... Esto evita que el manipulador de llamadas sea llamado directamente como una función desde consultas.
Sin embargo, los argumentos deben ser suministrados en la llamada cuando una funcion PL o procedimiento trigger en el lenguaje ofrecido por el manipulador sea ejecutado.
Cuando es llamado por el gestor de triggers, el único argumento es el ID del objeto tomada de la entrada de procedimientos pg_proc. Toda la demás información del gestor de triggers es encontrada en el puntero global CurrentTriggerData .
Cuando es llamado desde el gestor de funciones, los argumentos son el ID del objeto de la entrada pg_proc del procedimiento, el número de argumentos entregados a la funcion PL, los argumentos en una estructura FmgrValues y un puntero a un booleano donde la función informa si el valor de retorno es el valor NULL de SQL.
Es responsabilidad del manipulador de llamadas obtener la entrada pg_proc y analizar el argumento y tipos de retorno del procedimiento llamado. La cláusula AS del CREATE FUNCTION del procedimiento estará basada en el atributo prosrc de la tabla pg_proc. Esto puede ser el texto fuente en el lenguaje procedimental mismo (como en PL/Tcl), una ruta a un fichero o cualquier otra cosa que le indique al handler que hacer en detalle.
Utilice CREATE FUNCTION para crear una función.
Utilice DROP LANGUAGE para eliminar lenguajes de procedimiento.
Remítase a la tabla pg_language para más información:
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 |
Ya que el manipulador (call handler) para un lenguaje de procedimientos debe ser registrado en Postgres en el lenguaje 'C', hereda todas las capacidades y restricciones de las funciones de 'C'.
Actualmente, las definiciones para un lenguaje de procedimientos no pueden ser modificadas una vez que han sido creadas.
Esta es una plantilla para un manipulador 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) { /* * Llamado como una función */ retval = ... } else { /* * Llamado como un procedimiento "trigger" */ trigdata = CurrentTriggerData; CurrentTriggerData = NULL; retval = ... } *isNull = false; return retval; } |
Solamente unos pocos miles de líneas de código tienen que ser añadidas en vez de los puntos para completar el 'PL call handler' Vea CREATE FUNCTION para información sobre como compilarlo en un módulo cargable.
Los siguientes comandos entonces registran el lenguje de procedimientos de muestra:
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'; |