app/vmselect: fix binary comparison func (#1667)

The fix makes the binary comparison func to check for NaNs
before executing the actual comparison. This prevents VM
to return values for non-existing samples for expressions
which contain bool comparisons. Please see added test
for example.
This commit is contained in:
Roman Khavronenko 2021-09-30 12:24:17 +03:00 committed by Aliaksandr Valialkin
parent 57eb5ef194
commit 95ddfda894
No known key found for this signature in database
GPG Key ID: A72BEC6CD3D0DED1
2 changed files with 25 additions and 3 deletions

View File

@ -59,12 +59,12 @@ func newBinaryOpCmpFunc(cf func(left, right float64) bool) binaryOpFunc {
} }
return nan return nan
} }
if cf(left, right) {
return 1
}
if math.IsNaN(left) { if math.IsNaN(left) {
return nan return nan
} }
if cf(left, right) {
return 1
}
return 0 return 0
} }
return newBinaryOpFunc(cfe) return newBinaryOpFunc(cfe)

View File

@ -2180,6 +2180,28 @@ func TestExecSuccess(t *testing.T) {
resultExpected := []netstorage.Result{r} resultExpected := []netstorage.Result{r}
f(q, resultExpected) f(q, resultExpected)
}) })
t.Run(`nan!=bool scalar`, func(t *testing.T) {
t.Parallel()
q := `(time() > 1234) !=bool 1400`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{nan, nan, 0, 1, 1, 1},
Timestamps: timestampsExpected,
}
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`scalar!=bool nan`, func(t *testing.T) {
t.Parallel()
q := `1400 !=bool (time() > 1234)`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{nan, nan, 0, 1, 1, 1},
Timestamps: timestampsExpected,
}
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`scalar > time()`, func(t *testing.T) { t.Run(`scalar > time()`, func(t *testing.T) {
t.Parallel() t.Parallel()
q := `123 > time()` q := `123 > time()`