fix(instr): case-insensitive match and fix wrapped-substr clobber (#3650) - #3729
Open
chiliec wants to merge 1 commit into
Open
fix(instr): case-insensitive match and fix wrapped-substr clobber (#3650)#3729chiliec wants to merge 1 commit into
chiliec wants to merge 1 commit into
Conversation
…b#3650) INSTR had two defects: 1. It compared runes exactly, so it was case-sensitive for nonbinary strings. MySQL's INSTR is multibyte-safe and case-insensitive unless one argument is a binary string, e.g. INSTR('xyza','A') should return 4, not 0. 2. In the StringWrapper branch of the substring argument, the unwrapped value was assigned to text (the haystack) instead of subtext (the needle). A wrapped substring therefore left subtext empty and overwrote the haystack, making INSTR return 1 unconditionally. findSubsequence now folds case per rune, matching LOCATE's existing case-insensitive behavior, and the StringWrapper branch assigns to subtext.
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.
What
Closes #3650.
INSTRhad two independent defects insql/expression/function/substring.go:Case-sensitive for nonbinary strings.
findSubsequencecomparedrunes exactly, so
INSTR('xyza','A')returned0. Per the MySQL 8.4manual,
INSTR"is multibyte safe, and is case-sensitive only if atleast one argument is a binary string" — it should return
4. Thismirrors the existing case-insensitive behavior of
LOCATE(
locate.goalready lower-cases both sides).Wrapped substring clobbered the haystack. In
Instr.Eval, thesql.StringWrappercase of the substring argument assigned theunwrapped value to
text(the haystack) instead ofsubtext(theneedle). A wrapped substring (e.g. Dolt's out-of-band
TextStoragevalues) therefore left
subtextempty and overwrotetext, sofindSubsequenceran with an empty needle andINSTRreturned1unconditionally.
Fix
findSubsequencenow folds case per rune via a smallruneEqualFoldhelper (
a == b || unicode.ToLower(a) == unicode.ToLower(b)).sql.StringWrapperbranch of the substring argument now assigns tosubtext.+10/-2 in
substring.go, plus one new test file.Tests
Added
TestInstrIssue3650covering both defects (case-insensitiveneedle/haystack/mixed + no-match, and wrapped-substring match/no-match/
case-insensitive).
Validation (real results)
Toolchain: Go 1.26.2,
-tags gms_pure_go(pure-Go regex engine, no cgo).reverted (
git checkoutonsubstring.go), all 6 sub-tests fail(case-insensitive cases return
0, wrapped-substr cases return1).Restoring the fix turns them green:
TestInstrstill passes.gofmt -lclean on both files.The full
./sql/expression/function/package suite passes except forTestRegexpReplaceWithFlags/{sensitive_and_multiline_flags,all_flags},which fail identically on a clean
maincheckout under thegms_pure_gotag (a CRLF difference in the pure-Go regex engine) — theyare outside this diff and unrelated to this change.
First-time contributor here — happy to add an
enginetest/queriesend-to-end case or adjust anything if you'd prefer.