SSE: Reduce to apply Mode to instant vector (mathexp.Number) (#74859)

This commit is contained in:
Yuri Tseretyan 2023-09-14 12:26:00 -04:00 committed by GitHub
parent fb91919e3b
commit 68eda133e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 82 additions and 30 deletions

View File

@ -175,12 +175,21 @@ func (gr *ReduceCommand) Execute(ctx context.Context, _ time.Time, vars mathexp.
}
newRes.Values = append(newRes.Values, num)
case mathexp.Number: // if incoming vars is just a number, any reduce op is just a noop, add it as it is
value := v.GetFloat64Value()
if gr.seriesMapper != nil {
value = gr.seriesMapper.MapInput(value)
if value == nil { // same logic as in mapSeries
continue
}
}
copyV := mathexp.NewNumber(gr.refID, v.GetLabels())
copyV.SetValue(v.GetFloat64Value())
copyV.AddNotice(data.Notice{
Severity: data.NoticeSeverityWarning,
Text: fmt.Sprintf("Reduce operation is not needed. Input query or expression %s is already reduced data.", gr.VarToReduce),
})
copyV.SetValue(value)
if gr.seriesMapper == nil {
copyV.AddNotice(data.Notice{
Severity: data.NoticeSeverityWarning,
Text: fmt.Sprintf("Reduce operation is not needed. Input query or expression %s is already reduced data.", gr.VarToReduce),
})
}
newRes.Values = append(newRes.Values, copyV)
case mathexp.NoData:
newRes.Values = append(newRes.Values, v.New())

View File

@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"math"
"math/rand"
"testing"
"time"
@ -100,42 +101,83 @@ func Test_UnmarshalReduceCommand_Settings(t *testing.T) {
func TestReduceExecute(t *testing.T) {
varToReduce := util.GenerateShortUID()
cmd, err := NewReduceCommand(util.GenerateShortUID(), randomReduceFunc(), varToReduce, nil)
require.NoError(t, err)
t.Run("should noop if Number", func(t *testing.T) {
t.Run("when mapper is nil", func(t *testing.T) {
cmd, err := NewReduceCommand(util.GenerateShortUID(), randomReduceFunc(), varToReduce, nil)
require.NoError(t, err)
t.Run("should noop if Number", func(t *testing.T) {
var numbers mathexp.Values = []mathexp.Value{
mathexp.GenerateNumber(util.Pointer(rand.Float64())),
mathexp.GenerateNumber(util.Pointer(rand.Float64())),
mathexp.GenerateNumber(util.Pointer(rand.Float64())),
}
vars := map[string]mathexp.Results{
varToReduce: {
Values: numbers,
},
}
execute, err := cmd.Execute(context.Background(), time.Now(), vars, tracing.NewFakeTracer())
require.NoError(t, err)
require.Len(t, execute.Values, len(numbers))
for i, value := range execute.Values {
expected := numbers[i]
require.Equal(t, expected.Type(), value.Type())
require.Equal(t, expected.GetLabels(), value.GetLabels())
expectedValue := expected.Value().(*mathexp.Number).GetFloat64Value()
actualValue := value.Value().(*mathexp.Number).GetFloat64Value()
require.Equal(t, expectedValue, actualValue)
}
t.Run("should add warn notices to every frame", func(t *testing.T) {
frames := execute.Values.AsDataFrames("test")
for _, frame := range frames {
require.Len(t, frame.Meta.Notices, 1)
notice := frame.Meta.Notices[0]
require.Equal(t, data.NoticeSeverityWarning, notice.Severity)
}
})
})
})
t.Run("when mapper is not nil", func(t *testing.T) {
var numbers mathexp.Values = []mathexp.Value{
mathexp.GenerateNumber(util.Pointer(rand.Float64())),
mathexp.GenerateNumber(util.Pointer(rand.Float64())),
mathexp.GenerateNumber(nil),
mathexp.GenerateNumber(util.Pointer(math.NaN())),
mathexp.GenerateNumber(util.Pointer(math.Inf(-1))),
mathexp.GenerateNumber(util.Pointer(math.Inf(1))),
mathexp.GenerateNumber(util.Pointer(rand.Float64())),
}
varToReduce := util.GenerateShortUID()
vars := map[string]mathexp.Results{
varToReduce: {
Values: numbers,
},
}
execute, err := cmd.Execute(context.Background(), time.Now(), vars, tracing.NewFakeTracer())
require.NoError(t, err)
t.Run("drop all non numbers if mapper is DropNonNumber", func(t *testing.T) {
cmd, err := NewReduceCommand(util.GenerateShortUID(), randomReduceFunc(), varToReduce, &mathexp.DropNonNumber{})
require.NoError(t, err)
execute, err := cmd.Execute(context.Background(), time.Now(), vars, tracing.NewFakeTracer())
require.NoError(t, err)
require.Len(t, execute.Values, 2)
})
require.Len(t, execute.Values, len(numbers))
for i, value := range execute.Values {
expected := numbers[i]
require.Equal(t, expected.Type(), value.Type())
require.Equal(t, expected.GetLabels(), value.GetLabels())
expectedValue := expected.Value().(*mathexp.Number).GetFloat64Value()
actualValue := value.Value().(*mathexp.Number).GetFloat64Value()
require.Equal(t, expectedValue, actualValue)
}
t.Run("should add warn notices to every frame", func(t *testing.T) {
frames := execute.Values.AsDataFrames("test")
for _, frame := range frames {
require.Len(t, frame.Meta.Notices, 1)
notice := frame.Meta.Notices[0]
require.Equal(t, data.NoticeSeverityWarning, notice.Severity)
t.Run("replace all non numbers if mapper is ReplaceNonNumberWithValue", func(t *testing.T) {
cmd, err := NewReduceCommand(util.GenerateShortUID(), randomReduceFunc(), varToReduce, &mathexp.ReplaceNonNumberWithValue{Value: 1})
require.NoError(t, err)
execute, err := cmd.Execute(context.Background(), time.Now(), vars, tracing.NewFakeTracer())
require.NoError(t, err)
require.Len(t, execute.Values, len(numbers))
for _, value := range execute.Values[1 : len(numbers)-1] {
require.IsType(t, &mathexp.Number{}, value.Value())
f := value.Value().(*mathexp.Number)
require.Equal(t, float64(1), *f.GetFloat64Value())
}
})
})
@ -150,7 +192,8 @@ func TestReduceExecute(t *testing.T) {
Values: noData,
},
}
cmd, err := NewReduceCommand(util.GenerateShortUID(), randomReduceFunc(), varToReduce, nil)
require.NoError(t, err)
results, err := cmd.Execute(context.Background(), time.Now(), vars, tracing.NewFakeTracer())
require.NoError(t, err)