Repository navigation
A literal one line fix for full-text search missing matches in clips over ~2000 characters - #1173
Open
AlexErrant wants to merge 1 commit into
Open
AlexErrant wants to merge 1 commit into
AlexErrant wants to merge 1 commit into
Conversation
SQLite (3.44+, including the bundled 3.53.2) reads BLOB values larger than 4000 bytes from overflow pages through a column cache that tags them as UTF-8, even in a UTF-16 database. LIKE and REGEXP then read the UTF-16 bytes as UTF-8 and stop at the first zero byte, so full-text search only saw the first character of large CF_UNICODETEXT clips and effectively searched only the 500-character description. Passing the blob through substr() makes SQLite re-tag the function result with the database encoding, so the whole text is searched again.
This branch has not been deployed
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
With Search Full Text on, clips whose
CF_UNICODETEXTdata is over 4000 bytes (~2000 characters) only match on their first ~500 characters (the description). Shorter clips search normally. Wildcard, simple, and regex search are all affected.Regression
This broke in 1522219 (#666), which replaced the bundled SQLite 3.33.0 with SQLite3MultipleCiphers (SQLite 3.45.2).
Cause
Newer SQLite caches large values read from overflow pages (
vdbeColumnFromOverflow, for values over 4000 bytes). For a BLOB, that path callssqlite3VdbeMemSetStr(..., 0, ...), which tags the value as UTF-8 whatever the database encoding is. Ditto's database is UTF-16LE, so whenLIKE(or Ditto'sregexp) convertsData.ooDatato text, it reads the UTF-16 bytes as UTF-8 and stops at the first zero byte, which comes right after the first character.Fix
Search
substr(Data.ooData, 1)instead ofData.ooData. SQLite re-tags a function's BLOB result with the database encoding (OP_Functioncallssqlite3VdbeChangeEncoding), so the full text converts correctly.Testing
ooData LIKE '%e%'overCF_UNICODETEXTrows that contain an "e" after the first character. It matched 38,118 / 38,118 rows of 4000 bytes or less, but only 31 / 2,316 rows over 4000 bytes. Withsubstr(ooData, 1), it matched 2,316 / 2,316.