Don't do literal regex matching optimisation when case insensitive. (#8013)

Fixes #7994

Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
pull/7989/head
Brian Brazil 4 years ago committed by GitHub
parent 8dbfa14607
commit 924ce978b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -86,10 +86,10 @@ func optimizeConcatRegex(r *syntax.Regexp) (prefix, suffix, contains string) {
// Given Prometheus regex matchers are always anchored to the begin/end // Given Prometheus regex matchers are always anchored to the begin/end
// of the text, if the first/last operations are literals, we can safely // of the text, if the first/last operations are literals, we can safely
// treat them as prefix/suffix. // treat them as prefix/suffix.
if sub[0].Op == syntax.OpLiteral { if sub[0].Op == syntax.OpLiteral && (sub[0].Flags&syntax.FoldCase) == 0 {
prefix = string(sub[0].Rune) prefix = string(sub[0].Rune)
} }
if last := len(sub) - 1; sub[last].Op == syntax.OpLiteral { if last := len(sub) - 1; sub[last].Op == syntax.OpLiteral && (sub[last].Flags&syntax.FoldCase) == 0 {
suffix = string(sub[last].Rune) suffix = string(sub[last].Rune)
} }
@ -97,7 +97,7 @@ func optimizeConcatRegex(r *syntax.Regexp) (prefix, suffix, contains string) {
// 1st one. We do not keep the whole list of literals to simplify the // 1st one. We do not keep the whole list of literals to simplify the
// fast path. // fast path.
for i := 1; i < len(sub)-1; i++ { for i := 1; i < len(sub)-1; i++ {
if sub[i].Op == syntax.OpLiteral { if sub[i].Op == syntax.OpLiteral && (sub[i].Flags&syntax.FoldCase) == 0 {
contains = string(sub[i].Rune) contains = string(sub[i].Rune)
break break
} }

@ -76,6 +76,13 @@ func TestOptimizeConcatRegex(t *testing.T) {
{regex: ".*foo.*bar.*", prefix: "", suffix: "", contains: "foo"}, {regex: ".*foo.*bar.*", prefix: "", suffix: "", contains: "foo"},
{regex: ".*(foo|bar).*", prefix: "", suffix: "", contains: ""}, {regex: ".*(foo|bar).*", prefix: "", suffix: "", contains: ""},
{regex: ".*[abc].*", prefix: "", suffix: "", contains: ""}, {regex: ".*[abc].*", prefix: "", suffix: "", contains: ""},
{regex: ".*((?i)abc).*", prefix: "", suffix: "", contains: ""},
{regex: ".*(?i:abc).*", prefix: "", suffix: "", contains: ""},
{regex: "(?i:abc).*", prefix: "", suffix: "", contains: ""},
{regex: ".*(?i:abc)", prefix: "", suffix: "", contains: ""},
{regex: ".*(?i:abc)def.*", prefix: "", suffix: "", contains: "def"},
{regex: "(?i).*(?-i:abc)def", prefix: "", suffix: "", contains: "abc"},
{regex: ".*(?msU:abc).*", prefix: "", suffix: "", contains: "abc"},
} }
for _, c := range cases { for _, c := range cases {

@ -58,6 +58,51 @@ eval instant at 0s http_requests{foo!~"bar", job="api-server", instance="1", x!=
http_requests{job="api-server", instance="1", group="production"} 0 http_requests{job="api-server", instance="1", group="production"} 0
http_requests{job="api-server", instance="1", group="canary"} 0 http_requests{job="api-server", instance="1", group="canary"} 0
# https://github.com/prometheus/prometheus/issues/7994
eval instant at 8000s rate(http_requests{group=~"(?i:PRO).*"}[1m])
{job="api-server", instance="0", group="production"} 1
{job="api-server", instance="1", group="production"} 2
eval instant at 8000s rate(http_requests{group=~".*?(?i:PRO).*"}[1m])
{job="api-server", instance="0", group="production"} 1
{job="api-server", instance="1", group="production"} 2
eval instant at 8000s rate(http_requests{group=~".*(?i:DUC).*"}[1m])
{job="api-server", instance="0", group="production"} 1
{job="api-server", instance="1", group="production"} 2
eval instant at 8000s rate(http_requests{group=~".*(?i:TION)"}[1m])
{job="api-server", instance="0", group="production"} 1
{job="api-server", instance="1", group="production"} 2
eval instant at 8000s rate(http_requests{group=~".*(?i:TION).*?"}[1m])
{job="api-server", instance="0", group="production"} 1
{job="api-server", instance="1", group="production"} 2
eval instant at 8000s rate(http_requests{group=~"((?i)PRO).*"}[1m])
{job="api-server", instance="0", group="production"} 1
{job="api-server", instance="1", group="production"} 2
eval instant at 8000s rate(http_requests{group=~".*((?i)DUC).*"}[1m])
{job="api-server", instance="0", group="production"} 1
{job="api-server", instance="1", group="production"} 2
eval instant at 8000s rate(http_requests{group=~".*((?i)TION)"}[1m])
{job="api-server", instance="0", group="production"} 1
{job="api-server", instance="1", group="production"} 2
eval instant at 8000s rate(http_requests{group=~"(?i:PRODUCTION)"}[1m])
{job="api-server", instance="0", group="production"} 1
{job="api-server", instance="1", group="production"} 2
eval instant at 8000s rate(http_requests{group=~".*(?i:C).*"}[1m])
{job="api-server", instance="0", group="production"} 1
{job="api-server", instance="1", group="production"} 2
{job="api-server", instance="0", group="canary"} 3
{job="api-server", instance="1", group="canary"} 4
clear clear
load 1m load 1m
metric1{a="a"} 0+1x100 metric1{a="a"} 0+1x100

Loading…
Cancel
Save