Expand description
v7.12.4 — PL/pgSQL row-level trigger executor.
The catalogued spg_storage::FunctionDef carries the trigger
function’s source body as raw text (between the original
$$ ... $$). Each time a trigger fires we re-parse the body
via spg_sql::parse_function_body and walk the resulting
spg_sql::ast::PlPgSqlBlock against a NEW / OLD row context.
v7.12.4 surface (the minimum that lets a mailrs-shape
update_search_vector trigger run end-to-end):
NEW.col := <expr>;— mutate a NEW cell. BEFORE only.RETURN NEW;— pass the (possibly-mutated) row back to the row writer.RETURN OLD;— return the pre-change row.RETURN NULL;/RETURN;— skip the write (BEFORE) or no-op the notification (AFTER).- sub-expression eval recurses through the regular
crate::eval::eval_exprso anything the SELECT executor can compute is fair game inside a trigger body.
Out of scope for v7.12.4 (land in v7.12.5+):
DECLARE’d local variablesIF / ELSIF / ELSE / END IF;control flow- Embedded SQL statements (
UPDATE … WHERE …,SELECT … INTO var) RAISE NOTICE / RAISE EXCEPTION- Loop constructs
Structs§
- Deferred
Embedded Stmt - v7.12.7 — embedded SQL statement collected during a trigger
fire, queued for execution after the firing DML completes.
NEW / OLD / DECLARE-local references inside the statement’s
Expr tree have already been substituted with literals; the
engine just feeds it to
execute_stmt_with_cancel. - TgMeta
- v7.39 (read01 round 82) — the firing trigger’s identity, for the TG_* magic
variables.
opisINSERT/UPDATE/DELETE;levelisROW(SPG fires row-level triggers only).TG_WHENderives fromis_after.
Enums§
- Trigger
Error - Result type the trigger executor exposes. Wraps
EvalErrorat the eval-of-expressions layer and adds trigger-specific failure modes (OLD.col := …, unsupported PL/pgSQL feature, body that fails to re-parse, …). - Trigger
Outcome - What the trigger function returned. Drives the row-write path the trigger fired from.
Functions§
- call_
plpgsql_ scalar - v7.39 (read01 round 64) — run a plpgsql body as a SCALAR function: the same
interpreter the DO block and the triggers use, with no NEW / OLD, the
arguments pre-bound as locals, and
RETURN <expr>actually EVALUATED (the trigger path discards it —resolve_return’s own comment said “the scalar UDF surface in a later release handles RETURNproperly”). - execute_
do_ block_ top_ level - v7.16.2 — execute a DO block’s PlPgSqlBlock at top level.
Different from
fire_row_triggerin three ways: - fire_
row_ trigger - Fire a single row-level trigger.
- matching_
trigger_ names - v7.12.4 — find the triggers that should fire for a given
(table, event, timing)tuple. Returns names so the caller can iterate without holding a borrow on the catalog while it mutates rows.
Type Aliases§
- ForQuery
Resolver - v7.37.20 (20.5) — callback shape the DO-block executor registers
on
BodyCtxfor FOR-IN-SELECT loops. Runs the supplied SELECT statement against the engine and returns every row’s values. v7.39 (read01 round 64) — the COLUMN NAMES ride along now, so the loop can bind a record variable’s fields (rec.v), not just its first cell. - Notice
Sink - v7.39 (round 757, F31-B3) — where
RAISE NOTICE / WARNING / INFOdeliver their rendered messages. The caller drains it into the session’s pending notices, and pgwire ships one NoticeResponse per entry;None(the SELECT-path scalar-function caller, which holds the engine immutably) drops them — ledgered as the B3 residual. - Select
Into Resolver - v7.16.2 — callback shape the DO-block executor registers
on
BodyCtx. Runs the supplied SELECT statement against the engine, returns the first row’s first column.