app/vmselect/promql: fill gaps on right side with values from left side of or operator in the same way as Prometheus does

Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/552
This commit is contained in:
Aliaksandr Valialkin 2020-06-18 23:04:59 +03:00
parent 08495360b0
commit 88e1b7d144
2 changed files with 27 additions and 3 deletions

View file

@ -310,9 +310,22 @@ func binaryOpOr(bfa *binaryOpFuncArg) ([]*timeseries, error) {
for _, tss := range mLeft { for _, tss := range mLeft {
rvs = append(rvs, tss...) rvs = append(rvs, tss...)
} }
for k, tss := range mRight { for k, tssRight := range mRight {
if mLeft[k] == nil { tssLeft := mLeft[k]
rvs = append(rvs, tss...) if tssLeft == nil {
rvs = append(rvs, tssRight...)
continue
}
// Fill gaps in tssLeft with values from tssRight as Prometheus does.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/552
valuesRight := tssRight[0].Values
for _, tsLeft := range tssLeft {
valuesLeft := tsLeft.Values
for i, v := range valuesLeft {
if math.IsNaN(v) {
valuesLeft[i] = valuesRight[i]
}
}
} }
} }
return rvs, nil return rvs, nil

View file

@ -1849,6 +1849,17 @@ func TestExecSuccess(t *testing.T) {
resultExpected := []netstorage.Result{r} resultExpected := []netstorage.Result{r}
f(q, resultExpected) f(q, resultExpected)
}) })
t.Run(`scalar or scalar`, func(t *testing.T) {
t.Parallel()
q := `time() > 1400 or 123`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{123, 123, 123, 1600, 1800, 2000},
Timestamps: timestampsExpected,
}
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`timseries-with-tags unless 2`, func(t *testing.T) { t.Run(`timseries-with-tags unless 2`, func(t *testing.T) {
t.Parallel() t.Parallel()
q := `label_set(time(), "foo", "bar") unless 2` q := `label_set(time(), "foo", "bar") unless 2`