From e100520467192376bb7942b38d6dcda16c3b0eda Mon Sep 17 00:00:00 2001 From: Laurent Dufresne Date: Thu, 9 Apr 2026 15:16:13 +0200 Subject: [PATCH 1/2] annotations: add warning for ineffective sort in range queries Co-authored-by: Bojun Kim Co-authored-by: Laurent Dufresne Signed-off-by: Laurent Dufresne --- promql/engine.go | 5 ++ promql/promqltest/testdata/histograms.test | 65 +++++++++++++++++++ promql/promqltest/testdata/range_queries.test | 17 ++++- util/annotations/annotations.go | 10 +++ 4 files changed, 96 insertions(+), 1 deletion(-) diff --git a/promql/engine.go b/promql/engine.go index feddc34393..855e60d2a7 100644 --- a/promql/engine.go +++ b/promql/engine.go @@ -2010,6 +2010,11 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, return ev.evalInfo(ctx, e.Args) } + // Emit a warning when sort is used for range queries + if (e.Func.Name == "sort" || e.Func.Name == "sort_desc" || e.Func.Name == "sort_by_label" || e.Func.Name == "sort_by_label_desc") && ev.startTimestamp != ev.endTimestamp { + warnings.Add(annotations.NewSortInRangeQueryWarning(e.PositionRange())) + } + if !matrixArg { // Does not have a matrix argument. return ev.rangeEval(ctx, nil, func(v []Vector, _ Matrix, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { diff --git a/promql/promqltest/testdata/histograms.test b/promql/promqltest/testdata/histograms.test index db7d5de230..9e5a60ffc5 100644 --- a/promql/promqltest/testdata/histograms.test +++ b/promql/promqltest/testdata/histograms.test @@ -1169,3 +1169,68 @@ eval instant at 0 histogram_fraction(-Inf, 1, series) expect no_info expect warn msg: PromQL warning: vector contains a mix of classic and native histograms for metric name "series" # Should return no results. + +clear + +# Test histogram_quantile(s) and histogram_fraction warns about missing "le" +load 1m + series{ale="0.1"} 2 + +eval instant at 0 histogram_quantile(0.8, series) + expect no_info + expect warn msg: PromQL warning: bucket label "le" is missing or has a malformed value of "" for metric name "series" + # Should return no results. + +eval instant at 0 histogram_quantiles(series, "q", 0.1, 0.2) + expect no_info + expect warn msg: PromQL warning: bucket label "le" is missing or has a malformed value of "" for metric name "series" + # Should return no results. + +eval instant at 0 histogram_fraction(-Inf, 1, series) + expect no_info + expect warn msg: PromQL warning: bucket label "le" is missing or has a malformed value of "" for metric name "series" + # Should return no results. + +clear + +# Test histogram_quantile(s) and histogram_fraction warns about malformated "le" +load 1m + series{le="Hello World"} 2 + +eval instant at 0 histogram_quantile(0.8, series) + expect no_info + expect warn msg: PromQL warning: bucket label "le" is missing or has a malformed value of "Hello World" for metric name "series" + # Should return no results. + +eval instant at 0 histogram_quantiles(series, "q", 0.1, 0.2) + expect no_info + expect warn msg: PromQL warning: bucket label "le" is missing or has a malformed value of "Hello World" for metric name "series" + # Should return no results. + +eval instant at 0 histogram_fraction(-Inf, 1, series) + expect no_info + expect warn msg: PromQL warning: bucket label "le" is missing or has a malformed value of "Hello World" for metric name "series" + # Should return no results. + +clear + +# Test histogram_quantile(s) and histogram_fraction warns about mixed classic and native histogram +load 1m + series{le="0.1"} 1 + series{le="1"} 2 + series{} {{schema:0 count:10 sum:50 buckets:[1 2 3]}} + +eval instant at 0 histogram_quantile(0.8, series) + expect no_info + expect warn msg: PromQL warning: vector contains a mix of classic and native histograms for metric name "series" + # Should return no results. + +eval instant at 0 histogram_quantiles(series, "q", 0.1, 0.2) + expect no_info + expect warn msg: PromQL warning: vector contains a mix of classic and native histograms for metric name "series" + # Should return no results. + +eval instant at 0 histogram_fraction(-Inf, 1, series) + expect no_info + expect warn msg: PromQL warning: vector contains a mix of classic and native histograms for metric name "series" + # Should return no results. diff --git a/promql/promqltest/testdata/range_queries.test b/promql/promqltest/testdata/range_queries.test index 35a2f1b27e..b13bcf6a31 100644 --- a/promql/promqltest/testdata/range_queries.test +++ b/promql/promqltest/testdata/range_queries.test @@ -104,4 +104,19 @@ eval instant at 1m some_nonexistent_metric[1m] expect range vector from 10s to 1m step 10s eval instant at 10m some_metric[1m] - expect range vector from 9m10s to 10m step 1m \ No newline at end of file + expect range vector from 9m10s to 10m step 1m + +eval range from 1m to 2m step 1m sort(series) + expect warn msg: PromQL warning: sort is ineffective for range queries since results are always ordered by labels + +eval range from 1m to 2m step 1m sort_desc(series) + expect warn msg: PromQL warning: sort is ineffective for range queries since results are always ordered by labels + +eval range from 1m to 2m step 1m sort_by_label(series) + expect warn msg: PromQL warning: sort is ineffective for range queries since results are always ordered by labels + +eval range from 1m to 2m step 1m sort_by_label_desc(series) + expect warn msg: PromQL warning: sort is ineffective for range queries since results are always ordered by labels + +eval range from 1m to 2m step 1m sum(sort(series)) + expect warn msg: PromQL warning: sort is ineffective for range queries since results are always ordered by labels diff --git a/util/annotations/annotations.go b/util/annotations/annotations.go index 550b9fcdc5..d384e8406e 100644 --- a/util/annotations/annotations.go +++ b/util/annotations/annotations.go @@ -156,6 +156,7 @@ var ( NativeHistogramNotGaugeWarning = fmt.Errorf("%w: this native histogram metric is not a gauge:", PromQLWarning) MixedExponentialCustomHistogramsWarning = fmt.Errorf("%w: vector contains a mix of histograms with exponential and custom buckets schemas for metric name", PromQLWarning) IncompatibleBucketLayoutInBinOpWarning = fmt.Errorf("%w: incompatible bucket layout encountered for binary operator", PromQLWarning) + SortInRangeQueryWarning = fmt.Errorf("%w: sort is ineffective for range queries since results are always ordered by labels", PromQLWarning) PossibleNonCounterInfo = fmt.Errorf("%w: metric might not be a counter, name does not end in _total/_sum/_count/_bucket:", PromQLInfo) PossibleNonCounterLabelInfo = fmt.Errorf("%w: metric might not be a counter, __type__ label is not set to %q or %q", PromQLInfo, model.MetricTypeCounter, model.MetricTypeHistogram) @@ -424,6 +425,15 @@ func NewIncompatibleBucketLayoutInBinOpWarning(operator string, pos posrange.Pos } } +// NewSortInRangeQueryWarning is used when sort or sort_desc functions are used +// in range queries where they have no effect since results are always ordered by labels. +func NewSortInRangeQueryWarning(pos posrange.PositionRange) error { + return &annoErr{ + PositionRange: pos, + Err: SortInRangeQueryWarning, + } +} + func NewNativeHistogramQuantileNaNResultInfo(metricName string, pos posrange.PositionRange) error { return &annoErr{ PositionRange: pos, From 31b40c75b03c9819168a347e009564be2b8b916f Mon Sep 17 00:00:00 2001 From: George Krajcsovits Date: Fri, 10 Apr 2026 10:13:38 +0200 Subject: [PATCH 2/2] Apply suggestion from @krajorama Signed-off-by: George Krajcsovits --- promql/engine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/promql/engine.go b/promql/engine.go index 855e60d2a7..7039adfc9f 100644 --- a/promql/engine.go +++ b/promql/engine.go @@ -2010,7 +2010,7 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, return ev.evalInfo(ctx, e.Args) } - // Emit a warning when sort is used for range queries + // Emit a warning when sort is used for range queries. if (e.Func.Name == "sort" || e.Func.Name == "sort_desc" || e.Func.Name == "sort_by_label" || e.Func.Name == "sort_by_label_desc") && ev.startTimestamp != ev.endTimestamp { warnings.Add(annotations.NewSortInRangeQueryWarning(e.PositionRange())) }