fix(search-typesense)!: compile a where clause that can match nothing to a term matching nothing - #753
Merged
Conversation
… to a term matching nothing A clause whose every criterion was false compiled to no term, and a clause with no term was left out of filter_by. An absent conjunct constrains nothing, so false was compiled as true: a single misspelled field name in where turned a filtered search into the whole collection. - a clause with criteria but no terms now compiles to id:=[] – an empty identity membership, the same reading isUnsatisfiable gives one in the IR, and a term Typesense applies rather than ignores - a clause carrying no criteria at all still states nothing, not false, so it stays the vacuous no-op it reads as - onIgnoredFilter keeps reporting both, since neither compiles as written Not reachable through search(): assertValidQuery rejects an unknown field, a non-filterable one and an operator mismatch first, and isUnsatisfiable answers the empty id membership without a round-trip. It is reachable for every direct caller of buildSearchParams. BREAKING CHANGE: buildSearchParams compiles a where clause it cannot compile to “id:=[]” instead of omitting it, so a query that used to come back with every document now comes back empty. onIgnoredFilter still fires for it.
ddeboer
force-pushed
the
worktree-issue-752-empty-clause-widens
branch
from
August 20, 2026 15:36
73e4fc7 to
936a5b5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A
whereclause whose every criterion compiles to nothing was left out offilter_by– and aconjunct missing from a conjunction constrains nothing. So a clause the compiler read as false
was emitted as true: one misspelled field name turned a filtered search into the whole
collection.
The term for “nothing”
A clause with criteria but no terms now compiles to
id:=[]– an empty identity membership,“the document is one of no documents”. Not a sentinel: it is the same reading
isUnsatisfiablegives an empty
idmembership in the IR, and the one shape a filter language can spell when ithas no keyword for
false.It had to be a term the engine applies rather than ignores, so I checked the candidates against
a real Typesense 30.2 instance:
id:=``` is rejected outright (“Filter value cannot be empty”), whileid:=[]returns 0 against a baseline of 2. A new integration test insearch-engine.test.ts`pins that down – the fix is worthless if the engine ever starts ignoring the term.
A clause carrying no criteria at all (
{ or: [] }) states nothing rather than stating false,so it stays the vacuous no-op it reads as. That distinction is now the one thing
compileFilterdecides, and its JSDoc says so.
onIgnoredFilterkeeps firing for both kinds, since neither compiled as the caller wrote it –its doc now describes the two cases instead of implying every reported clause was skipped.
Reachability
Not reachable through
search():assertValidQueryrejects an unknown field, a non-filterableone and an operator mismatch before compiling, and
isUnsatisfiableanswers the emptyidmembership without a round-trip. The exposure was, and the fix is for, direct callers of the
exported
buildSearchParams.Fix #752