diff --git a/CHANGELOG.md b/CHANGELOG.md index 96514b6ed1..b71b148173 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ We use *breaking :warning:* to mark changes that are not backward compatible (re ### Added +- [#8191](https://github.com/thanos-io/thanos/pull/8191) Query: Add `--enable-feature=promql-experimental-functions` flag to enable experimental functions in query. + ### Changed - [#8192](https://github.com/thanos-io/thanos/pull/8192) Sidecar: fix default get config timeout diff --git a/cmd/thanos/query.go b/cmd/thanos/query.go index afacef9252..ecf03b3ac9 100644 --- a/cmd/thanos/query.go +++ b/cmd/thanos/query.go @@ -53,9 +53,10 @@ import ( ) const ( - promqlNegativeOffset = "promql-negative-offset" - promqlAtModifier = "promql-at-modifier" - queryPushdown = "query-pushdown" + promqlNegativeOffset = "promql-negative-offset" + promqlAtModifier = "promql-at-modifier" + queryPushdown = "query-pushdown" + promqlExperimentalFunctions = "promql-experimental-functions" ) // registerQuery registers a query command. @@ -135,7 +136,7 @@ func registerQuery(app *extkingpin.App) { activeQueryDir := cmd.Flag("query.active-query-path", "Directory to log currently active queries in the queries.active file.").Default("").String() - featureList := cmd.Flag("enable-feature", "Comma separated experimental feature names to enable.The current list of features is empty.").Hidden().Default("").Strings() + featureList := cmd.Flag("enable-feature", "Comma separated experimental feature names to enable. The current list of features is: promql-experimental-functions (enables experimental PromQL functions).").Hidden().Default("").Strings() enableExemplarPartialResponse := cmd.Flag("exemplar.partial-response", "Enable partial response for exemplar endpoint. --no-exemplar.partial-response for disabling."). Hidden().Default("true").Bool() @@ -317,6 +318,7 @@ func registerQuery(app *extkingpin.App) { *enableTargetPartialResponse, *enableMetricMetadataPartialResponse, *enableExemplarPartialResponse, + false, *activeQueryDir, time.Duration(*instantDefaultMaxSourceResolution), *defaultMetadataTimeRange, @@ -379,6 +381,7 @@ func runQuery( enableTargetPartialResponse bool, enableMetricMetadataPartialResponse bool, enableExemplarPartialResponse bool, + enableQueryExperimentalFunctions bool, activeQueryDir string, instantDefaultMaxSourceResolution time.Duration, defaultMetadataTimeRange time.Duration, @@ -464,6 +467,7 @@ func runQuery( lookbackDelta, defaultEvaluationInterval, extendedFunctionsEnabled, + enableQueryExperimentalFunctions, activeQueryTracker, queryMode, ) diff --git a/pkg/api/query/engine.go b/pkg/api/query/engine.go index a1f5e7221b..ab22ecf6bf 100644 --- a/pkg/api/query/engine.go +++ b/pkg/api/query/engine.go @@ -27,6 +27,7 @@ import ( "github.com/go-kit/log" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/prometheus/promql" + "github.com/prometheus/prometheus/promql/parser" "github.com/prometheus/prometheus/storage" "github.com/thanos-io/promql-engine/api" @@ -88,10 +89,14 @@ func NewQueryFactory( lookbackDelta time.Duration, evaluationInterval time.Duration, enableXFunctions bool, + enablePromQLExperimentalFunctions bool, activeQueryTracker *promql.ActiveQueryTracker, mode PromqlQueryMode, ) *QueryFactory { makeOpts := func(registry prometheus.Registerer) engine.Opts { + // Set global experimental functions flag + parser.EnableExperimentalFunctions = enablePromQLExperimentalFunctions + opts := engine.Opts{ EngineOpts: promql.EngineOpts{ Logger: logutil.GoKitLogToSlog(logger), diff --git a/pkg/api/query/v1_test.go b/pkg/api/query/v1_test.go index b410c67427..2fc926bbbc 100644 --- a/pkg/api/query/v1_test.go +++ b/pkg/api/query/v1_test.go @@ -97,6 +97,7 @@ var ( 5*time.Minute, 30*time.Second, true, + false, nil, PromqlQueryModeLocal, ) diff --git a/pkg/queryfrontend/config.go b/pkg/queryfrontend/config.go index d2a9b51a4d..ae56ba3fdb 100644 --- a/pkg/queryfrontend/config.go +++ b/pkg/queryfrontend/config.go @@ -202,17 +202,18 @@ type Config struct { LabelsConfig DownstreamTripperConfig - CortexHandlerConfig *transport.HandlerConfig - CompressResponses bool - CacheCompression string - RequestLoggingDecision string - DownstreamURL string - ForwardHeaders []string - NumShards int - TenantHeader string - DefaultTenant string - TenantCertField string - EnableXFunctions bool + CortexHandlerConfig *transport.HandlerConfig + CompressResponses bool + CacheCompression string + RequestLoggingDecision string + DownstreamURL string + ForwardHeaders []string + NumShards int + TenantHeader string + DefaultTenant string + TenantCertField string + EnableXFunctions bool + EnableQueryExperimentalFunctions bool } // QueryRangeConfig holds the config for query range tripperware. diff --git a/test/e2e/e2ethanos/services.go b/test/e2e/e2ethanos/services.go index 916e265423..a8a15bd424 100644 --- a/test/e2e/e2ethanos/services.go +++ b/test/e2e/e2ethanos/services.go @@ -282,6 +282,7 @@ type QuerierBuilder struct { queryDistributedWithOverlappingInterval bool enableXFunctions bool deduplicationFunc string + enableQueryExperimentalFunctions bool replicaLabels []string tracingConfig string @@ -391,6 +392,11 @@ func (q *QuerierBuilder) WithEnableXFunctions() *QuerierBuilder { return q } +func (q *QuerierBuilder) WithEnableExperimentalFunctions() *QuerierBuilder { + q.enableQueryExperimentalFunctions = true + return q +} + func (q *QuerierBuilder) WithDeduplicationFunc(deduplicationFunc string) *QuerierBuilder { q.deduplicationFunc = deduplicationFunc return q