Skip to content

Commit eef0958

Browse files
authored
Quietly truncate queries ranging into future (#532)
To fix #472 Grafana queries for current month/year would mostly fail due to weekly tables not existing into future. Fix is to detect end of time range is future and quietly change to now Additionally if begin of time-range is future, then immediately return empty resultset
1 parent 19a5d3f commit eef0958

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

pkg/chunk/chunk_store.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,19 @@ func (c *Store) Get(ctx context.Context, from, through model.Time, allMatchers .
155155
return nil, fmt.Errorf("invalid query, through < from (%d < %d)", through, from)
156156
}
157157

158+
now := model.Now()
159+
if from.After(now) {
160+
// time-span start is in future ... regard as legal
161+
util.WithContext(ctx).Debugf("Whole timerange %v..%v in future (now=%v) yield empty resultset", through, from, now)
162+
return []local.SeriesIterator{}, nil
163+
}
164+
165+
if through.After(now) {
166+
// time-span end is in future ... regard as legal
167+
util.WithContext(ctx).Debugf("Adjusting end timerange=%v from future to now=%v", through, now)
168+
through = now // Avoid processing future part - otherwise some schemas could fail with eg non-existent table gripes
169+
}
170+
158171
// Fetch metric name chunks if the matcher is of type equal,
159172
metricNameMatcher, matchers, ok := util.ExtractMetricNameMatcherFromMatchers(allMatchers)
160173
if ok && metricNameMatcher.Type == metric.Equal {

pkg/chunk/chunk_store_test.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,30 @@ func TestChunkStore_Get_concrete(t *testing.T) {
165165
t.Fatal(err)
166166
}
167167

168-
iterators, err := store.Get(ctx, now.Add(-time.Hour), now, tc.matchers...)
168+
// Query with ordinary time-range
169+
iterators1, err := store.Get(ctx, now.Add(-time.Hour), now, tc.matchers...)
169170
require.NoError(t, err)
170171

171-
sort.Sort(ByFingerprint(iterators))
172-
if !reflect.DeepEqual(tc.expect, iterators) {
173-
t.Fatalf("%s: wrong chunks - %s", tc.query, test.Diff(tc.expect, iterators))
172+
sort.Sort(ByFingerprint(iterators1))
173+
if !reflect.DeepEqual(tc.expect, iterators1) {
174+
t.Fatalf("%s: wrong chunks - %s", tc.query, test.Diff(tc.expect, iterators1))
175+
}
176+
177+
// Pushing end of time-range into future should yield exact same resultset
178+
iterators2, err := store.Get(ctx, now.Add(-time.Hour), now.Add(time.Hour*24*30), tc.matchers...)
179+
require.NoError(t, err)
180+
181+
sort.Sort(ByFingerprint(iterators2))
182+
if !reflect.DeepEqual(tc.expect, iterators2) {
183+
t.Fatalf("%s: wrong chunks - %s", tc.query, test.Diff(tc.expect, iterators2))
184+
}
185+
186+
// Query with both begin & end of time-range in future should yield empty resultset
187+
iterators3, err := store.Get(ctx, now.Add(time.Hour), now.Add(time.Hour*2), tc.matchers...)
188+
require.NoError(t, err)
189+
if len(iterators3) != 0 {
190+
t.Fatalf("%s: future query should yield empty resultset ... actually got %v chunks: %#v",
191+
tc.query, len(iterators3), iterators3)
174192
}
175193
})
176194
}

0 commit comments

Comments
 (0)