diff --git a/promql/engine.go b/promql/engine.go index f5ee591d3b..33e3f5b587 100644 --- a/promql/engine.go +++ b/promql/engine.go @@ -1228,7 +1228,7 @@ func (enh *EvalNodeHelper) resetHistograms(inVec Vector, arg parser.Expr) annota // function call results. // The prepSeries function (if provided) can be used to prepare the helper // for each series, then passed to each call funcCall. -func (ev *evaluator) rangeEval(ctx context.Context, prepSeries func(labels.Labels, *EvalSeriesHelper), funcCall func([]parser.Value, [][]EvalSeriesHelper, *EvalNodeHelper) (Vector, annotations.Annotations), exprs ...parser.Expr) (Matrix, annotations.Annotations) { +func (ev *evaluator) rangeEval(ctx context.Context, prepSeries func(labels.Labels, *EvalSeriesHelper), funcCall func([]Vector, Matrix, [][]EvalSeriesHelper, *EvalNodeHelper) (Vector, annotations.Annotations), exprs ...parser.Expr) (Matrix, annotations.Annotations) { numSteps := int((ev.endTimestamp-ev.startTimestamp)/ev.interval) + 1 matrixes := make([]Matrix, len(exprs)) origMatrixes := make([]Matrix, len(exprs)) @@ -1250,8 +1250,7 @@ func (ev *evaluator) rangeEval(ctx context.Context, prepSeries func(labels.Label } } - vectors := make([]Vector, len(exprs)) // Input vectors for the function. - args := make([]parser.Value, len(exprs)) // Argument to function. + vectors := make([]Vector, len(exprs)) // Input vectors for the function. // Create an output vector that is as big as the input matrix with // the most time series. biggestLen := 1 @@ -1305,7 +1304,6 @@ func (ev *evaluator) rangeEval(ctx context.Context, prepSeries func(labels.Label sh = seriesHelpers[i] } vectors[i], bh = ev.gatherVector(ts, matrixes[i], vectors[i], bh, sh) - args[i] = vectors[i] if prepSeries != nil { bufHelpers[i] = bh } @@ -1313,7 +1311,7 @@ func (ev *evaluator) rangeEval(ctx context.Context, prepSeries func(labels.Label // Make the function call. enh.Ts = ts - result, ws := funcCall(args, bufHelpers, enh) + result, ws := funcCall(vectors, nil, bufHelpers, enh) enh.Out = result[:0] // Reuse result vector. warnings.Merge(ws) @@ -1685,8 +1683,8 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, sortedGrouping = append(sortedGrouping, valueLabel.Val) slices.Sort(sortedGrouping) } - return ev.rangeEval(ctx, nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return ev.aggregationCountValues(e, sortedGrouping, valueLabel.Val, v[0].(Vector), enh) + return ev.rangeEval(ctx, nil, func(v []Vector, _ Matrix, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return ev.aggregationCountValues(e, sortedGrouping, valueLabel.Val, v[0], enh) }, e.Expr) } @@ -1766,22 +1764,18 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, if !matrixArg { // Does not have a matrix argument. - return ev.rangeEval(ctx, nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - vec, annos := call(v, e.Args, enh) + return ev.rangeEval(ctx, nil, func(v []Vector, _ Matrix, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + vec, annos := call(v, nil, e.Args, enh) return vec, warnings.Merge(annos) }, e.Args...) } - inArgs := make([]parser.Value, len(e.Args)) // Evaluate any non-matrix arguments. - otherArgs := make([]Matrix, len(e.Args)) - otherInArgs := make([]Vector, len(e.Args)) + evalVals := make([]Matrix, len(e.Args)) for i, e := range e.Args { if i != matrixArgIndex { val, ws := ev.eval(ctx, e) - otherArgs[i] = val.(Matrix) - otherInArgs[i] = Vector{Sample{}} - inArgs[i] = otherInArgs[i] + evalVals[i] = val.(Matrix) warnings.Merge(ws) } } @@ -1809,7 +1803,6 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, var histograms []HPoint var prevSS *Series inMatrix := make(Matrix, 1) - inArgs[matrixArgIndex] = inMatrix enh := &EvalNodeHelper{Out: make(Vector, 0, 1), enableDelayedNameRemoval: ev.enableDelayedNameRemoval} // Process all the calls for one time series at a time. it := storage.NewBuffer(selRange) @@ -1820,7 +1813,7 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, // vector functions, the only change needed is to drop the // metric name in the output. dropName := e.Func.Name != "last_over_time" - + vectorVals := make([]Vector, len(e.Args)-1) for i, s := range selVS.Series { if err := contextDone(ctx, "expression evaluation"); err != nil { ev.error(err) @@ -1848,9 +1841,11 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, // Set the non-matrix arguments. // They are scalar, so it is safe to use the step number // when looking up the argument, as there will be no gaps. + counter := 0 for j := range e.Args { if j != matrixArgIndex { - otherInArgs[j][0].F = otherArgs[j][0].Floats[step].F + vectorVals[counter] = Vector{Sample{F: evalVals[j][0].Floats[step].F}} + counter++ } } // Evaluate the matrix selector for this series @@ -1867,8 +1862,9 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, inMatrix[0].Floats = floats inMatrix[0].Histograms = histograms enh.Ts = ts + // Make the function call. - outVec, annos := call(inArgs, e.Args, enh) + outVec, annos := call(vectorVals, inMatrix, e.Args, enh) warnings.Merge(annos) ev.samplesStats.IncrementSamplesAtStep(step, int64(len(floats)+totalHPointSize(histograms))) @@ -2002,8 +1998,8 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, case *parser.BinaryExpr: switch lt, rt := e.LHS.Type(), e.RHS.Type(); { case lt == parser.ValueTypeScalar && rt == parser.ValueTypeScalar: - return ev.rangeEval(ctx, nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - val := scalarBinop(e.Op, v[0].(Vector)[0].F, v[1].(Vector)[0].F) + return ev.rangeEval(ctx, nil, func(v []Vector, _ Matrix, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + val := scalarBinop(e.Op, v[0][0].F, v[1][0].F) return append(enh.Out, Sample{F: val}), nil }, e.LHS, e.RHS) case lt == parser.ValueTypeVector && rt == parser.ValueTypeVector: @@ -2015,40 +2011,40 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, } switch e.Op { case parser.LAND: - return ev.rangeEval(ctx, initSignatures, func(v []parser.Value, sh [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return ev.VectorAnd(v[0].(Vector), v[1].(Vector), e.VectorMatching, sh[0], sh[1], enh), nil + return ev.rangeEval(ctx, initSignatures, func(v []Vector, _ Matrix, sh [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return ev.VectorAnd(v[0], v[1], e.VectorMatching, sh[0], sh[1], enh), nil }, e.LHS, e.RHS) case parser.LOR: - return ev.rangeEval(ctx, initSignatures, func(v []parser.Value, sh [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return ev.VectorOr(v[0].(Vector), v[1].(Vector), e.VectorMatching, sh[0], sh[1], enh), nil + return ev.rangeEval(ctx, initSignatures, func(v []Vector, _ Matrix, sh [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return ev.VectorOr(v[0], v[1], e.VectorMatching, sh[0], sh[1], enh), nil }, e.LHS, e.RHS) case parser.LUNLESS: - return ev.rangeEval(ctx, initSignatures, func(v []parser.Value, sh [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return ev.VectorUnless(v[0].(Vector), v[1].(Vector), e.VectorMatching, sh[0], sh[1], enh), nil + return ev.rangeEval(ctx, initSignatures, func(v []Vector, _ Matrix, sh [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return ev.VectorUnless(v[0], v[1], e.VectorMatching, sh[0], sh[1], enh), nil }, e.LHS, e.RHS) default: - return ev.rangeEval(ctx, initSignatures, func(v []parser.Value, sh [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - vec, err := ev.VectorBinop(e.Op, v[0].(Vector), v[1].(Vector), e.VectorMatching, e.ReturnBool, sh[0], sh[1], enh, e.PositionRange()) + return ev.rangeEval(ctx, initSignatures, func(v []Vector, _ Matrix, sh [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + vec, err := ev.VectorBinop(e.Op, v[0], v[1], e.VectorMatching, e.ReturnBool, sh[0], sh[1], enh, e.PositionRange()) return vec, handleVectorBinopError(err, e) }, e.LHS, e.RHS) } case lt == parser.ValueTypeVector && rt == parser.ValueTypeScalar: - return ev.rangeEval(ctx, nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - vec, err := ev.VectorscalarBinop(e.Op, v[0].(Vector), Scalar{V: v[1].(Vector)[0].F}, false, e.ReturnBool, enh, e.PositionRange()) + return ev.rangeEval(ctx, nil, func(v []Vector, _ Matrix, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + vec, err := ev.VectorscalarBinop(e.Op, v[0], Scalar{V: v[1][0].F}, false, e.ReturnBool, enh, e.PositionRange()) return vec, handleVectorBinopError(err, e) }, e.LHS, e.RHS) case lt == parser.ValueTypeScalar && rt == parser.ValueTypeVector: - return ev.rangeEval(ctx, nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - vec, err := ev.VectorscalarBinop(e.Op, v[1].(Vector), Scalar{V: v[0].(Vector)[0].F}, true, e.ReturnBool, enh, e.PositionRange()) + return ev.rangeEval(ctx, nil, func(v []Vector, _ Matrix, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + vec, err := ev.VectorscalarBinop(e.Op, v[1], Scalar{V: v[0][0].F}, true, e.ReturnBool, enh, e.PositionRange()) return vec, handleVectorBinopError(err, e) }, e.LHS, e.RHS) } case *parser.NumberLiteral: span.SetAttributes(attribute.Float64("value", e.Val)) - return ev.rangeEval(ctx, nil, func(_ []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return ev.rangeEval(ctx, nil, func(_ []Vector, _ Matrix, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { return append(enh.Out, Sample{F: e.Val, Metric: labels.EmptyLabels()}), nil }) @@ -2219,7 +2215,7 @@ func (ev *evaluator) rangeEvalTimestampFunctionOverVectorSelector(ctx context.Co seriesIterators[i] = storage.NewMemoizedIterator(it, durationMilliseconds(ev.lookbackDelta)-1) } - return ev.rangeEval(ctx, nil, func(_ []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return ev.rangeEval(ctx, nil, func(_ []Vector, _ Matrix, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, annotations.Annotations) { if vs.Timestamp != nil { // This is a special case for "timestamp()" when the @ modifier is used, to ensure that // we return a point for each time step in this case. @@ -2248,7 +2244,7 @@ func (ev *evaluator) rangeEvalTimestampFunctionOverVectorSelector(ctx context.Co } } ev.samplesStats.UpdatePeak(ev.currentSamples) - vec, annos := call([]parser.Value{vec}, e.Args, enh) + vec, annos := call([]Vector{vec}, nil, e.Args, enh) return vec, ws.Merge(annos) }) } diff --git a/promql/functions.go b/promql/functions.go index 2577e7f27b..d9839c5a05 100644 --- a/promql/functions.go +++ b/promql/functions.go @@ -56,10 +56,10 @@ import ( // metrics, the timestamp are not needed. // // Scalar results should be returned as the value of a sample in a Vector. -type FunctionCall func(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) +type FunctionCall func(vectorVals []Vector, matrixVals Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) // === time() float64 === -func funcTime(_ []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { +func funcTime(_ []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { return Vector{Sample{ F: float64(enh.Ts) / 1000, }}, nil @@ -69,11 +69,11 @@ func funcTime(_ []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vect // It calculates the rate (allowing for counter resets if isCounter is true), // extrapolates if the first/last sample is close to the boundary, and returns // the result as either per-second (if isRate is true) or overall. -func extrapolatedRate(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper, isCounter, isRate bool) (Vector, annotations.Annotations) { +func extrapolatedRate(vals Matrix, args parser.Expressions, enh *EvalNodeHelper, isCounter, isRate bool) (Vector, annotations.Annotations) { ms := args[0].(*parser.MatrixSelector) vs := ms.VectorSelector.(*parser.VectorSelector) var ( - samples = vals[0].(Matrix)[0] + samples = vals[0] rangeStart = enh.Ts - durationMilliseconds(ms.Range+vs.Offset) rangeEnd = enh.Ts - durationMilliseconds(vs.Offset) resultFloat float64 @@ -288,33 +288,33 @@ func histogramRate(points []HPoint, isCounter bool, metricName string, pos posra } // === delta(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcDelta(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return extrapolatedRate(vals, args, enh, false, false) +func funcDelta(_ []Vector, matrixVals Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return extrapolatedRate(matrixVals, args, enh, false, false) } // === rate(node parser.ValueTypeMatrix) (Vector, Annotations) === -func funcRate(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return extrapolatedRate(vals, args, enh, true, true) +func funcRate(_ []Vector, matrixVals Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return extrapolatedRate(matrixVals, args, enh, true, true) } // === increase(node parser.ValueTypeMatrix) (Vector, Annotations) === -func funcIncrease(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return extrapolatedRate(vals, args, enh, true, false) +func funcIncrease(_ []Vector, matrixVals Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return extrapolatedRate(matrixVals, args, enh, true, false) } // === irate(node parser.ValueTypeMatrix) (Vector, Annotations) === -func funcIrate(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return instantValue(vals, args, enh.Out, true) +func funcIrate(_ []Vector, matrixVals Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return instantValue(matrixVals, args, enh.Out, true) } // === idelta(node model.ValMatrix) (Vector, Annotations) === -func funcIdelta(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return instantValue(vals, args, enh.Out, false) +func funcIdelta(_ []Vector, matrixVals Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return instantValue(matrixVals, args, enh.Out, false) } -func instantValue(vals []parser.Value, args parser.Expressions, out Vector, isRate bool) (Vector, annotations.Annotations) { +func instantValue(vals Matrix, args parser.Expressions, out Vector, isRate bool) (Vector, annotations.Annotations) { var ( - samples = vals[0].(Matrix)[0] + samples = vals[0] metricName = samples.Metric.Get(labels.MetricName) ss = make([]Sample, 0, 2) annos annotations.Annotations @@ -441,14 +441,14 @@ func calcTrendValue(i int, tf, s0, s1, b float64) float64 { // affects how trends in historical data will affect the current data. A higher // trend factor increases the influence. of trends. Algorithm taken from // https://en.wikipedia.org/wiki/Exponential_smoothing . -func funcDoubleExponentialSmoothing(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - samples := vals[0].(Matrix)[0] +func funcDoubleExponentialSmoothing(vectorVals []Vector, matrixVal Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + samples := matrixVal[0] metricName := samples.Metric.Get(labels.MetricName) // The smoothing factor argument. - sf := vals[1].(Vector)[0].F + sf := vectorVals[0][0].F // The trend factor argument. - tf := vals[2].(Vector)[0].F + tf := vectorVals[1][0].F // Check that the input parameters are valid. if sf <= 0 || sf >= 1 { @@ -504,27 +504,27 @@ func filterFloats(v Vector) Vector { } // === sort(node parser.ValueTypeVector) (Vector, Annotations) === -func funcSort(vals []parser.Value, _ parser.Expressions, _ *EvalNodeHelper) (Vector, annotations.Annotations) { +func funcSort(vectorVals []Vector, _ Matrix, _ parser.Expressions, _ *EvalNodeHelper) (Vector, annotations.Annotations) { // NaN should sort to the bottom, so take descending sort with NaN first and // reverse it. - byValueSorter := vectorByReverseValueHeap(filterFloats(vals[0].(Vector))) + byValueSorter := vectorByReverseValueHeap(filterFloats(vectorVals[0])) sort.Sort(sort.Reverse(byValueSorter)) return Vector(byValueSorter), nil } // === sortDesc(node parser.ValueTypeVector) (Vector, Annotations) === -func funcSortDesc(vals []parser.Value, _ parser.Expressions, _ *EvalNodeHelper) (Vector, annotations.Annotations) { +func funcSortDesc(vectorVals []Vector, _ Matrix, _ parser.Expressions, _ *EvalNodeHelper) (Vector, annotations.Annotations) { // NaN should sort to the bottom, so take ascending sort with NaN first and // reverse it. - byValueSorter := vectorByValueHeap(filterFloats(vals[0].(Vector))) + byValueSorter := vectorByValueHeap(filterFloats(vectorVals[0])) sort.Sort(sort.Reverse(byValueSorter)) return Vector(byValueSorter), nil } // === sort_by_label(vector parser.ValueTypeVector, label parser.ValueTypeString...) (Vector, Annotations) === -func funcSortByLabel(vals []parser.Value, args parser.Expressions, _ *EvalNodeHelper) (Vector, annotations.Annotations) { +func funcSortByLabel(vectorVals []Vector, _ Matrix, args parser.Expressions, _ *EvalNodeHelper) (Vector, annotations.Annotations) { lbls := stringSliceFromArgs(args[1:]) - slices.SortFunc(vals[0].(Vector), func(a, b Sample) int { + slices.SortFunc(vectorVals[0], func(a, b Sample) int { for _, label := range lbls { lv1 := a.Metric.Get(label) lv2 := b.Metric.Get(label) @@ -544,13 +544,13 @@ func funcSortByLabel(vals []parser.Value, args parser.Expressions, _ *EvalNodeHe return labels.Compare(a.Metric, b.Metric) }) - return vals[0].(Vector), nil + return vectorVals[0], nil } // === sort_by_label_desc(vector parser.ValueTypeVector, label parser.ValueTypeString...) (Vector, Annotations) === -func funcSortByLabelDesc(vals []parser.Value, args parser.Expressions, _ *EvalNodeHelper) (Vector, annotations.Annotations) { +func funcSortByLabelDesc(vectorVals []Vector, _ Matrix, args parser.Expressions, _ *EvalNodeHelper) (Vector, annotations.Annotations) { lbls := stringSliceFromArgs(args[1:]) - slices.SortFunc(vals[0].(Vector), func(a, b Sample) int { + slices.SortFunc(vectorVals[0], func(a, b Sample) int { for _, label := range lbls { lv1 := a.Metric.Get(label) lv2 := b.Metric.Get(label) @@ -570,7 +570,7 @@ func funcSortByLabelDesc(vals []parser.Value, args parser.Expressions, _ *EvalNo return -labels.Compare(a.Metric, b.Metric) }) - return vals[0].(Vector), nil + return vectorVals[0], nil } func clamp(vec Vector, minVal, maxVal float64, enh *EvalNodeHelper) (Vector, annotations.Annotations) { @@ -595,46 +595,46 @@ func clamp(vec Vector, minVal, maxVal float64, enh *EvalNodeHelper) (Vector, ann } // === clamp(Vector parser.ValueTypeVector, min, max Scalar) (Vector, Annotations) === -func funcClamp(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - vec := vals[0].(Vector) - minVal := vals[1].(Vector)[0].F - maxVal := vals[2].(Vector)[0].F +func funcClamp(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + vec := vectorVals[0] + minVal := vectorVals[1][0].F + maxVal := vectorVals[2][0].F return clamp(vec, minVal, maxVal, enh) } // === clamp_max(Vector parser.ValueTypeVector, max Scalar) (Vector, Annotations) === -func funcClampMax(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - vec := vals[0].(Vector) - maxVal := vals[1].(Vector)[0].F +func funcClampMax(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + vec := vectorVals[0] + maxVal := vectorVals[1][0].F return clamp(vec, math.Inf(-1), maxVal, enh) } // === clamp_min(Vector parser.ValueTypeVector, min Scalar) (Vector, Annotations) === -func funcClampMin(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - vec := vals[0].(Vector) - minVal := vals[1].(Vector)[0].F +func funcClampMin(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + vec := vectorVals[0] + minVal := vectorVals[1][0].F return clamp(vec, minVal, math.Inf(+1), enh) } // === round(Vector parser.ValueTypeVector, toNearest=1 Scalar) (Vector, Annotations) === -func funcRound(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { +func funcRound(vectorVals []Vector, _ Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { // round returns a number rounded to toNearest. // Ties are solved by rounding up. toNearest := float64(1) if len(args) >= 2 { - toNearest = vals[1].(Vector)[0].F + toNearest = vectorVals[1][0].F } // Invert as it seems to cause fewer floating point accuracy issues. toNearestInverse := 1.0 / toNearest - return simpleFloatFunc(vals, enh, func(f float64) float64 { + return simpleFloatFunc(vectorVals, enh, func(f float64) float64 { return math.Floor(f*toNearestInverse+0.5) / toNearestInverse }), nil } // === Scalar(node parser.ValueTypeVector) Scalar === -func funcScalar(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { +func funcScalar(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { var ( - v = vals[0].(Vector) + v = vectorVals[0] value float64 found bool ) @@ -656,22 +656,22 @@ func funcScalar(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) return append(enh.Out, Sample{F: value}), nil } -func aggrOverTime(vals []parser.Value, enh *EvalNodeHelper, aggrFn func(Series) float64) Vector { - el := vals[0].(Matrix)[0] +func aggrOverTime(matrixVal Matrix, enh *EvalNodeHelper, aggrFn func(Series) float64) Vector { + el := matrixVal[0] return append(enh.Out, Sample{F: aggrFn(el)}) } -func aggrHistOverTime(vals []parser.Value, enh *EvalNodeHelper, aggrFn func(Series) (*histogram.FloatHistogram, error)) (Vector, error) { - el := vals[0].(Matrix)[0] +func aggrHistOverTime(matrixVal Matrix, enh *EvalNodeHelper, aggrFn func(Series) (*histogram.FloatHistogram, error)) (Vector, error) { + el := matrixVal[0] res, err := aggrFn(el) return append(enh.Out, Sample{H: res}), err } // === avg_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcAvgOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - firstSeries := vals[0].(Matrix)[0] +func funcAvgOverTime(_ []Vector, matrixVal Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + firstSeries := matrixVal[0] if len(firstSeries.Floats) > 0 && len(firstSeries.Histograms) > 0 { metricName := firstSeries.Metric.Get(labels.MetricName) return enh.Out, annotations.New().Add(annotations.NewMixedFloatsHistogramsWarning(metricName, args[0].PositionRange())) @@ -700,7 +700,7 @@ func funcAvgOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNode // the current implementation is accurate enough for practical purposes. if len(firstSeries.Floats) == 0 { // The passed values only contain histograms. - vec, err := aggrHistOverTime(vals, enh, func(s Series) (*histogram.FloatHistogram, error) { + vec, err := aggrHistOverTime(matrixVal, enh, func(s Series) (*histogram.FloatHistogram, error) { mean := s.Histograms[0].H.Copy() for i, h := range s.Histograms[1:] { count := float64(i + 2) @@ -727,7 +727,7 @@ func funcAvgOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNode } return vec, nil } - return aggrOverTime(vals, enh, func(s Series) float64 { + return aggrOverTime(matrixVal, enh, func(s Series) float64 { var ( // Pre-set the 1st sample to start the loop with the 2nd. sum, count = s.Floats[0].F, 1. @@ -761,15 +761,15 @@ func funcAvgOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNode } // === count_over_time(Matrix parser.ValueTypeMatrix) (Vector, Notes) === -func funcCountOverTime(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return aggrOverTime(vals, enh, func(s Series) float64 { +func funcCountOverTime(_ []Vector, matrixVals Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return aggrOverTime(matrixVals, enh, func(s Series) float64 { return float64(len(s.Floats) + len(s.Histograms)) }), nil } // === last_over_time(Matrix parser.ValueTypeMatrix) (Vector, Notes) === -func funcLastOverTime(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - el := vals[0].(Matrix)[0] +func funcLastOverTime(_ []Vector, matrixVal Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + el := matrixVal[0] var f FPoint if len(el.Floats) > 0 { @@ -794,8 +794,8 @@ func funcLastOverTime(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHe } // === mad_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcMadOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - samples := vals[0].(Matrix)[0] +func funcMadOverTime(_ []Vector, matrixVal Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + samples := matrixVal[0] var annos annotations.Annotations if len(samples.Floats) == 0 { return enh.Out, nil @@ -804,7 +804,7 @@ func funcMadOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNode metricName := samples.Metric.Get(labels.MetricName) annos.Add(annotations.NewHistogramIgnoredInMixedRangeInfo(metricName, args[0].PositionRange())) } - return aggrOverTime(vals, enh, func(s Series) float64 { + return aggrOverTime(matrixVal, enh, func(s Series) float64 { values := make(vectorByValueHeap, 0, len(s.Floats)) for _, f := range s.Floats { values = append(values, Sample{F: f.F}) @@ -819,8 +819,8 @@ func funcMadOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNode } // === ts_of_last_over_time(Matrix parser.ValueTypeMatrix) (Vector, Notes) === -func funcTsOfLastOverTime(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - el := vals[0].(Matrix)[0] +func funcTsOfLastOverTime(_ []Vector, matrixVal Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + el := matrixVal[0] var tf int64 if len(el.Floats) > 0 { @@ -839,22 +839,22 @@ func funcTsOfLastOverTime(vals []parser.Value, _ parser.Expressions, enh *EvalNo } // === ts_of_max_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcTsOfMaxOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return compareOverTime(vals, args, enh, func(cur, maxVal float64) bool { +func funcTsOfMaxOverTime(_ []Vector, matrixVal Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return compareOverTime(matrixVal, args, enh, func(cur, maxVal float64) bool { return (cur >= maxVal) || math.IsNaN(maxVal) }, true) } // === ts_of_min_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcTsOfMinOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return compareOverTime(vals, args, enh, func(cur, maxVal float64) bool { +func funcTsOfMinOverTime(_ []Vector, matrixVals Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return compareOverTime(matrixVals, args, enh, func(cur, maxVal float64) bool { return (cur <= maxVal) || math.IsNaN(maxVal) }, true) } // compareOverTime is a helper used by funcMaxOverTime and funcMinOverTime. -func compareOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper, compareFn func(float64, float64) bool, returnTimestamp bool) (Vector, annotations.Annotations) { - samples := vals[0].(Matrix)[0] +func compareOverTime(matrixVal Matrix, args parser.Expressions, enh *EvalNodeHelper, compareFn func(float64, float64) bool, returnTimestamp bool) (Vector, annotations.Annotations) { + samples := matrixVal[0] var annos annotations.Annotations if len(samples.Floats) == 0 { return enh.Out, nil @@ -863,7 +863,7 @@ func compareOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNode metricName := samples.Metric.Get(labels.MetricName) annos.Add(annotations.NewHistogramIgnoredInMixedRangeInfo(metricName, args[0].PositionRange())) } - return aggrOverTime(vals, enh, func(s Series) float64 { + return aggrOverTime(matrixVal, enh, func(s Series) float64 { maxVal := s.Floats[0].F tsOfMax := s.Floats[0].T for _, f := range s.Floats { @@ -880,29 +880,29 @@ func compareOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNode } // === max_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcMaxOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return compareOverTime(vals, args, enh, func(cur, maxVal float64) bool { +func funcMaxOverTime(_ []Vector, matrixVals Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return compareOverTime(matrixVals, args, enh, func(cur, maxVal float64) bool { return (cur > maxVal) || math.IsNaN(maxVal) }, false) } // === min_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcMinOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return compareOverTime(vals, args, enh, func(cur, maxVal float64) bool { +func funcMinOverTime(_ []Vector, matrixVals Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return compareOverTime(matrixVals, args, enh, func(cur, maxVal float64) bool { return (cur < maxVal) || math.IsNaN(maxVal) }, false) } // === sum_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcSumOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - firstSeries := vals[0].(Matrix)[0] +func funcSumOverTime(_ []Vector, matrixVal Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + firstSeries := matrixVal[0] if len(firstSeries.Floats) > 0 && len(firstSeries.Histograms) > 0 { metricName := firstSeries.Metric.Get(labels.MetricName) return enh.Out, annotations.New().Add(annotations.NewMixedFloatsHistogramsWarning(metricName, args[0].PositionRange())) } if len(firstSeries.Floats) == 0 { // The passed values only contain histograms. - vec, err := aggrHistOverTime(vals, enh, func(s Series) (*histogram.FloatHistogram, error) { + vec, err := aggrHistOverTime(matrixVal, enh, func(s Series) (*histogram.FloatHistogram, error) { sum := s.Histograms[0].H.Copy() for _, h := range s.Histograms[1:] { _, err := sum.Add(h.H) @@ -922,7 +922,7 @@ func funcSumOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNode } return vec, nil } - return aggrOverTime(vals, enh, func(s Series) float64 { + return aggrOverTime(matrixVal, enh, func(s Series) float64 { var sum, c float64 for _, f := range s.Floats { sum, c = kahanSumInc(f.F, sum, c) @@ -935,9 +935,9 @@ func funcSumOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNode } // === quantile_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcQuantileOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - q := vals[0].(Vector)[0].F - el := vals[1].(Matrix)[0] +func funcQuantileOverTime(vectorVals []Vector, matrixVal Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + q := vectorVals[0][0].F + el := matrixVal[0] if len(el.Floats) == 0 { return enh.Out, nil } @@ -957,8 +957,8 @@ func funcQuantileOverTime(vals []parser.Value, args parser.Expressions, enh *Eva return append(enh.Out, Sample{F: quantile(q, values)}), annos } -func varianceOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper, varianceToResult func(float64) float64) (Vector, annotations.Annotations) { - samples := vals[0].(Matrix)[0] +func varianceOverTime(matrixVal Matrix, args parser.Expressions, enh *EvalNodeHelper, varianceToResult func(float64) float64) (Vector, annotations.Annotations) { + samples := matrixVal[0] var annos annotations.Annotations if len(samples.Floats) == 0 { return enh.Out, nil @@ -967,7 +967,7 @@ func varianceOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNod metricName := samples.Metric.Get(labels.MetricName) annos.Add(annotations.NewHistogramIgnoredInMixedRangeInfo(metricName, args[0].PositionRange())) } - return aggrOverTime(vals, enh, func(s Series) float64 { + return aggrOverTime(matrixVal, enh, func(s Series) float64 { var count float64 var mean, cMean float64 var aux, cAux float64 @@ -986,18 +986,18 @@ func varianceOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNod } // === stddev_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcStddevOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return varianceOverTime(vals, args, enh, math.Sqrt) +func funcStddevOverTime(_ []Vector, matrixVals Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return varianceOverTime(matrixVals, args, enh, math.Sqrt) } // === stdvar_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcStdvarOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return varianceOverTime(vals, args, enh, nil) +func funcStdvarOverTime(_ []Vector, matrixVals Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return varianceOverTime(matrixVals, args, enh, nil) } // === absent(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcAbsent(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - if len(vals[0].(Vector)) > 0 { +func funcAbsent(vectorVals []Vector, _ Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + if len(vectorVals[0]) > 0 { return enh.Out, nil } return append(enh.Out, @@ -1012,19 +1012,19 @@ func funcAbsent(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelpe // This function will return 1 if the matrix has at least one element. // Due to engine optimization, this function is only called when this condition is true. // Then, the engine post-processes the results to get the expected output. -func funcAbsentOverTime(_ []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { +func funcAbsentOverTime(_ []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { return append(enh.Out, Sample{F: 1}), nil } // === present_over_time(Vector parser.ValueTypeMatrix) (Vector, Annotations) === -func funcPresentOverTime(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return aggrOverTime(vals, enh, func(_ Series) float64 { +func funcPresentOverTime(_ []Vector, matrixVals Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return aggrOverTime(matrixVals, enh, func(_ Series) float64 { return 1 }), nil } -func simpleFloatFunc(vals []parser.Value, enh *EvalNodeHelper, f func(float64) float64) Vector { - for _, el := range vals[0].(Vector) { +func simpleFloatFunc(vectorVals []Vector, enh *EvalNodeHelper, f func(float64) float64) Vector { + for _, el := range vectorVals[0] { if el.H == nil { // Process only float samples. if !enh.enableDelayedNameRemoval { el.Metric = el.Metric.DropReserved(schema.IsMetadataLabel) @@ -1040,127 +1040,127 @@ func simpleFloatFunc(vals []parser.Value, enh *EvalNodeHelper, f func(float64) f } // === abs(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcAbs(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Abs), nil +func funcAbs(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Abs), nil } // === ceil(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcCeil(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Ceil), nil +func funcCeil(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Ceil), nil } // === floor(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcFloor(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Floor), nil +func funcFloor(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Floor), nil } // === exp(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcExp(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Exp), nil +func funcExp(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Exp), nil } // === sqrt(Vector VectorNode) (Vector, Annotations) === -func funcSqrt(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Sqrt), nil +func funcSqrt(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Sqrt), nil } // === ln(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcLn(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Log), nil +func funcLn(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Log), nil } // === log2(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcLog2(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Log2), nil +func funcLog2(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Log2), nil } // === log10(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcLog10(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Log10), nil +func funcLog10(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Log10), nil } // === sin(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcSin(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Sin), nil +func funcSin(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Sin), nil } // === cos(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcCos(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Cos), nil +func funcCos(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Cos), nil } // === tan(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcTan(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Tan), nil +func funcTan(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Tan), nil } // === asin(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcAsin(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Asin), nil +func funcAsin(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Asin), nil } // === acos(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcAcos(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Acos), nil +func funcAcos(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Acos), nil } // === atan(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcAtan(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Atan), nil +func funcAtan(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Atan), nil } // === sinh(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcSinh(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Sinh), nil +func funcSinh(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Sinh), nil } // === cosh(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcCosh(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Cosh), nil +func funcCosh(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Cosh), nil } // === tanh(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcTanh(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Tanh), nil +func funcTanh(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Tanh), nil } // === asinh(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcAsinh(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Asinh), nil +func funcAsinh(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Asinh), nil } // === acosh(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcAcosh(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Acosh), nil +func funcAcosh(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Acosh), nil } // === atanh(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcAtanh(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, math.Atanh), nil +func funcAtanh(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, math.Atanh), nil } // === rad(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcRad(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, func(v float64) float64 { +func funcRad(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, func(v float64) float64 { return v * math.Pi / 180 }), nil } // === deg(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcDeg(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, func(v float64) float64 { +func funcDeg(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, func(v float64) float64 { return v * 180 / math.Pi }), nil } // === pi() Scalar === -func funcPi(_ []parser.Value, _ parser.Expressions, _ *EvalNodeHelper) (Vector, annotations.Annotations) { +func funcPi(_ []Vector, _ Matrix, _ parser.Expressions, _ *EvalNodeHelper) (Vector, annotations.Annotations) { return Vector{Sample{F: math.Pi}}, nil } // === sgn(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcSgn(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleFloatFunc(vals, enh, func(v float64) float64 { +func funcSgn(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleFloatFunc(vectorVals, enh, func(v float64) float64 { switch { case v < 0: return -1 @@ -1173,8 +1173,8 @@ func funcSgn(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Ve } // === timestamp(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcTimestamp(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - vec := vals[0].(Vector) +func funcTimestamp(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + vec := vectorVals[0] for _, el := range vec { if !enh.enableDelayedNameRemoval { el.Metric = el.Metric.DropReserved(schema.IsMetadataLabel) @@ -1250,8 +1250,8 @@ func linearRegression(samples []FPoint, interceptTime int64) (slope, intercept f } // === deriv(node parser.ValueTypeMatrix) (Vector, Annotations) === -func funcDeriv(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - samples := vals[0].(Matrix)[0] +func funcDeriv(_ []Vector, matrixVal Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + samples := matrixVal[0] metricName := samples.Metric.Get(labels.MetricName) // No sense in trying to compute a derivative without at least two float points. @@ -1275,9 +1275,9 @@ func funcDeriv(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper } // === predict_linear(node parser.ValueTypeMatrix, k parser.ValueTypeScalar) (Vector, Annotations) === -func funcPredictLinear(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - samples := vals[0].(Matrix)[0] - duration := vals[1].(Vector)[0].F +func funcPredictLinear(vectorVals []Vector, matrixVal Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + samples := matrixVal[0] + duration := vectorVals[0][0].F metricName := samples.Metric.Get(labels.MetricName) // No sense in trying to predict anything without at least two float points. @@ -1297,8 +1297,8 @@ func funcPredictLinear(vals []parser.Value, args parser.Expressions, enh *EvalNo return append(enh.Out, Sample{F: slope*duration + intercept}), nil } -func simpleHistogramFunc(vals []parser.Value, enh *EvalNodeHelper, f func(h *histogram.FloatHistogram) float64) Vector { - for _, el := range vals[0].(Vector) { +func simpleHistogramFunc(vectorVals []Vector, enh *EvalNodeHelper, f func(h *histogram.FloatHistogram) float64) Vector { + for _, el := range vectorVals[0] { if el.H != nil { // Process only histogram samples. if !enh.enableDelayedNameRemoval { el.Metric = el.Metric.DropMetricName() @@ -1314,28 +1314,28 @@ func simpleHistogramFunc(vals []parser.Value, enh *EvalNodeHelper, f func(h *his } // === histogram_count(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcHistogramCount(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleHistogramFunc(vals, enh, func(h *histogram.FloatHistogram) float64 { +func funcHistogramCount(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleHistogramFunc(vectorVals, enh, func(h *histogram.FloatHistogram) float64 { return h.Count }), nil } // === histogram_sum(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcHistogramSum(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleHistogramFunc(vals, enh, func(h *histogram.FloatHistogram) float64 { +func funcHistogramSum(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleHistogramFunc(vectorVals, enh, func(h *histogram.FloatHistogram) float64 { return h.Sum }), nil } // === histogram_avg(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcHistogramAvg(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return simpleHistogramFunc(vals, enh, func(h *histogram.FloatHistogram) float64 { +func funcHistogramAvg(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return simpleHistogramFunc(vectorVals, enh, func(h *histogram.FloatHistogram) float64 { return h.Sum / h.Count }), nil } -func histogramVariance(vals []parser.Value, enh *EvalNodeHelper, varianceToResult func(float64) float64) (Vector, annotations.Annotations) { - return simpleHistogramFunc(vals, enh, func(h *histogram.FloatHistogram) float64 { +func histogramVariance(vectorVals []Vector, enh *EvalNodeHelper, varianceToResult func(float64) float64) (Vector, annotations.Annotations) { + return simpleHistogramFunc(vectorVals, enh, func(h *histogram.FloatHistogram) float64 { mean := h.Sum / h.Count var variance, cVariance float64 it := h.AllBucketIterator() @@ -1372,20 +1372,20 @@ func histogramVariance(vals []parser.Value, enh *EvalNodeHelper, varianceToResul } // === histogram_stddev(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcHistogramStdDev(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return histogramVariance(vals, enh, math.Sqrt) +func funcHistogramStdDev(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return histogramVariance(vectorVals, enh, math.Sqrt) } // === histogram_stdvar(Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcHistogramStdVar(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return histogramVariance(vals, enh, nil) +func funcHistogramStdVar(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return histogramVariance(vectorVals, enh, nil) } // === histogram_fraction(lower, upper parser.ValueTypeScalar, Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcHistogramFraction(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - lower := vals[0].(Vector)[0].F - upper := vals[1].(Vector)[0].F - inVec := vals[2].(Vector) +func funcHistogramFraction(vectorVals []Vector, _ Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + lower := vectorVals[0][0].F + upper := vectorVals[1][0].F + inVec := vectorVals[2] annos := enh.resetHistograms(inVec, args[2]) @@ -1427,9 +1427,9 @@ func funcHistogramFraction(vals []parser.Value, args parser.Expressions, enh *Ev } // === histogram_quantile(k parser.ValueTypeScalar, Vector parser.ValueTypeVector) (Vector, Annotations) === -func funcHistogramQuantile(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - q := vals[0].(Vector)[0].F - inVec := vals[1].(Vector) +func funcHistogramQuantile(vectorVals []Vector, _ Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + q := vectorVals[0][0].F + inVec := vectorVals[1] var annos annotations.Annotations if math.IsNaN(q) || q < 0 || q > 1 { @@ -1479,9 +1479,9 @@ func funcHistogramQuantile(vals []parser.Value, args parser.Expressions, enh *Ev } // === resets(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcResets(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - floats := vals[0].(Matrix)[0].Floats - histograms := vals[0].(Matrix)[0].Histograms +func funcResets(_ []Vector, matrixVal Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + floats := matrixVal[0].Floats + histograms := matrixVal[0].Histograms resets := 0 if len(floats) == 0 && len(histograms) == 0 { return enh.Out, nil @@ -1524,9 +1524,9 @@ func funcResets(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) } // === changes(Matrix parser.ValueTypeMatrix) (Vector, Annotations) === -func funcChanges(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - floats := vals[0].(Matrix)[0].Floats - histograms := vals[0].(Matrix)[0].Histograms +func funcChanges(_ []Vector, matrixVal Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + floats := matrixVal[0].Floats + histograms := matrixVal[0].Histograms changes := 0 if len(floats) == 0 && len(histograms) == 0 { return enh.Out, nil @@ -1612,11 +1612,11 @@ func (ev *evaluator) evalLabelReplace(ctx context.Context, args parser.Expressio } // === Vector(s Scalar) (Vector, Annotations) === -func funcVector(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { +func funcVector(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { return append(enh.Out, Sample{ Metric: labels.Labels{}, - F: vals[0].(Vector)[0].F, + F: vectorVals[0][0].F, }), nil } @@ -1666,8 +1666,8 @@ func (ev *evaluator) evalLabelJoin(ctx context.Context, args parser.Expressions) } // Common code for date related functions. -func dateWrapper(vals []parser.Value, enh *EvalNodeHelper, f func(time.Time) float64) Vector { - if len(vals) == 0 { +func dateWrapper(vectorVals []Vector, enh *EvalNodeHelper, f func(time.Time) float64) Vector { + if len(vectorVals) == 0 { return append(enh.Out, Sample{ Metric: labels.Labels{}, @@ -1675,7 +1675,7 @@ func dateWrapper(vals []parser.Value, enh *EvalNodeHelper, f func(time.Time) flo }) } - for _, el := range vals[0].(Vector) { + for _, el := range vectorVals[0] { if el.H != nil { // Ignore histogram sample. continue @@ -1694,57 +1694,57 @@ func dateWrapper(vals []parser.Value, enh *EvalNodeHelper, f func(time.Time) flo } // === days_in_month(v Vector) Scalar === -func funcDaysInMonth(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return dateWrapper(vals, enh, func(t time.Time) float64 { +func funcDaysInMonth(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return dateWrapper(vectorVals, enh, func(t time.Time) float64 { return float64(32 - time.Date(t.Year(), t.Month(), 32, 0, 0, 0, 0, time.UTC).Day()) }), nil } // === day_of_month(v Vector) Scalar === -func funcDayOfMonth(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return dateWrapper(vals, enh, func(t time.Time) float64 { +func funcDayOfMonth(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return dateWrapper(vectorVals, enh, func(t time.Time) float64 { return float64(t.Day()) }), nil } // === day_of_week(v Vector) Scalar === -func funcDayOfWeek(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return dateWrapper(vals, enh, func(t time.Time) float64 { +func funcDayOfWeek(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return dateWrapper(vectorVals, enh, func(t time.Time) float64 { return float64(t.Weekday()) }), nil } // === day_of_year(v Vector) Scalar === -func funcDayOfYear(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return dateWrapper(vals, enh, func(t time.Time) float64 { +func funcDayOfYear(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return dateWrapper(vectorVals, enh, func(t time.Time) float64 { return float64(t.YearDay()) }), nil } // === hour(v Vector) Scalar === -func funcHour(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return dateWrapper(vals, enh, func(t time.Time) float64 { +func funcHour(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return dateWrapper(vectorVals, enh, func(t time.Time) float64 { return float64(t.Hour()) }), nil } // === minute(v Vector) Scalar === -func funcMinute(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return dateWrapper(vals, enh, func(t time.Time) float64 { +func funcMinute(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return dateWrapper(vectorVals, enh, func(t time.Time) float64 { return float64(t.Minute()) }), nil } // === month(v Vector) Scalar === -func funcMonth(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return dateWrapper(vals, enh, func(t time.Time) float64 { +func funcMonth(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return dateWrapper(vectorVals, enh, func(t time.Time) float64 { return float64(t.Month()) }), nil } // === year(v Vector) Scalar === -func funcYear(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { - return dateWrapper(vals, enh, func(t time.Time) float64 { +func funcYear(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) { + return dateWrapper(vectorVals, enh, func(t time.Time) float64 { return float64(t.Year()) }), nil }