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
DELETEholds, 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
INSERTholds, its own triggers excepted. - rewrite_
select - Applies a rewrite to every expression a query holds.
- rewrite_
update - Applies a rewrite to every expression an
UPDATEholds, its own triggers excepted.
Type Aliases§
- Rewrite
- A rewrite applied to one expression before its children are walked.