diff --git a/app/vmselect/promql/exec_test.go b/app/vmselect/promql/exec_test.go index ac4d2a1b55..5074b5e079 100644 --- a/app/vmselect/promql/exec_test.go +++ b/app/vmselect/promql/exec_test.go @@ -3056,6 +3056,7 @@ func TestExecSuccess(t *testing.T) { t.Parallel() q := `sort(buckets_limit(2, ( alias(label_set(100, "le", "inf", "x", "y"), "metric"), + alias(label_set(98, "le", "300", "x", "y"), "metric"), alias(label_set(52, "le", "200", "x", "y"), "metric"), alias(label_set(50, "le", "120", "x", "y"), "metric"), alias(label_set(20, "le", "70", "x", "y"), "metric"), @@ -3064,14 +3065,14 @@ func TestExecSuccess(t *testing.T) { )))` r1 := netstorage.Result{ MetricName: metricNameExpected, - Values: []float64{50, 50, 50, 50, 50, 50}, + Values: []float64{52, 52, 52, 52, 52, 52}, Timestamps: timestampsExpected, } r1.MetricName.MetricGroup = []byte("metric") r1.MetricName.Tags = []storage.Tag{ { Key: []byte("le"), - Value: []byte("120"), + Value: []byte("200"), }, { Key: []byte("x"), diff --git a/app/vmselect/promql/transform.go b/app/vmselect/promql/transform.go index 003074fba0..7fdc3ded79 100644 --- a/app/vmselect/promql/transform.go +++ b/app/vmselect/promql/transform.go @@ -363,8 +363,9 @@ func transformBucketsLimit(tfa *transformFuncArg) ([]*timeseries, error) { xxMinIdx = i } } - if xxMinIdx+1 == len(leGroup) { - // Merge the `inf` bucket with the previous bucket in order to save accuracy. + // Merge the leGroup[xxMinIdx] bucket with the smallest adjacent bucket in order to preserve + // the maximum accuracy. + if xxMinIdx+1 == len(leGroup) || (xxMinIdx > 0 && leGroup[xxMinIdx-1].hits < leGroup[xxMinIdx+1].hits) { xxMinIdx-- } leGroup[xxMinIdx+1].hits += leGroup[xxMinIdx].hits