Expand description
Plan cache — Mission D9.
Two queries that differ only in literal values share the same parsed +
planned tree. Re-running the lexer + parser + planner on every call is
pure overhead — easily 1-3μs per query, which is the entire budget on
sub-microsecond workloads like update_by_pk. SQLite gets around this
with prepare_cached; we get around it with this cache.
§How it works
crate::canonicalize::canonicalizelexes the input and produces(canonical_hash, literals). The hash collapses literal values into placeholders, soUser filter .id = 1andUser filter .id = 2have the same hash.- On the first call,
PlanCache::insertstores the planned tree keyed by the canonical hash. The plan still has the first call’s literal values baked into itsExpr::Literalnodes — that’s fine, we’ll overwrite them on subsequent hits. - On a subsequent call,
PlanCache::get_with_substitutionclones the cached plan and walks it depth-first, replacing eachExpr::Literalit finds (in source order) with the corresponding literal from the new query.
The walk order is deterministic and matches the source order of the
literal list collected by canonicalize — see the per-PlanNode
comments below for the exact traversal contract.
Structs§
- Plan
Cache - LRU-ish plan cache keyed by canonical query hash.