diff --git a/pkg/logql/log/filter.go b/pkg/logql/log/filter.go index e1530fec2c49..764584b5889e 100644 --- a/pkg/logql/log/filter.go +++ b/pkg/logql/log/filter.go @@ -471,6 +471,16 @@ func simplifyAlternate(reg *syntax.Regexp) (Filterer, bool) { // Anything else is rejected. func simplifyConcat(reg *syntax.Regexp, baseLiteral []byte) (Filterer, bool) { clearCapture(reg.Sub...) + // remove empty match as we don't need them for filtering + i := 0 + for _, r := range reg.Sub { + if r.Op == syntax.OpEmptyMatch { + continue + } + reg.Sub[i] = r + i++ + } + reg.Sub = reg.Sub[:i] // we support only simplication of concat operation with 3 sub expressions. // for instance .*foo.*bar contains 4 subs (.*+foo+.*+bar) and can't be simplified. if len(reg.Sub) > 3 { diff --git a/pkg/logql/log/filter_test.go b/pkg/logql/log/filter_test.go index bd28f26868a9..0e3d112e24c9 100644 --- a/pkg/logql/log/filter_test.go +++ b/pkg/logql/log/filter_test.go @@ -56,6 +56,7 @@ func Test_SimplifiedRegex(t *testing.T) { {"(?i)foo", true, newContainsFilter([]byte("foo"), true), true}, {"(?i)界", true, newContainsFilter([]byte("界"), true), true}, {"(?i)ïB", true, newContainsFilter([]byte("ïB"), true), true}, + {"(?:)foo|fatal|exception", true, newOrFilter(newOrFilter(newContainsFilter([]byte("foo"), false), newContainsFilter([]byte("fatal"), false)), newContainsFilter([]byte("exception"), false)), true}, // regex we are not supporting. {"[a-z]+foo", true, nil, false}, @@ -160,6 +161,7 @@ func Benchmark_LineFilter(b *testing.B) { {"(node:24) buzz*"}, {"(HTTP/.*\\\"|HEAD|GET) (2..|5..)"}, {"\"@l\":\"(Warning|Error|Fatal)\""}, + {"(?:)foo|fatal|exception"}, } { benchmarkRegex(b, test.re, logline, true) benchmarkRegex(b, test.re, logline, false)