Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow empty matcher at store gateway to fetch all postings #7260

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions pkg/store/bucket.go
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down
46 changes: 46 additions & 0 deletions pkg/store/bucket_e2e_test.go
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 8 additions & 2 deletions test/e2e/query_test.go
Expand Up @@ -2320,12 +2320,18 @@ func TestQueryTenancyEnforcement(t *testing.T) {
nil,
)

// default-tenant cannot attempt to view other tenants data, by setting the tenant id
// default-tenant cannot attempt to view other tenants data, by setting the tenant id.
// Query all data from `default-tenant` after enforcing tenancy.
queryAndAssertSeries(t, ctx, querierEnforce.Endpoint("http"), func() string { return "{tenant_id=\"tenant-01\"}" },
time.Now, promclient.QueryOptions{
Deduplicate: false,
},
nil,
[]model.Metric{
{
"c": "3",
"tenant_id": "default-tenant",
},
},
)

rangeQuery(t, ctx, querierEnforce.Endpoint("http"), func() string { return testQueryA }, timestamp.FromTime(now.Add(-time.Hour)), timestamp.FromTime(now.Add(time.Hour)), 3600,
Expand Down