fix(search): keep natural-language queries on the FTS5 path instead of crashing to the LIKE fallback - #354
fix(search): keep natural-language queries on the FTS5 path instead of crashing to the LIKE fallback#354Milgauss wants to merge 1 commit into
Conversation
…e LIKE fallback
sanitize_fts5_query only stripped a fixed set of FTS5 operator
characters, leaving apostrophes, commas, question marks and other
conversational punctuation in the unquoted query text. FTS5 parses
those as syntax errors ("fts5: syntax error near ..."), so store.search
silently degraded to the LIKE fallback for nearly any conversational
query, e.g. "don't". One production store logged the fallback warning
300+ times.
Fix: outside quoted phrases, keep only bareword-safe characters
(alphanumerics, underscore, whitespace). That is exactly the token
alphabet the unicode61 tokenizer indexed, so replacing everything else
with spaces matches the index instead of erroring. Quoted phrases pass
through verbatim, as before.
The LIKE fallback itself must NOT use that strict sanitization: it
matches raw stored content, so apostrophes, emoji and CJK punctuation
have to survive for the fallback to find them (emoji-only queries
would otherwise return nothing). Split the helper in two:
sanitize_fts5_query (strict, FTS MATCH paths) and
sanitize_like_terms_query (previous operator-stripping behavior, used
by the _search_like paths in store.py and dag.py).
Tests: new unit tests for the sanitizer plus store-level tests
asserting that "don't", a full conversational sentence, and a quoted
phrase with trailing punctuation all return results on the FTS path
with no "falling back to LIKE" warning. On unpatched code they fail
with the exact production symptom.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uao4D1LKM35dKzivcsWVf
|
Closing as superseded. Current Verified rather than assumed: this PR's three |
Problem
Any conversational search query containing an apostrophe, comma, question mark, or most other punctuation (for example
don't) is a syntax error to FTS5.store.searchcatches the error and silently degrades to the LIKE fallback, so in practice nearly every natural-language query runs on the slow, unranked fallback path instead of the FTS index.Mechanism
sanitize_fts5_query(search_query.py:47) only replaces the fixed operator set_FTS5_SPECIAL_CHARS(search_query.py:36), leaving apostrophes, commas, and question marks in the unquoted query text.store.search(store.py:931) passes the result tomessages_fts MATCH, FTS5 raisesfts5: syntax error near "'", and the handler atstore.py:997logs "FTS message search failed, falling back to LIKE" and degrades.dag.py:427has the same path for summary search.Fix
Outside quoted phrases, keep only bareword-safe characters (alphanumerics, underscore, whitespace) and replace everything else with spaces. That is exactly the token alphabet the unicode61 tokenizer indexed, so the sanitized query matches the index instead of erroring;
don'tbecomesdon t, which matches rows containingdon't. Quoted phrases pass through verbatim, as before.The LIKE fallback must not use that strict sanitization: it matches raw stored content, so apostrophes, emoji, and CJK punctuation have to survive for the fallback to find them (an emoji-only query would otherwise produce zero terms and return nothing). The helper is therefore split in two:
sanitize_fts5_query(strict, used by the FTS MATCH paths) andsanitize_like_terms_query(the previous operator-stripping behavior, used by_search_likeinstore.pyanddag.py).Verification
New tests cover:
don'treturning its row on the FTS path with no fallback warning, a full conversational sentence (what did I tell you, don't you remember?) searching without anyOperationalErroror fallback, quoted phrases with trailing conversational punctuation still matching as phrases, and sanitizer unit cases. On unpatched main the new tests fail with the exact production error (fts5: syntax error near ","). The fulltests/test_lcm_core.pysuite passes (288 tests), including the existing emoji and LIKE-fallback regression tests.Incident evidence
One live store logged the FTS-to-LIKE fallback warning over 300 times, meaning nearly every conversational search had been silently running on the degraded fallback path.