How to View PostgreSQL Trigger Definition and Details Using psql


2 views

When working with PostgreSQL triggers, you'll often need to inspect their complete definition beyond just listing them. While \dft shows a list of triggers, you need deeper inspection methods.

The most comprehensive way to view trigger details is querying the system catalog:

SELECT tgname AS trigger_name, 
       tgrelid::regclass AS table_name,
       tgenabled AS status,
       tgtype AS events,
       tgfoid::regproc AS function_name,
       tgargs AS function_args
FROM pg_trigger
WHERE tgname = 'your_trigger_name';

The tgtype field contains bitmask values representing trigger events:

-- Common event bitmasks
SELECT 
  (1<<0) AS "INSERT",
  (1<<1) AS "DELETE",
  (1<<2) AS "UPDATE",
  (1<<3) AS "TRUNCATE";

To see the actual function code being executed:

SELECT prosrc 
FROM pg_proc 
WHERE oid = (SELECT tgfoid FROM pg_trigger WHERE tgname = 'your_trigger_name');

For quick inspection, use these psql meta-commands:

\sf+ trigger_function_name  -- Show function definition
\d+ table_name              -- Show table structure including triggers

Let's examine an audit trigger:

-- Create sample trigger
CREATE TRIGGER audit_trigger
AFTER INSERT OR UPDATE OR DELETE ON employees
FOR EACH ROW EXECUTE FUNCTION audit_employee_changes();

-- View its definition
SELECT pg_get_triggerdef(oid) 
FROM pg_trigger 
WHERE tgname = 'audit_trigger';

To save all triggers for a table:

SELECT pg_get_triggerdef(oid) || ';' AS trigger_definition
FROM pg_trigger
WHERE tgrelid = 'your_table_name'::regclass;

When working with PostgreSQL triggers, developers often need to inspect specific trigger definitions beyond what \dft provides. The pg_trigger system catalog contains comprehensive metadata about all triggers in the database.

SELECT tgname, tgtype, tgenabled, tgconstraint, tgdeferrable, tginitdeferred,
       tgconstrrelid::regclass, tgconstrindid::regclass, tgfoid::regproc,
       tgargs, tgqual
FROM pg_trigger
WHERE tgname = 'your_trigger_name';

For a more human-readable format, use the pg_get_triggerdef() function:

SELECT pg_get_triggerdef(oid) AS trigger_definition
FROM pg_trigger
WHERE tgname = 'your_trigger_name';

Let's examine a trigger that logs changes to a products table:

-- First create the example trigger
CREATE OR REPLACE FUNCTION log_product_changes()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO product_audit(product_id, changed_at, old_price, new_price)
    VALUES (OLD.product_id, now(), OLD.price, NEW.price);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER product_price_update_trigger
AFTER UPDATE OF price ON products
FOR EACH ROW
EXECUTE FUNCTION log_product_changes();

Now query its details:

SELECT 
    tgname AS trigger_name,
    tgtype AS trigger_type,
    tgenabled AS is_enabled,
    tgisinternal AS is_internal,
    tgdeferrable AS is_deferrable,
    tginitdeferred AS initially_deferred,
    pg_get_triggerdef(oid) AS trigger_definition
FROM pg_trigger
WHERE tgname = 'product_price_update_trigger';

The tgtype field contains bitmask values indicating trigger characteristics:

-- Common tgtype values:
-- 1: BEFORE
-- 2: AFTER
-- 4: INSTEAD OF
-- 8: ROW-level
-- 16: STATEMENT-level
-- 32: INSERT operation
-- 64: UPDATE operation
-- 128: DELETE operation
-- 256: TRUNCATE operation

For standardized metadata access, query the information_schema.triggers view:

SELECT 
    trigger_name,
    event_manipulation,
    event_object_table,
    action_statement,
    action_timing,
    action_orientation
FROM information_schema.triggers
WHERE trigger_name = 'your_trigger_name';

1. Combine with function inspection to see the complete picture:

SELECT prosrc FROM pg_proc WHERE proname = 'log_product_changes';

2. For triggers on system tables, add schema qualification:

SELECT pg_get_triggerdef(t.oid)
FROM pg_trigger t
JOIN pg_class c ON t.tgrelid = c.oid
WHERE t.tgname = 'your_trigger'
AND c.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'your_schema');