diff --git a/promql/engine.go b/promql/engine.go index 2d13accddc..2e70680340 100644 --- a/promql/engine.go +++ b/promql/engine.go @@ -86,11 +86,6 @@ type engineMetrics struct { querySamples prometheus.Counter } -// convertibleToInt64 returns true if v does not over-/underflow an int64. -func convertibleToInt64(v float64) bool { - return v <= maxInt64 && v >= minInt64 -} - type ( // ErrQueryTimeout is returned if a query timed out during processing. ErrQueryTimeout string @@ -1433,6 +1428,15 @@ func (ev *evaluator) rangeEvalAgg(ctx context.Context, aggExpr *parser.Aggregate if params.Max() < 1 { return nil, annos } + if params.HasAnyNaN() { + ev.errorf("Parameter value is NaN") + } + if fParam := params.Min(); fParam <= minInt64 { + ev.errorf("Scalar value %v underflows int64", fParam) + } + if fParam := params.Max(); fParam >= maxInt64 { + ev.errorf("Scalar value %v overflows int64", fParam) + } seriess = make(map[uint64]Series, len(inputMatrix)) case parser.LIMIT_RATIO: @@ -1440,6 +1444,9 @@ func (ev *evaluator) rangeEvalAgg(ctx context.Context, aggExpr *parser.Aggregate if params.Max() == 0 && params.Min() == 0 { return nil, annos } + if params.HasAnyNaN() { + ev.errorf("Ratio value is NaN") + } if params.Max() > 1.0 { annos.Add(annotations.NewInvalidRatioWarning(params.Max(), 1.0, aggExpr.Param.PositionRange())) } @@ -3289,9 +3296,6 @@ seriesLoop: var r float64 switch op { case parser.TOPK, parser.BOTTOMK, parser.LIMITK: - if !convertibleToInt64(fParam) { - ev.errorf("Scalar value %v overflows int64", fParam) - } k = int64(fParam) if k > int64(len(inputMatrix)) { k = int64(len(inputMatrix)) @@ -3303,9 +3307,6 @@ seriesLoop: return nil, annos } case parser.LIMIT_RATIO: - if math.IsNaN(fParam) { - ev.errorf("Ratio value %v is NaN", fParam) - } switch { case fParam == 0: if enh.Ts != ev.endTimestamp { diff --git a/promql/promqltest/testdata/aggregators.test b/promql/promqltest/testdata/aggregators.test index 7062d37f05..7fc95bc28a 100644 --- a/promql/promqltest/testdata/aggregators.test +++ b/promql/promqltest/testdata/aggregators.test @@ -388,6 +388,15 @@ eval_info instant at 50m bottomk by (instance) (1, {__name__=~"http_requests(_hi {__name__="http_requests", group="production", instance="1", job="api-server"} 200 {__name__="http_requests", group="production", instance="2", job="api-server"} NaN +eval instant at 50m topk(NaN, non_existent) + expect fail msg: Parameter value is NaN + +eval instant at 50m limitk(NaN, non_existent) + expect fail msg: Parameter value is NaN + +eval instant at 50m limit_ratio(NaN, non_existent) + expect fail msg: Ratio value is NaN + clear # Tests for count_values. diff --git a/promql/promqltest/testdata/histograms.test b/promql/promqltest/testdata/histograms.test index 68f646dd9a..bf13864277 100644 --- a/promql/promqltest/testdata/histograms.test +++ b/promql/promqltest/testdata/histograms.test @@ -222,6 +222,9 @@ eval_warn instant at 50m histogram_quantile(NaN, testhistogram_bucket) {start="positive"} NaN {start="negative"} NaN +eval instant at 50m histogram_quantile(NaN, non_existent) + expect warn msg: PromQL warning: quantile value should be between 0 and 1, got NaN + # Quantile value in lowest bucket. eval instant at 50m histogram_quantile(0, testhistogram)