fix(promql): Ensure native histogram values copied in subqueries (#16879)

Signed-off-by: 🌲 Harry 🌊 John 🏔 <johrry@amazon.com>
This commit is contained in:
Harry John 2025-07-20 23:54:54 -07:00 committed by GitHub
parent 3602785a89
commit b09cf6be8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 2 deletions

View File

@ -3985,3 +3985,49 @@ func TestInconsistentHistogramCount(t *testing.T) {
require.Equal(t, countFromHistogram, countFromFunction, "histogram_count function should return the same count as the histogram itself")
}
// TestSubQueryHistogramsCopy reproduces a bug where native histogram values from subqueries are not copied.
func TestSubQueryHistogramsCopy(t *testing.T) {
start := time.Unix(0, 0)
end := time.Unix(144, 0)
step := time.Second * 3
load := `load 2m
http_request_duration_seconds{pod="nginx-1"} {{schema:0 count:110 sum:818.00 buckets:[1 14 95]}}+{{schema:0 count:110 buckets:[1 14 95]}}x20
http_request_duration_seconds{pod="nginx-2"} {{schema:0 count:210 sum:1598.00 buckets:[1 19 190]}}+{{schema:0 count:210 buckets:[1 19 190]}}x30`
subQuery := `min_over_time({__name__="http_request_duration_seconds"}[1h:1m])`
testQuery := `rate({__name__="http_request_duration_seconds"}[3m])`
ctx := context.Background()
for i := 0; i < 100; i++ {
queryable := promqltest.LoadedStorage(t, load)
engine := promqltest.NewTestEngine(t, false, 0, promqltest.DefaultMaxSamplesPerQuery)
q, err := engine.NewRangeQuery(ctx, queryable, nil, subQuery, start, end, step)
require.NoError(t, err)
q.Exec(ctx)
q.Close()
queryable.Close()
}
for i := 0; i < 100; i++ {
queryable := promqltest.LoadedStorage(t, load)
engine := promqltest.NewTestEngine(t, false, 0, promqltest.DefaultMaxSamplesPerQuery)
q, err := engine.NewRangeQuery(ctx, queryable, nil, testQuery, start, end, step)
require.NoError(t, err)
result := q.Exec(ctx)
mat, err := result.Matrix()
require.NoError(t, err)
for _, s := range mat {
for _, h := range s.Histograms {
require.NotEmpty(t, h.H.PositiveBuckets)
}
}
q.Close()
queryable.Close()
}
}

View File

@ -475,8 +475,12 @@ func (ssi *storageSeriesIterator) AtHistogram(*histogram.Histogram) (int64, *his
panic(errors.New("storageSeriesIterator: AtHistogram not supported"))
}
func (ssi *storageSeriesIterator) AtFloatHistogram(*histogram.FloatHistogram) (int64, *histogram.FloatHistogram) {
return ssi.currT, ssi.currH
func (ssi *storageSeriesIterator) AtFloatHistogram(fh *histogram.FloatHistogram) (int64, *histogram.FloatHistogram) {
if fh == nil {
return ssi.currT, ssi.currH.Copy()
}
ssi.currH.CopyTo(fh)
return ssi.currT, fh
}
func (ssi *storageSeriesIterator) AtT() int64 {