mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-01 14:47:38 +00:00
lib/storage: fix matching against tag filter with empty name
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/137
This commit is contained in:
parent
5b8526e925
commit
b7c4b0c6d2
3 changed files with 84 additions and 6 deletions
|
@ -1430,7 +1430,7 @@ func matchTagFilters(mn *MetricName, tfs []*tagFilter, kb *bytesutil.ByteBuffer)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Found the matching tag name. Match for the value.
|
// Found the matching tag name. Match the value.
|
||||||
b := tag.Marshal(kb.B)
|
b := tag.Marshal(kb.B)
|
||||||
kb.B = b[:len(kb.B)]
|
kb.B = b[:len(kb.B)]
|
||||||
ok, err := matchTagFilter(b, tf)
|
ok, err := matchTagFilter(b, tf)
|
||||||
|
@ -1443,7 +1443,7 @@ func matchTagFilters(mn *MetricName, tfs []*tagFilter, kb *bytesutil.ByteBuffer)
|
||||||
tagMatched = true
|
tagMatched = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if !tagMatched {
|
if !tagMatched && !tf.isNegative {
|
||||||
// Matching tag name wasn't found.
|
// Matching tag name wasn't found.
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -804,8 +804,8 @@ func TestMatchTagFilters(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
if ok {
|
if !ok {
|
||||||
t.Fatalf("Shouldn't match")
|
t.Fatalf("Should match")
|
||||||
}
|
}
|
||||||
tfs.Reset(mn.AccountID, mn.ProjectID)
|
tfs.Reset(mn.AccountID, mn.ProjectID)
|
||||||
if err := tfs.Add([]byte("non-existing-tag"), []byte("foob.+metric"), true, true); err != nil {
|
if err := tfs.Add([]byte("non-existing-tag"), []byte("foob.+metric"), true, true); err != nil {
|
||||||
|
@ -815,8 +815,19 @@ func TestMatchTagFilters(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
if ok {
|
if !ok {
|
||||||
t.Fatalf("Shouldn't match")
|
t.Fatalf("Should match")
|
||||||
|
}
|
||||||
|
tfs.Reset(mn.AccountID, mn.ProjectID)
|
||||||
|
if err := tfs.Add([]byte("non-existing-tag"), []byte(".+"), true, true); err != nil {
|
||||||
|
t.Fatalf("cannot add regexp, negative filter: %s", err)
|
||||||
|
}
|
||||||
|
ok, err = matchTagFilters(&mn, toTFPointers(tfs.tfs), &bb)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Should match")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Negative match by existing tag
|
// Negative match by existing tag
|
||||||
|
@ -910,6 +921,17 @@ func TestMatchTagFilters(t *testing.T) {
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Fatalf("Should match")
|
t.Fatalf("Should match")
|
||||||
}
|
}
|
||||||
|
tfs.Reset(mn.AccountID, mn.ProjectID)
|
||||||
|
if err := tfs.Add([]byte("key 3"), []byte(""), true, false); err != nil {
|
||||||
|
t.Fatalf("cannot add regexp, negative filter: %s", err)
|
||||||
|
}
|
||||||
|
ok, err = matchTagFilters(&mn, toTFPointers(tfs.tfs), &bb)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Should match")
|
||||||
|
}
|
||||||
|
|
||||||
// Positive match by multiple tags and MetricGroup
|
// Positive match by multiple tags and MetricGroup
|
||||||
tfs.Reset(mn.AccountID, mn.ProjectID)
|
tfs.Reset(mn.AccountID, mn.ProjectID)
|
||||||
|
|
|
@ -308,6 +308,62 @@ func TestTagFilterMatchSuffix(t *testing.T) {
|
||||||
mismatch("bar")
|
mismatch("bar")
|
||||||
match("xhttpbar")
|
match("xhttpbar")
|
||||||
})
|
})
|
||||||
|
t.Run("non-empty-string-regexp-negative-match", func(t *testing.T) {
|
||||||
|
value := ".+"
|
||||||
|
isNegative := true
|
||||||
|
isRegexp := true
|
||||||
|
expectedPrefix := tvNoTrailingTagSeparator("")
|
||||||
|
init(value, isNegative, isRegexp, expectedPrefix)
|
||||||
|
if len(tf.orSuffixes) != 0 {
|
||||||
|
t.Fatalf("unexpected non-zero number of or suffixes: %d; %q", len(tf.orSuffixes), tf.orSuffixes)
|
||||||
|
}
|
||||||
|
|
||||||
|
match("")
|
||||||
|
mismatch("x")
|
||||||
|
mismatch("foo")
|
||||||
|
})
|
||||||
|
t.Run("non-empty-string-regexp-match", func(t *testing.T) {
|
||||||
|
value := ".+"
|
||||||
|
isNegative := false
|
||||||
|
isRegexp := true
|
||||||
|
expectedPrefix := tvNoTrailingTagSeparator("")
|
||||||
|
init(value, isNegative, isRegexp, expectedPrefix)
|
||||||
|
if len(tf.orSuffixes) != 0 {
|
||||||
|
t.Fatalf("unexpected non-zero number of or suffixes: %d; %q", len(tf.orSuffixes), tf.orSuffixes)
|
||||||
|
}
|
||||||
|
|
||||||
|
mismatch("")
|
||||||
|
match("x")
|
||||||
|
match("foo")
|
||||||
|
})
|
||||||
|
t.Run("match-all-regexp-negative-match", func(t *testing.T) {
|
||||||
|
value := ".*"
|
||||||
|
isNegative := true
|
||||||
|
isRegexp := true
|
||||||
|
expectedPrefix := tvNoTrailingTagSeparator("")
|
||||||
|
init(value, isNegative, isRegexp, expectedPrefix)
|
||||||
|
if len(tf.orSuffixes) != 0 {
|
||||||
|
t.Fatalf("unexpected non-zero number of or suffixes: %d; %q", len(tf.orSuffixes), tf.orSuffixes)
|
||||||
|
}
|
||||||
|
|
||||||
|
mismatch("")
|
||||||
|
mismatch("x")
|
||||||
|
mismatch("foo")
|
||||||
|
})
|
||||||
|
t.Run("match-all-regexp-match", func(t *testing.T) {
|
||||||
|
value := ".*"
|
||||||
|
isNegative := false
|
||||||
|
isRegexp := true
|
||||||
|
expectedPrefix := tvNoTrailingTagSeparator("")
|
||||||
|
init(value, isNegative, isRegexp, expectedPrefix)
|
||||||
|
if len(tf.orSuffixes) != 0 {
|
||||||
|
t.Fatalf("unexpected non-zero number of or suffixes: %d; %q", len(tf.orSuffixes), tf.orSuffixes)
|
||||||
|
}
|
||||||
|
|
||||||
|
match("")
|
||||||
|
match("x")
|
||||||
|
match("foo")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetOrValues(t *testing.T) {
|
func TestGetOrValues(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue