Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9b4bf10
Adding support for anchored and smoothed range selectors
tcp13equals2 Nov 7, 2025
4bc430c
Update CHANGELOG.md
tcp13equals2 Nov 7, 2025
60909cd
Fix upstream tests file
tcp13equals2 Nov 7, 2025
3f66e89
Update extended_vectors.test
tcp13equals2 Nov 7, 2025
3dd1f0e
Update data.go
tcp13equals2 Nov 7, 2025
1c7b40c
Re-use the view
tcp13equals2 Nov 7, 2025
9871e70
Merge remote-tracking branch 'origin/main' into support_anchored_smoo…
tcp13equals2 Nov 7, 2025
61ca856
Update anchored.test
tcp13equals2 Nov 7, 2025
3fa4ea4
Fix tests
tcp13equals2 Nov 7, 2025
44b9386
Update astmapper.go
tcp13equals2 Nov 7, 2025
7c49f22
Address PR feedback
tcp13equals2 Nov 10, 2025
0b32e52
Merge branch 'main' into support_anchored_smoothed_selectors
tcp13equals2 Nov 10, 2025
770065d
Update smoothed.test
tcp13equals2 Nov 10, 2025
e8f0546
Merge branch 'support_anchored_smoothed_selectors' of https://github.…
tcp13equals2 Nov 10, 2025
0bf73de
Update extend_range_vector.go
tcp13equals2 Nov 10, 2025
9b48285
Merge branch 'main' into support_anchored_smoothed_selectors
tcp13equals2 Nov 11, 2025
6ffb7ed
Address PR feedback and add new CLI arg for enabling extended range s…
tcp13equals2 Nov 11, 2025
8599e17
Update extended_vectors.test
tcp13equals2 Nov 11, 2025
2eb8e88
Cursor tips
tcp13equals2 Nov 11, 2025
ae3b216
Update engine_test.go
tcp13equals2 Nov 11, 2025
aff095a
Feedback
tcp13equals2 Nov 11, 2025
c3cfc54
Updated cli help
tcp13equals2 Nov 11, 2025
69c0579
TestConfigDescriptorIsUpToDate
tcp13equals2 Nov 11, 2025
4f39452
Update rate_increase.go
tcp13equals2 Nov 11, 2025
6889720
Merge branch 'main' into support_anchored_smoothed_selectors
tcp13equals2 Nov 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
* [FEATURE] Query-frontends: Automatically adjust features used in query plans generated for remote execution based on what the available queriers support. #13017 #13164
* [FEATURE] Memberlist: Add experimental support for zone-aware routing, in order to reduce memberlist cross-AZ data transfer. #13129
* [FEATURE] Query-frontend and querier: Add experimental support for performing query planning in query-frontends and distributing portions of the plan to queriers for execution. #13058
* [FEATURE] MQE: Add support for experimental extended range selector modifiers `smoothed` and `anchored`. These can be enabled with `-query-frontend.enabled-promql-extended-range-selectors=smoothed,anchored` #13398
* [FEATURE] Querier: Add `querier.mimir-query-engine.enable-reduce-matchers` flag that enables a new MQE AST optimization pass that eliminates duplicate or redundant matchers that are part of selector expressions. #13178
* [ENHANCEMENT] Compactor, Store-gateway: Change default value of `-compactor.upload-sparse-index-headers` to `true`. This improves lazy loading performance in the store-gateway. #13089
* [ENHANCEMENT] Store-gateway: Verify CRC32 checksums for 1 out of every 128 chunks read from object storage and the chunks cache to detect corruption. #13151
Expand Down Expand Up @@ -56,6 +57,7 @@
* `-ruler-storage.gcs.max-retries`
* [ENHANCEMENT] Usage-tracker: Improve first snapshot loading & rehash speed. #13284
* [ENHANCEMENT] Ruler: Implemented `OperatorControllableErrorClassifier` for rule evaluation, allowing differentiation between operator-controllable errors (e.g., storage failures, 5xx errors, rate limiting) and user-controllable errors (e.g., bad queries, validation errors, 4xx errors). This change affects the rule evaluation failure metric `prometheus_rule_evaluation_failures_total`, which now includes a `reason` label with values `operator` or `user` to distinguish between them. #13313
* [ENHANCEMENT] Query-frontend: Limits middleware will record different error messages when experimental functions, aggregations, or extended range selector modifiers are used but not enabled for a tenant. #13398
* [BUGFIX] Compactor: Fix potential concurrent map writes. #13053
* [BUGFIX] Query-frontend: Fix issue where queries sometimes fail with `failed to receive query result stream message: rpc error: code = Canceled desc = context canceled` if remote execution is enabled. #13084
* [BUGFIX] Query-frontend: Fix issue where query stats, such as series read, did not include the parameters to the `histogram_quantile` and `histogram_fraction` functions if remote execution was enabled. #13084
Expand Down
10 changes: 10 additions & 0 deletions cmd/mimir/config-descriptor.json
Original file line number Diff line number Diff line change
Expand Up @@ -5753,6 +5753,16 @@
"fieldFlag": "query-frontend.enabled-promql-experimental-functions",
"fieldType": "string"
},
{
"kind": "field",
"name": "enabled_promql_extended_range_selectors",
"required": false,
"desc": "Enable certain experimental PromQL extended range selector modifiers, which are subject to being changed or removed at any time, on a per-tenant basis. Defaults to empty which means all experimental modifiers are disabled. Set to 'all' to enable all experimental modifiers.",
"fieldValue": null,
"fieldDefaultValue": "",
"fieldFlag": "query-frontend.enabled-promql-extended-range-selectors",
"fieldType": "string"
},
{
"kind": "field",
"name": "prom2_range_compat",
Expand Down
2 changes: 2 additions & 0 deletions cmd/mimir/help-all.txt.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2349,6 +2349,8 @@ Usage of ./cmd/mimir/mimir:
[experimental] If set to true and the Mimir query engine is in use, use remote execution to evaluate queries in queriers.
-query-frontend.enabled-promql-experimental-functions comma-separated-list-of-strings
Enable certain experimental PromQL functions, which are subject to being changed or removed at any time, on a per-tenant basis. Defaults to empty which means all experimental functions are disabled. Set to 'all' to enable all experimental functions.
-query-frontend.enabled-promql-extended-range-selectors comma-separated-list-of-strings
Enable certain experimental PromQL extended range selector modifiers, which are subject to being changed or removed at any time, on a per-tenant basis. Defaults to empty which means all experimental modifiers are disabled. Set to 'all' to enable all experimental modifiers.
-query-frontend.extra-propagated-headers comma-separated-list-of-strings
Comma-separated list of request header names to allow to pass through to the rest of the query path. This is in addition to a list of required headers that the read path needs.
-query-frontend.grpc-client-config.backoff-max-period duration
Expand Down
2 changes: 2 additions & 0 deletions cmd/mimir/help.txt.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,8 @@ Usage of ./cmd/mimir/mimir:
Cache statistics of processed samples on results cache.
-query-frontend.enabled-promql-experimental-functions comma-separated-list-of-strings
Enable certain experimental PromQL functions, which are subject to being changed or removed at any time, on a per-tenant basis. Defaults to empty which means all experimental functions are disabled. Set to 'all' to enable all experimental functions.
-query-frontend.enabled-promql-extended-range-selectors comma-separated-list-of-strings
Enable certain experimental PromQL extended range selector modifiers, which are subject to being changed or removed at any time, on a per-tenant basis. Defaults to empty which means all experimental modifiers are disabled. Set to 'all' to enable all experimental modifiers.
-query-frontend.log-queries-longer-than duration
Log queries that are slower than the specified duration. Set to 0 to disable. Set to < 0 to enable on all queries.
-query-frontend.max-queriers-per-tenant int
Expand Down
1 change: 1 addition & 0 deletions docs/sources/mimir/configure/about-versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ The following features are currently experimental:
- Remote execution of queries in queriers: `-query-frontend.enable-remote-execution=true`
- Performing query sharding within MQE: `-query-frontend.use-mimir-query-engine-for-sharding=true`
- Rewriting of queries to optimize processing: `-query-frontend.rewrite-histogram-queries` and `-query-frontend.rewrite-propagate-matchers`
- Enable experimental Prometheus extended range selector modifiers `smoothed` and `anchored` (`-query-frontend.enabled-promql-extended-range-selectors=smoothed,anchored`)
- Query-scheduler
- `-query-scheduler.querier-forget-delay`
- Store-gateway
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3986,6 +3986,13 @@ blocked_requests:
# CLI flag: -query-frontend.enabled-promql-experimental-functions
[enabled_promql_experimental_functions: <string> | default = ""]

# Enable certain experimental PromQL extended range selector modifiers, which
# are subject to being changed or removed at any time, on a per-tenant basis.
# Defaults to empty which means all experimental modifiers are disabled. Set to
# 'all' to enable all experimental modifiers.
# CLI flag: -query-frontend.enabled-promql-extended-range-selectors
[enabled_promql_extended_range_selectors: <string> | default = ""]

# (experimental) Rewrite queries using the same range selector and resolution
# [X:X] which don't work in Prometheus 3.0 to a nearly identical form that works
# with Prometheus 3.0 semantics
Expand Down
7 changes: 4 additions & 3 deletions operations/mimir/mimir-flags-defaults.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@
"server.grpc-max-recv-msg-size-bytes": 104857600,
"server.grpc-max-send-msg-size-bytes": 104857600,
"server.grpc-max-concurrent-streams": 100,
"server.grpc.keepalive.max-connection-idle": 9223372036854776000,
"server.grpc.keepalive.max-connection-age": 9223372036854776000,
"server.grpc.keepalive.max-connection-age-grace": 9223372036854776000,
"server.grpc.keepalive.max-connection-idle": 9223372036854775807,
"server.grpc.keepalive.max-connection-age": 9223372036854775807,
"server.grpc.keepalive.max-connection-age-grace": 9223372036854775807,
"server.grpc.keepalive.time": 7200000000000,
"server.grpc.keepalive.timeout": 20000000000,
"server.grpc.keepalive.min-time-between-pings": 10000000000,
Expand Down Expand Up @@ -393,6 +393,7 @@
"query-frontend.results-cache-ttl-for-errors": 300000000000,
"query-frontend.max-query-expression-size-bytes": 0,
"query-frontend.enabled-promql-experimental-functions": "",
"query-frontend.enabled-promql-extended-range-selectors": "",
"query-frontend.labels-query-optimizer-enabled": true,
"querier.label-names-and-values-results-max-size-bytes": 419430400,
"querier.label-values-max-cardinality-label-names-per-request": 100,
Expand Down
2 changes: 2 additions & 0 deletions pkg/frontend/querymiddleware/astmapper/astmapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ func cloneExpr(expr parser.Expr) (parser.Expr, error) {
LabelMatchers: matchers,
BypassEmptyMatcherCheck: e.BypassEmptyMatcherCheck,
PosRange: e.PosRange,
Anchored: e.Anchored,
Smoothed: e.Smoothed,
}, nil

case *parser.MatrixSelector:
Expand Down
9 changes: 9 additions & 0 deletions pkg/frontend/querymiddleware/astmapper/astmapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ func TestCloneExpr(t *testing.T) {
`foo and bar`,
`foo == bar`,
`foo == bool bar`,

// Range modifiers
`metric[1m] anchored`,
`metric[1m] smoothed`,
`rate(metric[1m] anchored)`,
`increase(metric[1m] smoothed)`,
}

for i, tc := range testCases {
Expand Down Expand Up @@ -245,11 +251,14 @@ func loadTestExpressionsFromDirectory(t *testing.T, dir string, accumulatedExpre
func enableExperimentalParserFeaturesDuringTest(t *testing.T) {
oldDurationExpressions := parser.ExperimentalDurationExpr
oldExperimentalFunctions := parser.EnableExperimentalFunctions
oldEnableExtendedRangeSelectors := parser.EnableExtendedRangeSelectors
parser.ExperimentalDurationExpr = true
parser.EnableExperimentalFunctions = true
parser.EnableExtendedRangeSelectors = true
t.Cleanup(func() {
parser.ExperimentalDurationExpr = oldDurationExpressions
parser.EnableExperimentalFunctions = oldExperimentalFunctions
parser.EnableExtendedRangeSelectors = oldEnableExtendedRangeSelectors
})
}

Expand Down
68 changes: 58 additions & 10 deletions pkg/frontend/querymiddleware/experimental_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import (

const (
allExperimentalFunctions = "all"
isFunction = 1
isAggregator = 2
isExtendedRangeSelector = 3
)

type experimentalFunctionsMiddleware struct {
Expand All @@ -26,6 +29,7 @@ type experimentalFunctionsMiddleware struct {

// newExperimentalFunctionsMiddleware creates a middleware that blocks queries that contain PromQL experimental functions
// that are not enabled for the active tenant(s), allowing us to enable specific functions only for selected tenants.
// This middleware also manages blocking queries that contain PromQL experimental aggregates and extended range selector modifiers.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we rename this type and file to match this new behaviour?

func newExperimentalFunctionsMiddleware(limits Limits, logger log.Logger) MetricsQueryMiddleware {
return MetricsQueryMiddlewareFunc(func(next MetricsQueryHandler) MetricsQueryHandler {
return &experimentalFunctionsMiddleware{
Expand All @@ -52,7 +56,17 @@ func (m *experimentalFunctionsMiddleware) Do(ctx context.Context, req MetricsQue
}
}

if allExperimentalFunctionsEnabled {
enabledExtendedRangeSelectors := make(map[string][]string, len(tenantIDs))
allExtendedRangeSelectorsEnabled := true
for _, tenantID := range tenantIDs {
enabled := m.limits.EnabledPromQLExtendedRangeSelectors(tenantID)
enabledExtendedRangeSelectors[tenantID] = enabled
if len(enabled) == 0 || enabled[0] != allExperimentalFunctions {
allExtendedRangeSelectorsEnabled = false
}
}

if allExperimentalFunctionsEnabled && allExtendedRangeSelectorsEnabled {
// If all experimental functions are enabled for all tenants here, we don't need to check the query
// for those functions and can skip this middleware.
return m.next.Do(ctx, req)
Expand All @@ -68,17 +82,24 @@ func (m *experimentalFunctionsMiddleware) Do(ctx context.Context, req MetricsQue
return m.next.Do(ctx, req)
}

// Make sure that every used experimental function is enabled for all the tenants here.
for name := range funcs {
for tenantID, enabled := range enabledExperimentalFunctions {
// Make sure that every used experimental function/modifier is enabled for all the tenants here.
var tenantMap map[string][]string
for name, t := range funcs {
switch t {
case isFunction, isAggregator:
tenantMap = enabledExperimentalFunctions
case isExtendedRangeSelector:
tenantMap = enabledExtendedRangeSelectors
}

for tenantID, enabled := range tenantMap {
if len(enabled) > 0 && enabled[0] == allExperimentalFunctions {
// If the first item matches the const value of allExperimentalFunctions, then all experimental
// functions are enabled for this tenant.
continue
}
if !slices.Contains(enabled, name) {
err := fmt.Errorf("function %q is not enabled for tenant %s", name, tenantID)
return nil, apierror.New(apierror.TypeBadData, DecorateWithParamName(err, "query").Error())
return nil, raiseError(tenantID, name, t)
}
}
}
Expand All @@ -87,18 +108,45 @@ func (m *experimentalFunctionsMiddleware) Do(ctx context.Context, req MetricsQue
return m.next.Do(ctx, req)
}

func raiseError(tenantID string, name string, t int) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] Perhaps createExperimentalFeatureError would be a clearer name?

switch t {
case isFunction:
err := fmt.Errorf("function %q is not enabled for tenant %s", name, tenantID)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't bother including the tenant ID here - this won't mean much to users and we can see it in the query-frontend logs if the query fails because of this.

return apierror.New(apierror.TypeBadData, DecorateWithParamName(err, "query").Error())
case isAggregator:
err := fmt.Errorf("aggregate %q is not enabled for tenant %s", name, tenantID)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
err := fmt.Errorf("aggregate %q is not enabled for tenant %s", name, tenantID)
err := fmt.Errorf("aggregation %q is not enabled for tenant %s", name, tenantID)

return apierror.New(apierror.TypeBadData, DecorateWithParamName(err, "query").Error())
case isExtendedRangeSelector:
err := fmt.Errorf("extended range selector modifier %q is not enabled for tenant %s", name, tenantID)
return apierror.New(apierror.TypeBadData, DecorateWithParamName(err, "query").Error())
}
return nil
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Silent Error Bypass Allows Invalid Queries

The raiseError function returns nil when the type parameter doesn't match any of the expected constants (isFunction, isAggregator, or isExtendedRangeSelector). This means if an unexpected type value is passed, the function silently returns nil instead of an error, causing the middleware to incorrectly allow the query to proceed rather than rejecting it.

Fix in Cursor Fix in Web


// containedExperimentalFunctions returns any PromQL experimental functions used in the query.
func containedExperimentalFunctions(expr parser.Expr) map[string]struct{} {
expFuncNames := map[string]struct{}{}
func containedExperimentalFunctions(expr parser.Expr) map[string]int {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than returning a map[string]int like this, what if we added a experimentalFeature struct with name and type fields?

expFuncNames := map[string]int{}
_ = inspect(expr, func(node parser.Node) error {
switch n := node.(type) {
case *parser.Call:
if parser.Functions[n.Func.Name].Experimental {
expFuncNames[n.Func.Name] = struct{}{}
expFuncNames[n.Func.Name] = isFunction
}
case *parser.AggregateExpr:
if n.Op.IsExperimentalAggregator() {
expFuncNames[n.Op.String()] = struct{}{}
expFuncNames[n.Op.String()] = isAggregator
}
case *parser.MatrixSelector:
// technically anchored & smoothed are range selectors not functions
vs, ok := n.VectorSelector.(*parser.VectorSelector)
if ok && vs.Anchored {
expFuncNames["anchored"] = isExtendedRangeSelector
} else if ok && vs.Smoothed {
expFuncNames["smoothed"] = isExtendedRangeSelector
}
case *parser.VectorSelector:
if n.Smoothed {
expFuncNames["smoothed"] = isExtendedRangeSelector
}
}
return nil
Expand Down
47 changes: 45 additions & 2 deletions pkg/frontend/querymiddleware/experimental_functions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,53 +10,96 @@ import (
)

func TestContainedExperimentalFunctions(t *testing.T) {
t.Cleanup(func() { parser.EnableExperimentalFunctions = false })
t.Cleanup(func() {
parser.EnableExperimentalFunctions = false
parser.EnableExtendedRangeSelectors = false
})
parser.EnableExperimentalFunctions = true
parser.EnableExtendedRangeSelectors = true

testCases := map[string]struct {
query string
expect []string
err string
}{
"sum by": {
query: `sum(up) by (namespace)`,
err: "function \"sum by\" is not enabled for tenant tenant",
},
"mad_over_time": {
query: `mad_over_time(up[5m])`,
expect: []string{"mad_over_time"},
err: "function \"mad_over_time\" is not enabled for tenant tenant",
},
"mad_over_time with sum and by": {
query: `sum(mad_over_time(up[5m])) by (namespace)`,
expect: []string{"mad_over_time"},
err: "function \"mad_over_time\" is not enabled for tenant tenant",
},
"sort_by_label": {
query: `sort_by_label({__name__=~".+"}, "__name__")`,
expect: []string{"sort_by_label"},
err: "function \"sort_by_label\" is not enabled for tenant tenant",
},
"sort_by_label_desc": {
query: `sort_by_label_desc({__name__=~".+"}, "__name__")`,
expect: []string{"sort_by_label_desc"},
err: "function \"sort_by_label_desc\" is not enabled for tenant tenant",
},
"limitk": {
query: `limitk by (group) (0, up)`,
expect: []string{"limitk"},
err: "aggregate \"limitk\" is not enabled for tenant tenant",
},
"limit_ratio": {
query: `limit_ratio(0.5, up)`,
expect: []string{"limit_ratio"},
err: "aggregate \"limit_ratio\" is not enabled for tenant tenant",
},
"limit_ratio with mad_over_time": {
query: `limit_ratio(0.5, mad_over_time(up[5m]))`,
expect: []string{"limit_ratio", "mad_over_time"},
},
"metric smoothed": {
query: `metric smoothed`,
expect: []string{"smoothed"},
err: "extended range selector modifier \"smoothed\" is not enabled for tenant tenant",
},
"metric[1m] smoothed": {
query: `metric[1m] smoothed`,
expect: []string{"smoothed"},
err: "extended range selector modifier \"smoothed\" is not enabled for tenant tenant",
},
"metric[1m] anchored": {
query: `metric[1m] anchored`,
expect: []string{"anchored"},
err: "extended range selector modifier \"anchored\" is not enabled for tenant tenant",
},
"rate(metric[1m] smoothed)": {
query: `rate(metric[1m] smoothed)`,
expect: []string{"smoothed"},
err: "extended range selector modifier \"smoothed\" is not enabled for tenant tenant",
},
"increase(metric[1m] anchored)": {
query: `increase(metric[1m] anchored)`,
expect: []string{"anchored"},
err: "extended range selector modifier \"anchored\" is not enabled for tenant tenant",
},
}

for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
expr, err := parser.ParseExpr(tc.query)
require.NoError(t, err)
var enabled []string
for key := range containedExperimentalFunctions(expr) {
for key, funcType := range containedExperimentalFunctions(expr) {
enabled = append(enabled, key)
if len(tc.err) > 0 {
// test that if an error was raised for this function/aggregate/modifier that the expected error string is formed
// an empty tc.err allows for the case to be skipped - such as where we have multiple errors which are validated elsewhere
err := raiseError("tenant", key, funcType)
require.ErrorContains(t, err, tc.err)
}
}
require.ElementsMatch(t, tc.expect, enabled)
})
Expand Down
3 changes: 3 additions & 0 deletions pkg/frontend/querymiddleware/limits.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ type Limits interface {
// EnabledPromQLExperimentalFunctions returns the names of PromQL experimental functions allowed for the tenant.
EnabledPromQLExperimentalFunctions(userID string) []string

// EnabledPromQLExtendedRangeSelectors returns the names of PromQL experimental extended range selectors modifiers allowed for the tenant.
EnabledPromQLExtendedRangeSelectors(userID string) []string

// Prom2RangeCompat returns if Prometheus 2/3 range compatibility fixes are enabled for the tenant.
Prom2RangeCompat(userID string) bool

Expand Down
9 changes: 9 additions & 0 deletions pkg/frontend/querymiddleware/limits_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,10 @@ func (m multiTenantMockLimits) EnabledPromQLExperimentalFunctions(userID string)
return m.byTenant[userID].enabledPromQLExperimentalFunctions
}

func (m multiTenantMockLimits) EnabledPromQLExtendedRangeSelectors(userID string) []string {
return m.byTenant[userID].enabledPromQLExtendedRangeSelectors
}

func (m multiTenantMockLimits) Prom2RangeCompat(userID string) bool {
return m.byTenant[userID].prom2RangeCompat
}
Expand Down Expand Up @@ -741,6 +745,7 @@ type mockLimits struct {
resultsCacheTTLForErrors time.Duration
resultsCacheForUnalignedQueryEnabled bool
enabledPromQLExperimentalFunctions []string
enabledPromQLExtendedRangeSelectors []string
prom2RangeCompat bool
blockedQueries []validation.BlockedQuery
limitedQueries []validation.LimitedQuery
Expand Down Expand Up @@ -838,6 +843,10 @@ func (m mockLimits) EnabledPromQLExperimentalFunctions(string) []string {
return m.enabledPromQLExperimentalFunctions
}

func (m mockLimits) EnabledPromQLExtendedRangeSelectors(string) []string {
return m.enabledPromQLExtendedRangeSelectors
}

func (m mockLimits) Prom2RangeCompat(string) bool {
return m.prom2RangeCompat
}
Expand Down
Loading
Loading