Triggers (disparadores)

Postgres tiene algunas interfaces cliente como Perl, Tcl, Python y C, as� como dos Lenguajes Procedurales (PL). Tambi�n es posible llamar a funciones C como acciones trigger. Notar que los eventos trigger a nivel STATEMENT no est�n soportados en la versi�n actual. Actualmente es posible especificar BEFORE o AFTER en los INSERT, DELETE o UPDATE de un registro como un evento trigger.

Creaci�n de Triggers

Si un evento trigger ocurre, el administrador de triggers (llamado Ejecutor) inicializa la estructura global TriggerData *CurrentTriggerData (descrita m�s abajo) y llama a la funci�n trigger para procesar el evento.

La funci�n trigger debe ser creada antes que el trigger, y debe hacerse como una funci�n sin argumentos, y c�digos de retorno opacos.

La sintaxis para la creaci�n de triggers es la siguiente:

   CREATE TRIGGER <trigger name> <BEFORE|AFTER> <INSERT|DELETE|UPDATE>
       ON <relation name> FOR EACH <ROW|STATEMENT>
       EXECUTE PROCEDURE <procedure name> (<function args>);

El nombre del trigger se usar� si se desea eliminar el trigger. Se usa como argumento del comando DROP TRIGGER.

La palabra siguiente determina si la funci�n debe ser llamada antes (BEFORE) o despu�s (AFTER) del evento.

El siguiente elemento del comando determina en que evento/s ser� llamada la funci�n. Es posible especificar m�ltiples eventos utilizado el operador OR.

El nombre de la relaci�n (relation name) determinar� la tabla afectada por el evento.

La instrucci�n FOR EACH determina si el trigger se ejecutar� para cada fila afectada o bien antes (o despu�s) de que la secuencia se haya completado.

El nombre del procedimiento (procedure name) es la funci�n C llamada.

Los argumentos son pasados a la funci�n en la estructura CurrentTriggerData. El prop�sito de pasar los argumentos a la funci�n es permitir a triggers diferentes con requisitos similares llamar a la misma funci�n.

Adem�s, la funci�n puede ser utilizada para disparar distintas relaciones (estas funciones son llamadas "general trigger funcions").

Como ejemplo de utilizaci�n de lo descrito, se puede hacer una funci�n general que toma como argumentos dos nombres de campo e inserta el nombre del usuario y la fecha (timestamp) actuales en ellos. Esto permite, por ejemplo, utilizar los triggers en los eventos INSERT para realizar un seguimiento autom�tico de la creaci�n de registros en una tabla de transacciones. Se podr�a utilizar tambi�n para registrar actualizaciones si es utilizado en un evento UPDATE.

Las funciones trigger retornan un �rea de tuplas (HeapTuple) al ejecutor. Esto es ignorado para trigger lanzados tras (AFTER) una operaci�n INSERT, DELETE o UPDATE, pero permite lo siguiente a los triggers BEFORE: - retornar NULL e ignorar la operaci�n para la tupla actual (y de este modo la tupla no ser� insertada/actualizada/borrada); - devolver un puntero a otra tupla (solo en eventos INSERT y UPDATE) que ser�n insertados (como la nueva versi�n de la tupla actualizada en caso de UPDATE) en lugar de la tupla original.

Notar que no hay inicializaci�n por parte del CREATE TRIGGER handler. Esto ser� cambiado en el futuro. Adem�s, si m�s de un trigger es definido para el mismo evento en la misma relaci�n, el orden de ejecuci�n de los triggers es impredecible. Esto puede ser cambiado en el futuro.

Si una funci�n trigger ejecuta consultas SQL (utilizando SPI) entonces estas funciones pueden disparar nuevos triggers. Esto es conocido como triggers en cascada. No hay ninguna limitaci�n explicita en cuanto al n�mero de niveles de cascada.

Si un trigger es lanzado por un INSERT e inserta una nueva tupla en la misma relaci�n, el trigger ser� llamado de nuevo (por el nuevo INSERT). Actualmente, no se proporciona ning�n mecanismo de sincronizaci�n (etc) para estos casos pero esto puede cambiar. Por el momento, existe una funci�n llamada funny_dup17() en los tests de regresi�n que utiliza algunas t�cnicas para parar la recursividad (cascada) en si misma...