simplify: replace ~160-line hand-rolled FTS5 pre-validator with run-then-fallback #21
Labels
No labels
code-review
correctness
dos
performance
security
severity/high
severity/low
severity/medium
tech-debt
Kind/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
h-dv/code-index#21
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
fts5_safe_querydecides pass-through-vs-phrase-wrap using a ~160-line hand-rolled FTS5 grammar pre-validator (looks_like_fts5_syntax,parens_look_like_fts5_grouping,preceded_by_word, byte-walking depth/quote/NEAR() state) plus a 245-line test module. This replicates validation SQLite already performs and is necessarily an approximation of FTS5's real grammar, so it carries permanent false-positive/negative risk against the actual parser.Where
crates/daemon/src/local_index.rs:1873-2035(validator) +2088-2333(tests). Single production caller:search_text(local_index.rs:1325).Severity
Low — a JUDGMENT CALL, not a defect. The current code is correct and heavily tested. This is a simplification/maintainability proposal, filed for tracking, not a bug.
Proposal
Execute the raw user query as
MATCHfirst; only on a SQLite FTS5 parse error, retry phrase-wrapped (escape embedded quotes + wrap in"…"). SQLite is the authoritative source of truth for its own grammar, so this preserves the exact "pass valid syntax through / wrap invalid as a phrase" intent while collapsing the hand-rolled parser and its test surface.Trade-off to weigh before doing this: a run-then-fallback issues up to two queries for invalid input, and turns a parse error into a caught-and-retried path (must ensure the first failed statement doesn't leave the connection in a bad state — it doesn't for read-only MATCH, but verify). Keep a small regression suite mapping representative inputs → expected wrapped/passed form.
Surfaced by the v0.5.8 ultradeep review (architecture dimension, CONFIRMED as a simplification opportunity).
Acceptance
fts5_safe_query's behavior (which inputs pass through vs get phrase-wrapped) is preserved for the existing test corpus.Implemented on
fix/ultradeep-review-findings(commit820fd9d).The ~160-line hand-rolled validator (
looks_like_fts5_syntax+parens_look_like_fts5_grouping+preceded_by_word) is replaced by a cheap structural-operator scan plus SQLite as the authority on its own grammar:step— a syntax error means "not a real query" → fall back to the phrase form.The probe runs only for operator-bearing input, so plain searches (the overwhelming majority) issue no second query. A failed read-only MATCH leaves the connection usable (verified).
Behavior preserved (acceptance): a new
full_corpus_matches_legacy_validator_decisionstest runs all 60 inputs from the retired validator's corpus against a real trigramfiles_ftsand asserts identical pass-through-vs-phrase outcomes. I empirically confirmed SQLite reproduces the old validator's decision on every corpus case; the one input where a naive run-raw-first would diverge (a*b) is kept as a literal phrase by a 5-line prefix-token guard inhas_fts5_operator.Net +209/−420 in
local_index.rs. No new FTS5 crash surface — malformed operator queries fall back via SQLite's own verdict. Closing.