mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
app/vmselect/promql: return back the behaviour for deriv()
function when the lookbehind window doesnt contain enough points
It is expected that the `deriv(m[d])` returns non-empty value if the lookbehind window `d`
contains less than 2 samples in the same way as `rate()` does.
This is a follow-up after 3e084be06b
.
This commit is contained in:
parent
3e084be06b
commit
c45210a6f9
3 changed files with 39 additions and 4 deletions
|
@ -6239,6 +6239,39 @@ func TestExecSuccess(t *testing.T) {
|
||||||
resultExpected := []netstorage.Result{r}
|
resultExpected := []netstorage.Result{r}
|
||||||
f(q, resultExpected)
|
f(q, resultExpected)
|
||||||
})
|
})
|
||||||
|
t.Run(`deriv(1)`, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
q := `deriv(1)`
|
||||||
|
r := netstorage.Result{
|
||||||
|
MetricName: metricNameExpected,
|
||||||
|
Values: []float64{0, 0, 0, 0, 0, 0},
|
||||||
|
Timestamps: timestampsExpected,
|
||||||
|
}
|
||||||
|
resultExpected := []netstorage.Result{r}
|
||||||
|
f(q, resultExpected)
|
||||||
|
})
|
||||||
|
t.Run(`deriv(time())`, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
q := `deriv(2*time())`
|
||||||
|
r := netstorage.Result{
|
||||||
|
MetricName: metricNameExpected,
|
||||||
|
Values: []float64{2, 2, 2, 2, 2, 2},
|
||||||
|
Timestamps: timestampsExpected,
|
||||||
|
}
|
||||||
|
resultExpected := []netstorage.Result{r}
|
||||||
|
f(q, resultExpected)
|
||||||
|
})
|
||||||
|
t.Run(`deriv(-time())`, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
q := `deriv(-time())`
|
||||||
|
r := netstorage.Result{
|
||||||
|
MetricName: metricNameExpected,
|
||||||
|
Values: []float64{-1, -1, -1, -1, -1, -1},
|
||||||
|
Timestamps: timestampsExpected,
|
||||||
|
}
|
||||||
|
resultExpected := []netstorage.Result{r}
|
||||||
|
f(q, resultExpected)
|
||||||
|
})
|
||||||
t.Run(`delta(time())`, func(t *testing.T) {
|
t.Run(`delta(time())`, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
q := `delta(time())`
|
q := `delta(time())`
|
||||||
|
|
|
@ -151,7 +151,6 @@ var rollupFuncsCannotAdjustWindow = map[string]bool{
|
||||||
"holt_winters": true,
|
"holt_winters": true,
|
||||||
"idelta": true,
|
"idelta": true,
|
||||||
"increase": true,
|
"increase": true,
|
||||||
"deriv": true,
|
|
||||||
"predict_linear": true,
|
"predict_linear": true,
|
||||||
"resets": true,
|
"resets": true,
|
||||||
"avg_over_time": true,
|
"avg_over_time": true,
|
||||||
|
@ -865,9 +864,13 @@ func linearRegression(rfa *rollupFuncArg) (float64, float64) {
|
||||||
// before calling rollup funcs.
|
// before calling rollup funcs.
|
||||||
values := rfa.values
|
values := rfa.values
|
||||||
timestamps := rfa.timestamps
|
timestamps := rfa.timestamps
|
||||||
if len(values) < 2 {
|
n := float64(len(values))
|
||||||
|
if n == 0 {
|
||||||
return nan, nan
|
return nan, nan
|
||||||
}
|
}
|
||||||
|
if n == 1 {
|
||||||
|
return values[0], 0
|
||||||
|
}
|
||||||
|
|
||||||
// See https://en.wikipedia.org/wiki/Simple_linear_regression#Numerical_example
|
// See https://en.wikipedia.org/wiki/Simple_linear_regression#Numerical_example
|
||||||
interceptTime := rfa.currTimestamp
|
interceptTime := rfa.currTimestamp
|
||||||
|
@ -882,7 +885,6 @@ func linearRegression(rfa *rollupFuncArg) (float64, float64) {
|
||||||
tvSum += dt * v
|
tvSum += dt * v
|
||||||
ttSum += dt * dt
|
ttSum += dt * dt
|
||||||
}
|
}
|
||||||
n := float64(len(values))
|
|
||||||
k := (tvSum - tSum*vSum/n) / (ttSum - tSum*tSum/n)
|
k := (tvSum - tSum*vSum/n) / (ttSum - tSum*tSum/n)
|
||||||
v := vSum/n - k*tSum/n
|
v := vSum/n - k*tSum/n
|
||||||
return v, k
|
return v, k
|
||||||
|
|
|
@ -979,7 +979,7 @@ func TestRollupFuncsNoWindow(t *testing.T) {
|
||||||
}
|
}
|
||||||
rc.Timestamps = getTimestamps(rc.Start, rc.End, rc.Step)
|
rc.Timestamps = getTimestamps(rc.Start, rc.End, rc.Step)
|
||||||
values := rc.Do(nil, testValues, testTimestamps)
|
values := rc.Do(nil, testValues, testTimestamps)
|
||||||
valuesExpected := []float64{nan, -2879.310344827588, 127.87627310448904, -496.5831435079728, nan}
|
valuesExpected := []float64{nan, -2879.310344827588, 127.87627310448904, -496.5831435079728, 0}
|
||||||
timestampsExpected := []int64{0, 40, 80, 120, 160}
|
timestampsExpected := []int64{0, 40, 80, 120, 160}
|
||||||
testRowsEqual(t, values, rc.Timestamps, valuesExpected, timestampsExpected)
|
testRowsEqual(t, values, rc.Timestamps, valuesExpected, timestampsExpected)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue