lib/storage: properly handle series selector matching multiple metric names plus a negative filter

Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2238

This is a follow-up for 00cbb099b6
This commit is contained in:
Aliaksandr Valialkin 2022-02-24 12:10:44 +02:00
parent af5bdb9254
commit a16f1ae565
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
3 changed files with 8 additions and 18 deletions

View file

@ -33,6 +33,7 @@ This rule is equivalent to less clear traditional one:
* FEATURE: reduce memory usage for various caches under [high churn rate](https://docs.victoriametrics.com/FAQ.html#what-is-high-churn-rate).
* BUGFIX: properly handle [series selector](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors) containing a filter for multiple metric names plus a negative filter. For example, `{__name__=~"foo|bar",job!="baz"}` . Previously VictoriaMetrics could return series with `foo` or `bar` names and with `job="baz"`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2238).
* BUGFIX: [vmgateway](https://docs.victoriametrics.com/vmgateway.html): properly parse JWT tokens if they are encoded with [URL-safe base64 encoding](https://datatracker.ietf.org/doc/html/rfc4648#section-5).

View file

@ -49,7 +49,10 @@ func convertToCompositeTagFilters(tfs *TagFilters) []*TagFilters {
hasPositiveFilter = true
}
}
if len(names) == 0 {
// If tfs have no filters on __name__ or have no non-negative filters,
// then it is impossible to construct composite tag filter.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2238
if len(names) == 0 || !hasPositiveFilter {
atomic.AddUint64(&compositeFilterMissingConversions, 1)
return []*TagFilters{tfs}
}
@ -61,7 +64,7 @@ func convertToCompositeTagFilters(tfs *TagFilters) []*TagFilters {
tfsNew := make([]tagFilter, 0, len(tfs.tfs))
for _, tf := range tfs.tfs {
if len(tf.key) == 0 {
if !hasPositiveFilter || tf.isNegative {
if tf.isNegative {
// Negative filters on metric name cannot be used for building composite filter, so leave them as is.
tfsNew = append(tfsNew, tf)
continue

View file

@ -185,7 +185,7 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
IsRegexp: false,
},
{
Key: []byte("\xfe\x03barfoo"),
Key: []byte("foo"),
Value: []byte("abc"),
IsNegative: true,
IsRegexp: false,
@ -588,21 +588,7 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
IsRegexp: true,
},
{
Key: []byte("\xfe\x03barfoo"),
Value: []byte("abc"),
IsNegative: true,
IsRegexp: false,
},
},
{
{
Key: nil,
Value: []byte("bar|foo"),
IsNegative: false,
IsRegexp: true,
},
{
Key: []byte("\xfe\x03foofoo"),
Key: []byte("foo"),
Value: []byte("abc"),
IsNegative: true,
IsRegexp: false,