app/vmselect/promql: align the behavior of or, and and unless operators with on (labels) modifier to Prometheus

Previously VictoriaMetrics could return unexpected result of the right-hand side operand
had multiple time series with the given set of labels mentioned in `on(labels)`.

See https://github.com/VictoriaMetrics/VictoriaMetrics/pull/1643
This commit is contained in:
Aliaksandr Valialkin 2021-09-24 00:46:22 +03:00
parent 8148bfc06d
commit 1115c2f235
No known key found for this signature in database
GPG Key ID: A72BEC6CD3D0DED1
2 changed files with 28 additions and 12 deletions

View File

@ -303,12 +303,18 @@ func binaryOpAnd(bfa *binaryOpFuncArg) ([]*timeseries, error) {
if tssLeft == nil { if tssLeft == nil {
continue continue
} }
// Add gaps to tssLeft if there are gaps at valuesRight. // Add gaps to tssLeft if there are gaps at tssRight.
valuesRight := tssRight[0].Values
for _, tsLeft := range tssLeft { for _, tsLeft := range tssLeft {
valuesLeft := tsLeft.Values valuesLeft := tsLeft.Values
for i, v := range valuesRight { for i := range valuesLeft {
if math.IsNaN(v) { hasValue := false
for _, tsRight := range tssRight {
if !math.IsNaN(tsRight.Values[i]) {
hasValue = true
break
}
}
if !hasValue {
valuesLeft[i] = nan valuesLeft[i] = nan
} }
} }
@ -333,12 +339,18 @@ func binaryOpOr(bfa *binaryOpFuncArg) ([]*timeseries, error) {
} }
// Fill gaps in tssLeft with values from tssRight as Prometheus does. // Fill gaps in tssLeft with values from tssRight as Prometheus does.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/552 // See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/552
valuesRight := tssRight[0].Values
for _, tsLeft := range tssLeft { for _, tsLeft := range tssLeft {
valuesLeft := tsLeft.Values valuesLeft := tsLeft.Values
for i, v := range valuesLeft { for i, v := range valuesLeft {
if math.IsNaN(v) { if !math.IsNaN(v) {
valuesLeft[i] = valuesRight[i] continue
}
for _, tsRight := range tssRight {
vRight := tsRight.Values[i]
if !math.IsNaN(vRight) {
valuesLeft[i] = vRight
break
}
} }
} }
} }
@ -355,13 +367,15 @@ func binaryOpUnless(bfa *binaryOpFuncArg) ([]*timeseries, error) {
rvs = append(rvs, tssLeft...) rvs = append(rvs, tssLeft...)
continue continue
} }
// Add gaps to tssLeft if the are no gaps at valuesRight. // Add gaps to tssLeft if the are no gaps at tssRight.
valuesRight := tssRight[0].Values
for _, tsLeft := range tssLeft { for _, tsLeft := range tssLeft {
valuesLeft := tsLeft.Values valuesLeft := tsLeft.Values
for i, v := range valuesRight { for i := range valuesLeft {
if !math.IsNaN(v) { for _, tsRight := range tssRight {
valuesLeft[i] = nan if !math.IsNaN(tsRight.Values[i]) {
valuesLeft[i] = nan
break
}
} }
} }
} }

View File

@ -6,6 +6,8 @@ sort: 15
## tip ## tip
* BUGFIX: align behavior of the queries `a or on (labels) b`, `a and on (labels) b` and `a unless on (labels) b` where `b` has multiple time series with the given `labels` to Prometheus behavior. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/1643).
## [v1.66.2](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.66.2) ## [v1.66.2](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.66.2)