Un disparador de eventos se ejecuta cada vez que ocurre el evento con el que está asociado
en la base de datos en la que está definido. Actualmente, los eventos admitidos son
login,
ddl_command_start,
ddl_command_end,
table_rewrite
y sql_drop.
Se podría añadir soporte para eventos adicionales en futuras versiones.
El evento login ocurre cuando un usuario autenticado inicia
sesión en el sistema. Cualquier error en un procedimiento de disparador para este evento puede
impedir el inicio de sesión exitoso en el sistema. Dichos errores pueden solucionarse
estableciendo event_triggers en false
ya sea en una cadena de conexión o en el archivo de configuración. Alternativamente, puedes
reiniciar el sistema en modo monousuario (ya que los disparadores de eventos están
desactivados en este modo). Consulta la página de referencia de la postgres
para obtener detalles sobre el uso del modo monousuario.
El evento login también se ejecutará en servidores en espera (standby).
Para evitar que los servidores se vuelvan inaccesibles, dichos disparadores deben evitar
escribir en la base de datos cuando se ejecutan en un servidor en espera.
Además, se recomienda evitar consultas de larga duración en los disparadores del evento
login. Ten en cuenta que, por ejemplo,
cancelar una conexión en psql no cancelará
el disparador de login en curso.
Para ver un ejemplo de cómo utilizar el disparador del evento login,
consulta la Section 38.5.
El evento ddl_command_start ocurre justo antes de la
ejecución de un comando DDL. Los comandos DDL en este contexto son:
CREATE
ALTER
DROP
COMMENT
GRANT
IMPORT FOREIGN SCHEMA
REINDEX
REFRESH MATERIALIZED VIEW
REVOKE
SECURITY LABEL
ddl_command_start también ocurre justo antes de la
ejecución de un comando SELECT INTO, ya que este es
equivalente a CREATE TABLE AS.
Como excepción, este evento no ocurre para los comandos DDL dirigidos a objetos compartidos:
bases de datos
roles (definiciones de roles y membresías a roles)
tablespaces
privilegios de parámetros
ALTER SYSTEM
Este evento tampoco ocurre para comandos dirigidos a los propios disparadores de eventos.
No se realiza ninguna comprobación de si el objeto afectado existe o no antes de que se ejecute el disparador de eventos.
El evento ddl_command_end ocurre justo después de la ejecución del
mismo conjunto de comandos que ddl_command_start. Para
obtener más detalles sobre las operaciones DDL
que tuvieron lugar, utiliza la función que devuelve un conjunto
pg_event_trigger_ddl_commands() desde el código del
disparador del evento ddl_command_end (consulta la
Section 9.30). Ten en cuenta que el disparador se ejecuta
después de que las acciones hayan tenido lugar (pero antes de que se confirme la transacción)
y, por lo tanto, los catálogos del sistema se pueden leer como ya modificados.
El evento sql_drop ocurre justo antes del disparador del
evento ddl_command_end para cualquier operación que elimine
objetos de la base de datos. Ten en cuenta que, además de los comandos DROP
obvios, algunos comandos ALTER también pueden desencadenar un
evento sql_drop.
Para listar los objetos que han sido eliminados, utiliza la función
que devuelve un conjunto pg_event_trigger_dropped_objects() desde el
código del disparador del evento sql_drop (consulta la
Section 9.30). Ten en cuenta que
el disparador se ejecuta después de que los objetos han sido eliminados de los
catálogos del sistema, por lo que ya no es posible buscarlos.
El evento table_rewrite ocurre justo antes de que una tabla sea
reescrita por algunas acciones de los comandos ALTER TABLE y
ALTER TYPE. Aunque existen otras
sentencias de control disponibles para reescribir una tabla,
como CLUSTER y VACUUM,
el evento table_rewrite no es desencadenado por ellas.
Para encontrar el OID de la tabla que fue reescrita, utiliza la función
pg_event_trigger_table_rewrite_oid(), y para descubrir la(s)
razón(es) de la reescritura, utiliza la función
pg_event_trigger_table_rewrite_reason() (consulta la Section 9.30).
Los disparadores de eventos (al igual que otras funciones) no se pueden ejecutar en una
transacción abortada. Por lo tanto, si un comando DDL falla con un error, los
disparadores ddl_command_end asociados no se ejecutarán. Por el contrario,
si un disparador ddl_command_start falla con un error, no se
ejecutarán más disparadores de eventos y no se intentará ejecutar el
comando en sí. Del mismo modo, si un disparador ddl_command_end
falla con un error, los efectos de la sentencia DDL se revertirán (roll back),
tal como sucederería en cualquier otro caso en que la transacción contenedora
se aborte.
Los disparadores de eventos se crean utilizando el comando CREATE EVENT TRIGGER.
Para crear un disparador de eventos, primero debes crear una función con
el tipo de retorno especial event_trigger. Esta función
no necesita (y no debe) devolver un valor; el tipo de retorno sirve simplemente como
una señal de que la función se va a invocar como un disparador de eventos.
Si se define más de un disparador de eventos para un evento en particular, se ejecutarán en orden alfabético por el nombre del disparador.
La definición de un disparador también puede especificar una condición WHEN
para que, por ejemplo, un disparador ddl_command_start
se ejecute solo para comandos particulares que el usuario desee
interceptar. Un uso común de tales disparadores es restringir el rango de
operaciones DDL que los usuarios pueden realizar.