Triggers

Event-driven logic that fires automatically on INSERT, UPDATE, or DELETE - on graph labels or document collections. Triggers execute within the same transaction as the triggering operation, guaranteeing atomicity.

CREATE TRIGGER

-- After insert on a document collection
CREATE TRIGGER create_profile
  AFTER INSERT ON COLLECTION auth.users
  FOR EACH ROW AS {
    UPSERT DOCUMENT IN profiles NEW.id {
      id: NEW.id,
      username: NEW.username,
      email: NEW.email
    }
  }

-- Before delete with RAISE to prevent deletion
CREATE TRIGGER protect_admin
  BEFORE DELETE ON COLLECTION auth.users
  FOR EACH ROW AS {
    RAISE 'Cannot delete admin users'
  }

-- Set timestamps on graph node creation
CREATE TRIGGER set_timestamps
  BEFORE INSERT ON :Project PRIORITY 10
  FOR EACH ROW AS {
    SET NEW.created_on = timestamp(),
        NEW.created_by = current_user()
  }

-- Audit log on delete
CREATE TRIGGER audit_delete
  AFTER DELETE ON :Project
  FOR EACH ROW AS {
    CREATE DOCUMENT IN audit_log uuid() {
      action: 'DELETE',
      old_name: OLD.name,
      deleted_by: current_user(),
      timestamp: timestamp()
    }
  }

Trigger Body Statements

StatementDescription
CREATE DOCUMENT IN coll key { ... }Insert document (no-op if key exists)
UPSERT DOCUMENT IN coll key { ... }Insert or merge fields
MATCH DOCUMENT d IN coll WHERE ... SET ...Find and update documents
SET NEW.field = exprModify row before write (BEFORE only)
RAISE 'message'Abort the operation (BEFORE only)

OLD / NEW Pseudo-Variables

EventOLDNEW
INSERTNot availableThe new row
UPDATERow before changesRow after changes
DELETEThe deleted rowNot available

Management

CREATE OR REPLACE TRIGGER name ...
DROP TRIGGER name
ENABLE TRIGGER name
DISABLE TRIGGER name
SHOW TRIGGERS
SHOW TRIGGERS ON :Label
SHOW TRIGGERS ON COLLECTION auth.users

Built-in Functions in Triggers

FunctionDescription
current_user()UUID of the current session user
current_username()Login username of the current session
is_sync()Whether the operation was sync-originated
timestamp()Current epoch milliseconds
uuid()Generate a new UUID v4

Chaining, Backfill & Depth

Trigger chaining: an UPSERT DOCUMENT executed inside a trigger body fires any AFTER triggers defined on the target collection.

Trigger backfill: creating a new trigger automatically processes all existing records in its target (label or collection), so existing data is immediately consistent with the new logic.

Priority ordering: lower number fires first (default 100). Recursive trigger firing is capped at 16 levels deep to prevent infinite loops. Use SKIP TRIGGERS on sync rules to prevent cascades.