Skip to main content

Module rewrite

Module rewrite 

Source
Expand description

Rewriting a bound tree in place, exhaustively.

Invariant: a walk here reaches every expression a statement holds - result columns, filters, join constraints, window frames, VALUES rows, compound arms and subquery blocks alike - or it is a defect rather than an omission. The walks are written beside the definitions they mirror for that reason: a field added to BoundSelect and not added here is a subtree some rewrite silently skips, and the symptom is a wrong answer rather than a refusal.

§What it is for

The trigger firing point. A trigger body is bound once, against the statement that fires it, and its expressions read OLD and NEW through the two sentinel source numbers crate::bind::OLD_SOURCE and crate::bind::NEW_SOURCE. At the moment a trigger fires, both rows are values the write path is already holding - so the body is copied, every OLD and NEW read in it is replaced by the value itself, and what is left is an ordinary statement with no external references that the ordinary planner plans and the ordinary write path applies.

That is what makes DELETE FROM child WHERE parent_id = OLD.id reach the same index probe the same DELETE typed by hand reaches, and it is why there is no second execution path for a trigger body.

§The one subtree a rewrite must not enter

A body statement carries its own triggers, and those have their own OLD and NEW. Substituting the firing statement’s rows into them would give an inner trigger the outer row, which is a wrong answer of exactly the kind this engine is not allowed to have. So rewrite_insert, rewrite_update and rewrite_delete walk every field of their statement except triggers and replace_triggers, and each nested fire substitutes its own rows when its own turn comes.

Functions§

rewrite_delete
Applies a rewrite to every expression a DELETE holds, its own triggers excepted.
rewrite_expr
Applies a rewrite to one expression and everything under it.
rewrite_insert
Applies a rewrite to every expression an INSERT holds, its own triggers excepted.
rewrite_select
Applies a rewrite to every expression a query holds.
rewrite_update
Applies a rewrite to every expression an UPDATE holds, its own triggers excepted.

Type Aliases§

Rewrite
A rewrite applied to one expression before its children are walked.