Skip to content
27 changes: 25 additions & 2 deletions engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ type Opts struct {
// This will default to false.
EnableXFunctions bool

// EnableExtendedRangeSelectors enables the anchored and smoothed modifiers
// for range vector selectors.
// See https://github.com/prometheus/proposals/blob/main/proposals/0052-extended-range-selectors-semantics.md
EnableExtendedRangeSelectors bool

// EnableAnalysis enables query analysis.
EnableAnalysis bool

Expand Down Expand Up @@ -183,7 +188,8 @@ func NewWithScanners(opts Opts, scanners engstorage.Scanners) *Engine {
scanners: scanners,
activeQueryTracker: queryTracker,

disableDuplicateLabelChecks: opts.DisableDuplicateLabelChecks,
disableDuplicateLabelChecks: opts.DisableDuplicateLabelChecks,
enableExtendedRangeSelectors: opts.EnableExtendedRangeSelectors,

logger: opts.Logger,
lookbackDelta: opts.LookbackDelta,
Expand Down Expand Up @@ -213,7 +219,8 @@ type Engine struct {
scanners engstorage.Scanners
activeQueryTracker promql.QueryTracker

disableDuplicateLabelChecks bool
disableDuplicateLabelChecks bool
enableExtendedRangeSelectors bool

logger *slog.Logger
lookbackDelta time.Duration
Expand All @@ -236,6 +243,14 @@ func (e *Engine) MakeInstantQuery(ctx context.Context, q storage.Queryable, opts
}
defer e.activeQueryTracker.Delete(idx)

// NOTE: parser.EnableExtendedRangeSelectors is a process-global variable
// in the upstream Prometheus parser. Once set to true, it remains enabled
// for all subsequent parses in the process, matching how Prometheus handles
// it (set once at startup via --enable-feature). Two engine instances in
// the same process cannot independently control this flag.
if e.enableExtendedRangeSelectors {
parser.EnableExtendedRangeSelectors = true
}
expr, err := parser.NewParser(qs, parser.WithFunctions(e.functions)).ParseExpr()
if err != nil {
return nil, err
Expand Down Expand Up @@ -334,6 +349,14 @@ func (e *Engine) MakeRangeQuery(ctx context.Context, q storage.Queryable, opts *
}
defer e.activeQueryTracker.Delete(idx)

// NOTE: parser.EnableExtendedRangeSelectors is a process-global variable
// in the upstream Prometheus parser. Once set to true, it remains enabled
// for all subsequent parses in the process, matching how Prometheus handles
// it (set once at startup via --enable-feature). Two engine instances in
// the same process cannot independently control this flag.
if e.enableExtendedRangeSelectors {
parser.EnableExtendedRangeSelectors = true
}
expr, err := parser.NewParser(qs, parser.WithFunctions(e.functions)).ParseExpr()
if err != nil {
return nil, err
Expand Down
9 changes: 6 additions & 3 deletions engine/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ func (s *skipTest) Run(name string, t func(*testing.T)) bool {
func TestPromqlAcceptance(t *testing.T) {
// promql acceptance tests disable experimental functions again
// since we use them in our tests too we need to enable them afterwards again
t.Cleanup(func() { parser.EnableExperimentalFunctions = true })
t.Cleanup(func() {
parser.EnableExperimentalFunctions = true
})

engine := engine.New(engine.Opts{
EngineOpts: promql.EngineOpts{
Expand All @@ -85,13 +87,14 @@ func TestPromqlAcceptance(t *testing.T) {
MaxSamples: 5e10,
Timeout: 1 * time.Hour,
NoStepSubqueryIntervalFn: func(rangeMillis int64) int64 { return 30 * time.Second.Milliseconds() },
}})
},
EnableExtendedRangeSelectors: true,
})

st := &skipTest{
skipTests: []string{
"testdata/name_label_dropping.test", // feature unsupported
"testdata/type_and_unit.test", // feature unsupported
"testdata/extended_vectors.test", // experimental anchored/smoothed modifiers unsupported
"testdata/info.test", // info() function unsupported
"testdata/literals.test", // string literal expressions as query results unsupported
"testdata/range_queries.test", // matrix selector as instant query result unsupported
Expand Down
Loading
Loading