From 034ab65c6bab3229e456b3760108bdc2b54b29ad Mon Sep 17 00:00:00 2001 From: Keegan Smith Date: Wed, 26 Aug 2026 08:49:45 +0000 Subject: [PATCH] fix/search: measure regexp literals in runes The trigram optimizer operates on rune trigrams, but its eligibility check measured UTF-8 bytes. This sent short non-ASCII literals through an inconsistent planning path and could produce surprising composite trees. Use the parsed rune count so the optimizer and substring planner apply the same threshold. Amp-Thread-ID: https://ampcode.com/threads/T-01a03d06-0149-77e8-9156-33171018a250 --- index/eval.go | 2 +- index/eval_test.go | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/index/eval.go b/index/eval.go index 4bba7322e..665168145 100644 --- a/index/eval.go +++ b/index/eval.go @@ -625,7 +625,7 @@ func (d *indexData) regexpToMatchTreeRecursive(r *syntax.Regexp, minTextSize int switch r.Op { case syntax.OpLiteral: s := string(r.Rune) - if len(s) >= minTextSize { + if len(r.Rune) >= minTextSize { ignoreCase := syntax.FoldCase == (r.Flags & syntax.FoldCase) mt, err := d.newSubstringMatchTree(&query.Substring{Pattern: s, FileName: fileName, CaseSensitive: !ignoreCase && caseSensitive}) return mt, true, !strings.Contains(s, "\n"), err diff --git a/index/eval_test.go b/index/eval_test.go index 1d20b9e6f..e090c1242 100644 --- a/index/eval_test.go +++ b/index/eval_test.go @@ -90,6 +90,9 @@ func TestRegexpParse(t *testing.T) { cases := []testcase{ {"(foo|)bar", substrMT("bar"), false, false}, {"(foo|)", &bruteForceMatchTree{}, false, false}, + {"éa", &bruteForceMatchTree{}, false, false}, + {"éab", substrMT("éab"), true, false}, + {"(éa|êb)", &bruteForceMatchTree{}, false, false}, {"(foo|bar)baz.*bla", &andMatchTree{[]matchTree{ &orMatchTree{[]matchTree{ substrMT("foo"),