pub enum PlPgSqlStmt {
Show 18 variants
Assign {
target: AssignTarget,
value: Expr,
},
SelectInto {
var: String,
body: Box<SelectStatement>,
},
Return(ReturnTarget),
ReturnNext(Expr),
ReturnQuery(Box<SelectStatement>),
ReturnQueryExecute {
sql: Expr,
},
If {
branches: Vec<(Expr, Vec<PlPgSqlStmt>)>,
else_branch: Vec<PlPgSqlStmt>,
},
Raise {
level: RaiseLevel,
message: String,
args: Vec<Expr>,
},
EmbeddedSql(Box<Statement>),
Assert {
condition: Expr,
message: Option<Expr>,
},
While {
condition: Expr,
body: Vec<PlPgSqlStmt>,
},
ForRange {
var: String,
start: Expr,
end: Expr,
reverse: bool,
body: Vec<PlPgSqlStmt>,
},
Loop {
body: Vec<PlPgSqlStmt>,
},
Exit {
when: Option<Expr>,
},
Continue {
when: Option<Expr>,
},
ExecuteDynamic {
sql: Expr,
},
ForQuery {
var: String,
query: Box<SelectStatement>,
body: Vec<PlPgSqlStmt>,
},
ForExecute {
var: String,
sql_expr: Expr,
body: Vec<PlPgSqlStmt>,
},
}Variants§
Assign
NEW.col := expr; or OLD.col := expr;. OLD is parsed
for clarity in error reporting (PG also forbids it) — the
executor errors with a clear “OLD is read-only” message.
SelectInto
v7.16.2 — plpgsql SELECT <projection> INTO <var> [FROM …] (mailrs round-10 migrate-042). The body is
the SELECT statement with the INTO clause stripped; the
engine runs it via Engine::execute, takes the first
row’s first column, and assigns to the local variable
in the DECLARE scope. Single-column / single-row
queries only at v7.16.2; multi-target (INTO a, b) is
a v7.16.x follow-up.
Return(ReturnTarget)
RETURN <target>; — trigger functions canonically return
NEW / OLD / NULL; v7.12.4 also accepts a bare
expression for forward compatibility with scalar UDFs.
ReturnNext(Expr)
v7.39 (read01 round 66) — RETURN NEXT <expr>;: append one row to the
set a SETOF function is building, and KEEP GOING. Not a return.
ReturnQuery(Box<SelectStatement>)
v7.39 (read01 round 66) — RETURN QUERY <select>;: append every row the
query yields, and keep going. It used to desugar to a side-effect
statement whose result was DISCARDED — in a SETOF function that is the
whole answer thrown away.
ReturnQueryExecute
v7.39 (read01 round 68) — RETURN QUERY EXECUTE <sql expr>: the dynamic
twin. Its rows go to the set too; it used to run and discard them.
If
v7.12.6 — IF cond THEN body [ELSIF cond THEN body]* [ELSE body] END IF;. Branches are tried in order; first
truthy condition wins; the optional ELSE runs when no
condition matched.
Raise
v7.12.6 — RAISE <level> '<fmt>' [, args]*;. Level is one
of NOTICE / WARNING / INFO / LOG / DEBUG
(logging — observable side effect only) or EXCEPTION
(aborts the trigger and propagates as an error). v7.12.6
supports the basic format-string substitution PG uses
(% placeholders consumed positionally).
EmbeddedSql(Box<Statement>)
v7.12.6 — embedded SQL statement inside the trigger body
(INSERT INTO …, UPDATE …, DELETE FROM …, SELECT …).
NEW.col / OLD.col references inside the embedded
statement’s expression tree are substituted with the
current trigger context before the engine re-executes the
statement. Recursion depth into nested triggers is
bounded by the engine’s existing trigger-fire guard.
Assert
v7.37.20 (20.14) — ASSERT <condition> [, <message>];. If
the condition evaluates falsy the trigger / DO block aborts
with the message (defaulting to a generic shape when none
is provided). Same propagation shape as RAISE EXCEPTION
— the error reaches the caller’s query path. PG’s behaviour
is identical except for a plpgsql.check_asserts GUC that
can disable the check globally; SPG always evaluates.
While
v7.37.20 (20.3) — WHILE <condition> LOOP <body> END LOOP;.
Iterate the body while condition evaluates truthy. Iteration
count is bounded by WHILE_LOOP_BUDGET to prevent runaway
loops; the executor errors out when reached. EXIT / CONTINUE
inside the body queue with 20.2.
ForRange
v7.37.20 (20.4) — `FOR IN [REVERSE]
Loop
v7.37.20 (20.2) — bare LOOP <body> END LOOP;. Runs the body
repeatedly; only EXIT [WHEN <cond>] breaks out. Iteration
budget guards runaway.
Fields
body: Vec<PlPgSqlStmt>Exit
v7.37.20 (20.2) — EXIT [WHEN <condition>]; inside a loop.
Unconditional (no WHEN) or conditional (only breaks when
condition is truthy). Bubbles up as BodyOutcome::Break which
the enclosing loop catches. Outside a loop it’s a no-op.
Continue
v7.37.20 (20.2) — CONTINUE [WHEN <condition>]; inside a
loop. Same shape as EXIT but bubbles up as BodyOutcome::Continue
which the enclosing loop catches, skipping the remainder of
the body and jumping to the next iteration.
ExecuteDynamic
v7.37.20 (20.13) — EXECUTE <string_expr>; runs a runtime-
computed SQL statement. The expression is evaluated to a
text value, the resulting string is parsed and dispatched
through the engine like an EmbeddedSql. USING <param_list>
for placeholder binding queues with v7.40 PL/pgSQL epic.
ForQuery
v7.37.20 (20.5) — FOR <var> IN <select_body> LOOP <body> END LOOP;. Runs the SELECT once, iterates the resulting
rows, binds the first column of each row to var as a
scalar Value, then runs the body per iteration. EXIT /
CONTINUE / ASSERT / RAISE etc. propagate through the
enclosing loop’s BodyOutcome discipline the same way
FOR range and WHILE do. Full record-binding (var as
composite carrying all columns) queues with v7.40 record
type infrastructure.
ForExecute
v7.37.20 (20.6) — `FOR IN EXECUTE <string_expr> LOOP
Trait Implementations§
Source§impl Clone for PlPgSqlStmt
impl Clone for PlPgSqlStmt
Source§fn clone(&self) -> PlPgSqlStmt
fn clone(&self) -> PlPgSqlStmt
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more