fix(python): reject empty fts queries - #640
Open
HosniBelfeki wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR hardens Python-side validation and execution for FTS (full-text search) queries by rejecting empty/whitespace-only Fts inputs and ensuring stripped FTS text is forwarded to the native _Fts binding.
Changes:
- Treat whitespace-only
fts.query_string/fts.match_stringas empty via centralized stripping helpers and updatehas_fts()accordingly. - Add validation to reject
Ftsobjects that provide neither a non-emptyquery_stringnormatch_string. - Update the executor to forward stripped FTS strings to native
_Fts, and add tests covering empty inputs and stripping behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| python/zvec/model/param/query.py | Adds stripped/normalized FTS accessors and strengthens _validate() to reject empty FTS. |
| python/zvec/executor/query_executor.py | Forwards stripped FTS strings into the native _Fts query object. |
| python/tests/test_query_executor.py | Adds a regression test ensuring FTS text is stripped before reaching native query construction. |
| python/tests/test_fts_query.py | Adds parameterized tests asserting empty/whitespace-only FTS inputs are rejected. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+117
to
+121
| def _fts_query_string(self) -> str: | ||
| return self.fts.query_string.strip() if self.fts and self.fts.query_string else "" | ||
|
|
||
| def _fts_match_string(self) -> str: | ||
| return self.fts.match_string.strip() if self.fts and self.fts.match_string else "" |
HosniBelfeki
force-pushed
the
fix-python-fts-empty-validation
branch
from
August 2, 2026 14:58
44847cc to
ccf8325
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (3)
python/zvec/model/param/query.py:125
_fts_match_string()has the same issue as_fts_query_string(): calling.strip()on a non-string will raise at runtime, and could also pass an unexpected type into the native query layer. Add a runtime type check and raiseValueErrorwith a clear message.
def _fts_match_string(self) -> str:
return (
self.fts.match_string.strip() if self.fts and self.fts.match_string else ""
)
python/zvec/model/param/query.py:120
_fts_query_string()assumesself.fts.query_stringis astrand calls.strip()unconditionally when truthy. Since dataclasses don't enforce types at runtime, passing a non-string (e.g., int/bytes) will raiseAttributeError(or propagate an unexpected type into the native_Ftsbinding). Add an explicit runtime type check and raise a clearValueErrorinstead.
This issue also appears on line 122 of the same file.
def _fts_query_string(self) -> str:
return (
self.fts.query_string.strip() if self.fts and self.fts.query_string else ""
)
python/zvec/executor/query_executor.py:223
QueryExecutoris callingQuerymethods that are underscore-prefixed (_fts_query_string(),_fts_match_string()), which implies they are private implementation details. Since this behavior is now relied on across modules, consider making these helpers part of the publicQueryAPI (e.g.,fts_query_string()/fts_match_string()orfts_query_string_strippedproperties) and update callers accordingly to avoid coupling to internals.
def _apply_fts(self, query: Query, search_query: _SearchQuery) -> None:
"""Set FTS query on search_query if the query has FTS parameters."""
if query.has_fts():
fts = _Fts()
fts.query_string = query._fts_query_string()
fts.match_string = query._fts_match_string()
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.
Summary
This hardens Python FTS query validation by rejecting Fts objects that do not provide a non-empty query_string or match_string. Previously, empty or whitespace-only FTS values could pass Python-side validation and reach the native query path.
The executor now forwards stripped FTS text to the native _Fts object, keeping validation and execution behavior consistent.
Tests
Note: focused pytest against local source is blocked in this workspace because zvec._zvec is not built locally.