From a11509212bcf55df0c93a4552be09f8ba69d4474 Mon Sep 17 00:00:00 2001 From: Ben Ye Date: Fri, 5 Apr 2024 05:21:11 +0000 Subject: [PATCH] allow empty matcher at store gateway to fetch all postings Signed-off-by: Ben Ye --- pkg/store/bucket.go | 6 +++++ pkg/store/bucket_e2e_test.go | 46 ++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/pkg/store/bucket.go b/pkg/store/bucket.go index 1951c217bf5..ff6ad1b9094 100644 --- a/pkg/store/bucket.go +++ b/pkg/store/bucket.go @@ -112,6 +112,7 @@ const ( var ( errBlockSyncConcurrencyNotValid = errors.New("the block sync concurrency must be equal or greater than 1.") hashPool = sync.Pool{New: func() interface{} { return xxhash.New() }} + allPostingMatcher = labels.MustNewMatcher(labels.MatchEqual, "", "") ) type bucketStoreMetrics struct { @@ -1478,6 +1479,11 @@ func (s *BucketStore) Series(req *storepb.SeriesRequest, seriesSrv storepb.Store if !ok { continue } + // If no matcher left after removing external label matchers, + // fallback to use all posting matcher. + if len(blockMatchers) == 0 { + blockMatchers = []*labels.Matcher{allPostingMatcher} + } // Sort matchers to make sure we generate the same cache key // when fetching expanded postings. sortedBlockMatchers := newSortedMatchers(blockMatchers) diff --git a/pkg/store/bucket_e2e_test.go b/pkg/store/bucket_e2e_test.go index c91fb4096df..7ee1b724703 100644 --- a/pkg/store/bucket_e2e_test.go +++ b/pkg/store/bucket_e2e_test.go @@ -464,6 +464,23 @@ func testBucketStore_e2e(t *testing.T, ctx context.Context, s *storeSuite) { {{Name: "a", Value: "1"}, {Name: "c", Value: "2"}, {Name: "ext2", Value: "value2"}}, }, }, + // External label only. Should fetch all series matching external label. + { + req: &storepb.SeriesRequest{ + Matchers: []storepb.LabelMatcher{ + {Type: storepb.LabelMatcher_EQ, Name: "ext1", Value: "value1"}, + }, + MinTime: mint, + MaxTime: maxt, + }, + expectedChunkLen: 3, + expected: [][]labelpb.ZLabel{ + {{Name: "a", Value: "1"}, {Name: "b", Value: "1"}, {Name: "ext1", Value: "value1"}}, + {{Name: "a", Value: "1"}, {Name: "b", Value: "2"}, {Name: "ext1", Value: "value1"}}, + {{Name: "a", Value: "2"}, {Name: "b", Value: "1"}, {Name: "ext1", Value: "value1"}}, + {{Name: "a", Value: "2"}, {Name: "b", Value: "2"}, {Name: "ext1", Value: "value1"}}, + }, + }, } { if ok := t.Run(fmt.Sprint(i), func(t *testing.T) { srv := newStoreSeriesServer(ctx) @@ -766,6 +783,20 @@ func TestBucketStore_LabelNames_e2e(t *testing.T) { }, expected: nil, }, + "ext1=value1 matcher": { + req: &storepb.LabelNamesRequest{ + Start: timestamp.FromTime(minTime), + End: timestamp.FromTime(maxTime), + Matchers: []storepb.LabelMatcher{ + { + Type: storepb.LabelMatcher_EQ, + Name: "ext1", + Value: "value1", + }, + }, + }, + expected: []string{"a", "b", "ext1"}, + }, } { t.Run(name, func(t *testing.T) { vals, err := s.store.LabelNames(ctx, tc.req) @@ -924,6 +955,21 @@ func TestBucketStore_LabelValues_e2e(t *testing.T) { }, expected: nil, // ext1 is replaced with ext2 for series with c }, + "label a, ext1=value1": { + req: &storepb.LabelValuesRequest{ + Label: "a", + Start: timestamp.FromTime(minTime), + End: timestamp.FromTime(maxTime), + Matchers: []storepb.LabelMatcher{ + { + Type: storepb.LabelMatcher_EQ, + Name: "ext1", + Value: "value1", + }, + }, + }, + expected: []string{"1", "2"}, + }, } { t.Run(name, func(t *testing.T) { vals, err := s.store.LabelValues(ctx, tc.req)