diff --git a/storage/nhcb_querier.go b/storage/nhcb_querier.go index 717646e9f5..5ec9867724 100644 --- a/storage/nhcb_querier.go +++ b/storage/nhcb_querier.go @@ -81,8 +81,9 @@ func (q *NHCBAsClassicQuerier) Select(ctx context.Context, sortSeries bool, hint return ErrSeriesSet(err) } + seriesSets := make([]SeriesSet, 0, 2) if len(classicSeries) > 0 { - return &bufferedSeriesSet{series: classicSeries} + seriesSets = append(seriesSets, &bufferedSeriesSet{series: classicSeries}) } baseMatchers = append(baseMatchers, labels.MustNewMatcher(labels.MatchEqual, model.MetricNameLabel, metricName)) @@ -90,11 +91,15 @@ func (q *NHCBAsClassicQuerier) Select(ctx context.Context, sortSeries bool, hint if nhcbSet.Err() != nil { return nhcbSet } - - return &nhcbToClassicSeriesSet{ + seriesSets = append(seriesSets, &nhcbToClassicSeriesSet{ nhcbSet: nhcbSet, suffix: suffix, metricName: metricName, + }) + + return &multipleSeriesSet{ + seriesSet: seriesSets, + idx: 0, } } @@ -162,6 +167,43 @@ func extractHistogramSuffix(matchers []*labels.Matcher) (string, string, []*labe return baseName, suffix, baseMatchers } +type multipleSeriesSet struct { + seriesSet []SeriesSet + idx int +} + +func (m *multipleSeriesSet) Next() bool { + if m.idx >= len(m.seriesSet) { + return false + } + if !(m.seriesSet[m.idx].Next()) { + m.idx++ + return m.Next() + } + return true +} + +func (m *multipleSeriesSet) At() Series { + return m.seriesSet[m.idx].At() +} + +func (m *multipleSeriesSet) Err() error { + for _, ss := range m.seriesSet { + if err := ss.Err(); err != nil { + return err + } + } + return nil +} + +func (m *multipleSeriesSet) Warnings() annotations.Annotations { + var w annotations.Annotations + for _, ss := range m.seriesSet { + w.Merge(ss.Warnings()) + } + return w +} + // nhcbToClassicSeriesSet converts NHCB series to classic histogram series format. type nhcbToClassicSeriesSet struct { nhcbSet SeriesSet diff --git a/storage/nhcb_querier_test.go b/storage/nhcb_querier_test.go index 2ce39af7bd..d642700a3b 100644 --- a/storage/nhcb_querier_test.go +++ b/storage/nhcb_querier_test.go @@ -140,6 +140,18 @@ func TestNHCBAsClassicQuerier_Select(t *testing.T) { expectedCount: 1, expectedSuffix: "_sum", }, + { + name: "both classic and NHCB - return both", + queryMatchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, model.MetricNameLabel, "http_requests_bucket")}, + classicSeries: []Series{ + NewListSeries(labels.FromStrings("__name__", "http_requests_bucket", "le", "1"), []chunks.Sample{fSample{t: 1, f: 5}}), + }, + nhcbSeries: []Series{ + NewListSeries(labels.FromStrings("__name__", "http_requests"), []chunks.Sample{hSample{t: 1, h: nhcb}}), + }, + expectedCount: 5, + expectedSuffix: "_bucket", + }, { name: "no classic and no NHCB - return empty", queryMatchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, model.MetricNameLabel, "http_requests_bucket")},