fix(sql): validate table qualifiers in FTS function column args (SQLR-15)#168
Merged
Conversation
…-15) fts_match() / bm25_score() extract their column argument syntactically (they need the column name to find the index, not its value), so the qualifier never passed through RowScope::lookup and SQLR-14's check. A bogus qualifier was silently dropped: fts_match(bogus.body, 'q') ran as fts_match(body, 'q'). Add RowScope::scope_name() (Some(name) for single-table scope, None for joined / group-row scopes) and run check_single_scope_qualifier in resolve_fts_args when the column arg is a CompoundIdentifier. Error wording matches SQLR-14. 3+-part identifiers now error like the main evaluator instead of being silently truncated. Audited the other syntactic extraction sites: JSON and vec_distance helpers evaluate args through eval_expr_scope (already covered); pager catalog re-parses are trusted engine-written SQL. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
Problem
SQLR-14 (#167) made single-table scope reject unknown table qualifiers in plain column references, but
fts_match/bm25_scoreextract their column argument syntactically (they need the column name to find the FTS index, not its value), so the qualifier never went throughRowScope::lookup:This was the explicitly-deferred gap in #167's "Known gaps".
Fix
scope_name(&self) -> Option<&str>to theRowScopetrait —Some(alias-or-table-name)forSingleTableScope,NoneforJoinedScope(per-qualifier resolution happens inlookup) andGroupRowScope(output rows carry no qualifier).resolve_fts_argsnow runscheck_single_scope_qualifieron a two-partCompoundIdentifiercolumn arg, producing the SQLR-14 wording:unknown table qualifier '<q>' in column reference '<q>.<col>'. Identifiers with 3+ parts now error like the main evaluator instead of silently truncating.The optimizer probes (
try_fts_probe,identify_indexed_arg_and_literal) only match bare identifiers, so qualified args always take the scalar path — which now validates.Audit of other syntactic extraction sites (per acceptance criteria)
vec_distance_*— no gap: their args are evaluated througheval_expr_scope→scope.lookup, which already runs the SQLR-14 check.pager/mod.rs) — trusted engine-writtensqlrite_masterSQL, not user input. No change.CREATE INDEX ix ON t (bogus.col)strips qualifier) and SQLR Release v0.1.2 #18 (aggregating-pathORDER BY bogus.namestrips qualifier when matching output columns).Tests
7 new end-to-end tests in
src/sql/mod.rscovering the acceptance matrix: matching table-name qualifier (incl. case-insensitive), matching alias, alias-shadows-table-name, bogus qualifier in WHERE (fts_match), WHERE-comparison and ORDER BY (bm25_score), and a ranking test proving qualified args still produce correct top-k via the scalar path. The three negative tests fail on the unfixed executor and pass with the fix.Full verification: workspace test suite (CI exclusions) all green,
cargo fmt --checkclean, clippy/doc warnings unchanged (pre-existing, none on changed code). REPL + file-backed save/reopen smoke checks pass.Docs
docs/supported-sql.md— qualified-references bullet now covers FTS function args (SQLR-15)docs/fts.md— qualified-arg behavior documented for both functions, plus a note that qualified args skip the optimizer probedocs/sql-engine.md— expression-evaluator section mentions theRowScope::scope_name()path🤖 Generated with Claude Code