core/translate: SQLite-compatible affinity check for index seeks#7385
Open
jussisaurio wants to merge 1 commit into
Open
core/translate: SQLite-compatible affinity check for index seeks#7385jussisaurio wants to merge 1 commit into
jussisaurio wants to merge 1 commit into
Conversation
27fc1b0 to
eecf763
Compare
Fixes #7373, #7374, and a related IN-list/IN-subquery affinity bypass surfaced during review. The bug. Index-driven seeks applied the indexed column's affinity to the seek key. SQLite applies the comparison's resolved affinity (`sqlite3CompareAffinity`). The two diverge for cross-type comparisons: -- l.txt TEXT, r.flag INTEGER, '' stored in l. SELECT l.txt, r.flag FROM l JOIN r ON l.txt <= r.flag; Comparison affinity here is NUMERIC. The TEXT index forced TEXT onto the integer probe ('0') and the b-tree comparator then ranked '' below '0' lexicographically — rather than SQLite's type ordering (INTEGER < TEXT) that puts every integer below every text. False match. Same shape broke `WHERE x IN (SELECT y ...)` with TEXT x / INTEGER y: the IN ephemeral stored integers, the TEXT index never coerced them, and the b-tree sorted every integer below every text key — zero rows. The fix. Port SQLite's `sqlite3IndexAffinityOk` (`Affinity::index_affinity_ok`), cache the resolved comparison affinity on each `Constraint` at construction, and consult it at every index-selection site (regular b-tree, auto-index, ephemeral-subquery, IN-seek) so incompatible indexes are rejected up front. At emission, `index_seek_affinities` now reads the cached comparison affinity instead of the column's. Snapshot churn: 7 files. All are affinity-character shifts (D→C for cross-type numeric comparisons) or removal of redundant TEXT-on-TEXT Affinity opcodes that SQLite never emits either. Fixes #7373. Fixes #7374.
eecf763 to
8f58d4f
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.
Fixes #7373, #7374, and a related IN-list/IN-subquery affinity bypass surfaced during review.
Bug
Index seeks applied the indexed column's affinity to the seek key. SQLite applies the comparison's resolved affinity (
sqlite3CompareAffinity). The two diverge for cross-type comparisons:Comparison affinity here is NUMERIC. The TEXT index forced TEXT onto the integer probe ('0') and the b-tree comparator then ranked '' below '0' lexicographically rather than SQLite's type ordering (INTEGER < TEXT) that puts every integer below every text. False match.
The same shape broke
WHERE x IN (SELECT y ...)with TEXT x / INTEGER y: the IN ephemeral stored integers, the TEXT index never coerced them, and the b-tree sorted every integer below every text key — zero rows.Fix
sqlite3IndexAffinityOk(Affinity::index_affinity_ok)Constraintat construction,index_seek_affinitiesnow reads the cached comparison affinity instead of the column's.Snapshot churn: 7 files. All are affinity-character shifts (D→C for cross-type numeric comparisons) or removal of redundant TEXT-on-TEXT Affinity opcodes that SQLite never emits either.
Fixes #7373.
Fixes #7374.