app/vmselect/promql: properly calculate histogram_quantile() over zero buckets and only a single non-zero le="+Inf"` bucket like Prometheus does

This commit is contained in:
Aliaksandr Valialkin 2021-02-24 00:40:16 +02:00
parent 2c44178645
commit f4135b0d14
3 changed files with 22 additions and 7 deletions

View file

@ -2757,6 +2757,26 @@ func TestExecSuccess(t *testing.T) {
resultExpected := []netstorage.Result{} resultExpected := []netstorage.Result{}
f(q, resultExpected) f(q, resultExpected)
}) })
t.Run(`histogram_quantile(single-value-inf-le)`, func(t *testing.T) {
t.Parallel()
q := `histogram_quantile(0.6, label_set(100, "le", "+Inf"))`
resultExpected := []netstorage.Result{}
f(q, resultExpected)
})
t.Run(`histogram_quantile(single-value-inf-le)`, func(t *testing.T) {
t.Parallel()
q := `histogram_quantile(0.6, (
label_set(100, "le", "+Inf"),
label_set(0, "le", "42"),
))`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{42, 42, 42, 42, 42, 42},
Timestamps: timestampsExpected,
}
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`histogram_quantile(single-value-valid-le)`, func(t *testing.T) { t.Run(`histogram_quantile(single-value-valid-le)`, func(t *testing.T) {
t.Parallel() t.Parallel()
q := `histogram_quantile(0.6, label_set(100, "le", "200"))` q := `histogram_quantile(0.6, label_set(100, "le", "200"))`

View file

@ -649,14 +649,9 @@ func transformHistogramQuantile(tfa *transformFuncArg) ([]*timeseries, error) {
m := groupLeTimeseries(tss) m := groupLeTimeseries(tss)
// Calculate quantile for each group in m // Calculate quantile for each group in m
lastNonInf := func(i int, xss []leTimeseries) float64 { lastNonInf := func(i int, xss []leTimeseries) float64 {
for len(xss) > 0 { for len(xss) > 0 {
xsLast := xss[len(xss)-1] xsLast := xss[len(xss)-1]
v := xsLast.ts.Values[i]
if v == 0 {
return nan
}
if !math.IsInf(xsLast.le, 0) { if !math.IsInf(xsLast.le, 0) {
return xsLast.le return xsLast.le
} }
@ -700,8 +695,7 @@ func transformHistogramQuantile(tfa *transformFuncArg) ([]*timeseries, error) {
continue continue
} }
if math.IsInf(le, 0) { if math.IsInf(le, 0) {
vv := lastNonInf(i, xss) break
return vv, vv, inf
} }
if v == vPrev { if v == vPrev {
return lePrev, lePrev, v return lePrev, lePrev, v

View file

@ -17,6 +17,7 @@
* BUGFIX: vmagent: properly perform graceful shutdown on `SIGINT` and `SIGTERM` signals. The graceful shutdown has been broken in `v1.54.0`. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1065 * BUGFIX: vmagent: properly perform graceful shutdown on `SIGINT` and `SIGTERM` signals. The graceful shutdown has been broken in `v1.54.0`. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1065
* BUGFIX: reduce the probability of `duplicate time series` errors when querying Kubernetes metrics. * BUGFIX: reduce the probability of `duplicate time series` errors when querying Kubernetes metrics.
* BUGFIX: properly calculate `histogram_quantile()` over time series with only a single non-zero bucket with `{le="+Inf"}`. Previously `NaN` was returned, now the value for the last bucket before `{le="+Inf"}` is returned like Prometheus does.
# [v1.54.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.54.1) # [v1.54.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.54.1)