Derive a query's dependency profile from a parse tree.
The profile is what the matcher compares update events against:
{:tables #{table-name}
:columns #{column-name}
:wildcard-tables #{table-name}} ; any change re-runs
Columns are kept as a bare-name set with no alias binding: a column name shared by two queried tables over-triggers recomputation but can never miss one. Stars resolve through each core's FROM aliases, including CTE names (to the CTE body's tables, recursively) and FROM subqueries. Anything the grammar cannot parse returns :all, which recomputes on every write.
Known unsound edge, accepted for simplicity: CTE names are subtracted globally rather than lexically, so a query that both defines a CTE and separately queries a real table of the same name would under-trigger for that table.
All names are normalised - quotes stripped, ASCII-folded - because SQLite treats identifiers as ASCII case-insensitive and the database reports column names in their declared case.
Derive a query's dependency profile from a parse tree.
The profile is what the matcher compares update events against:
{:tables #{table-name}
:columns #{column-name}
:wildcard-tables #{table-name}} ; any change re-runs
Columns are kept as a bare-name set with no alias binding: a column
name shared by two queried tables over-triggers recomputation but
can never miss one. Stars resolve through each core's FROM aliases,
including CTE names (to the CTE body's tables, recursively) and
FROM subqueries. Anything the grammar cannot parse returns :all,
which recomputes on every write.
Known unsound edge, accepted for simplicity: CTE names are
subtracted globally rather than lexically, so a query that both
defines a CTE and separately queries a *real table of the same
name* would under-trigger for that table.
All names are normalised - quotes stripped, ASCII-folded - because
SQLite treats identifiers as ASCII case-insensitive and the
database reports column names in their declared case.(deps sql eqp-tables)Dependency profile blending sqlite's own plan with the grammar.
eqp-tables is the normalised table set the backend extracted from EXPLAIN QUERY PLAN for this statement - the sound floor that keeps working for statements the grammar cannot parse. Where the grammar succeeds it contributes column granularity and star resolution on top; where it fails, the profile degrades to table granularity (wildcards over every planned table) rather than re-running on every write. :all survives only for the degenerate case of an empty EQP set with an unparsable statement.
Dependency profile blending sqlite's own plan with the grammar. eqp-tables is the normalised table set the backend extracted from EXPLAIN QUERY PLAN for this statement - the sound floor that keeps working for statements the grammar cannot parse. Where the grammar succeeds it contributes column granularity and star resolution on top; where it fails, the profile degrades to table granularity (wildcards over every planned table) rather than re-running on every write. :all survives only for the degenerate case of an empty EQP set with an unparsable statement.
(eqp-detail-table detail)Table name from one EXPLAIN QUERY PLAN detail string, or nil. Handles both the modern ('SCAN users', 'SEARCH users AS u USING ...') and legacy ('SCAN TABLE users') shapes; skips plan artifacts that are not base tables (subqueries, temp b-trees, co-routines). Shared by every backend, since EQP detail format is sqlite's, not the driver's. JS regexes lack inline flags, hence the per-platform patterns.
Table name from one EXPLAIN QUERY PLAN detail string, or nil.
Handles both the modern ('SCAN users', 'SEARCH users AS u USING
...') and legacy ('SCAN TABLE users') shapes; skips plan artifacts
that are not base tables (subqueries, temp b-trees, co-routines).
Shared by every backend, since EQP detail format is sqlite's, not
the driver's. JS regexes lack inline flags, hence the per-platform
patterns.(norm-name s)Strip identifier quoting and ASCII-lower, the shared normalisation for names from SQL and from the database.
Strip identifier quoting and ASCII-lower, the shared normalisation for names from SQL and from the database.
(pure-deps sql)Grammar-only dependency profile of a SELECT statement - tables,
columns and star-resolved wildcards, all normalised - or nil when
the grammar cannot parse it. Engine code wants deps, which
blends this with the EQP-reported table set.
Grammar-only dependency profile of a SELECT statement - tables, columns and star-resolved wildcards, all normalised - or nil when the grammar cannot parse it. Engine code wants `deps`, which blends this with the EQP-reported table set.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |