app/vmselect/promql: properly handle histogram_quantile(0, ...) with zero buckets

This commit is contained in:
Aliaksandr Valialkin 2019-11-23 14:02:14 +02:00
parent f8298c7f13
commit 193d553f6d
2 changed files with 53 additions and 5 deletions

View file

@ -2299,6 +2299,45 @@ func TestExecSuccess(t *testing.T) {
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`histogram_quantile(single-value-valid-le-max-phi)`, func(t *testing.T) {
t.Parallel()
q := `histogram_quantile(1, (
label_set(100, "le", "200"),
label_set(0, "le", "55"),
))`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{200, 200, 200, 200, 200, 200},
Timestamps: timestampsExpected,
}
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`histogram_quantile(single-value-valid-le-min-phi)`, func(t *testing.T) {
t.Parallel()
q := `histogram_quantile(0, (
label_set(100, "le", "200"),
label_set(0, "le", "55"),
))`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{55, 55, 55, 55, 55, 55},
Timestamps: timestampsExpected,
}
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`histogram_quantile(single-value-valid-le-min-phi-no-zero-bucket)`, func(t *testing.T) {
t.Parallel()
q := `histogram_quantile(0, label_set(100, "le", "200"))`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{0, 0, 0, 0, 0, 0},
Timestamps: timestampsExpected,
}
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`histogram_quantile(scalar-phi)`, func(t *testing.T) {
t.Parallel()
q := `histogram_quantile(time() / 2 / 1e3, label_set(100, "le", "200"))`

View file

@ -447,7 +447,15 @@ func transformHistogramQuantile(tfa *transformFuncArg) ([]*timeseries, error) {
vPrev = v
}
}
if len(xss) == 0 {
vLast := nan
for len(xss) > 0 {
vLast = xss[len(xss)-1].ts.Values[i]
if !math.IsNaN(vLast) {
break
}
xss = xss[:len(xss)-1]
}
if vLast == 0 || math.IsNaN(vLast) {
return nan
}
if phi < 0 {
@ -456,10 +464,6 @@ func transformHistogramQuantile(tfa *transformFuncArg) ([]*timeseries, error) {
if phi > 1 {
return inf
}
vLast := xss[len(xss)-1].ts.Values[i]
if vLast == 0 {
return nan
}
vReq := vLast * phi
vPrev = 0
lePrev := float64(0)
@ -471,6 +475,11 @@ func transformHistogramQuantile(tfa *transformFuncArg) ([]*timeseries, error) {
continue
}
le := xs.le
if v <= 0 {
// Skip zero buckets.
lePrev = le
continue
}
if v < vReq {
vPrev = v
lePrev = le