mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
SSE: Change math expression to accept any value convertible to float (#34996)
* SSE: Change math expression to accept any scalar value * Apply suggestions from code review * Update test * Remove TODO
This commit is contained in:
parent
b558d32502
commit
eeb84d09c2
2
go.mod
2
go.mod
@ -52,7 +52,7 @@ require (
|
|||||||
github.com/gosimple/slug v1.9.0
|
github.com/gosimple/slug v1.9.0
|
||||||
github.com/grafana/grafana-aws-sdk v0.4.0
|
github.com/grafana/grafana-aws-sdk v0.4.0
|
||||||
github.com/grafana/grafana-live-sdk v0.0.6
|
github.com/grafana/grafana-live-sdk v0.0.6
|
||||||
github.com/grafana/grafana-plugin-sdk-go v0.102.0
|
github.com/grafana/grafana-plugin-sdk-go v0.104.0
|
||||||
github.com/grafana/loki v1.6.2-0.20210520072447-15d417efe103
|
github.com/grafana/loki v1.6.2-0.20210520072447-15d417efe103
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
||||||
github.com/hashicorp/go-hclog v0.16.0
|
github.com/hashicorp/go-hclog v0.16.0
|
||||||
|
2
go.sum
2
go.sum
@ -922,6 +922,8 @@ github.com/grafana/grafana-plugin-sdk-go v0.79.0/go.mod h1:NvxLzGkVhnoBKwzkst6CF
|
|||||||
github.com/grafana/grafana-plugin-sdk-go v0.91.0/go.mod h1:Ot3k7nY7P6DXmUsDgKvNB7oG1v7PRyTdmnYVoS554bU=
|
github.com/grafana/grafana-plugin-sdk-go v0.91.0/go.mod h1:Ot3k7nY7P6DXmUsDgKvNB7oG1v7PRyTdmnYVoS554bU=
|
||||||
github.com/grafana/grafana-plugin-sdk-go v0.102.0 h1:Pknh7mlOaJvdhPgKHxcimDOSd9h29eSpA34W0/sOF6c=
|
github.com/grafana/grafana-plugin-sdk-go v0.102.0 h1:Pknh7mlOaJvdhPgKHxcimDOSd9h29eSpA34W0/sOF6c=
|
||||||
github.com/grafana/grafana-plugin-sdk-go v0.102.0/go.mod h1:D7x3ah+1d4phNXpbnOaxa/osSaZlwh9/ZUnGGzegRbk=
|
github.com/grafana/grafana-plugin-sdk-go v0.102.0/go.mod h1:D7x3ah+1d4phNXpbnOaxa/osSaZlwh9/ZUnGGzegRbk=
|
||||||
|
github.com/grafana/grafana-plugin-sdk-go v0.104.0 h1:Ij2tPdEasSjCb2MxHaaiylyW4RLVZYyWpApzN/mlTxo=
|
||||||
|
github.com/grafana/grafana-plugin-sdk-go v0.104.0/go.mod h1:D7x3ah+1d4phNXpbnOaxa/osSaZlwh9/ZUnGGzegRbk=
|
||||||
github.com/grafana/loki v1.6.2-0.20210520072447-15d417efe103 h1:qCmofFVwQR9QnsinstVqI1NPLMVl33jNCnOCXEAVn6E=
|
github.com/grafana/loki v1.6.2-0.20210520072447-15d417efe103 h1:qCmofFVwQR9QnsinstVqI1NPLMVl33jNCnOCXEAVn6E=
|
||||||
github.com/grafana/loki v1.6.2-0.20210520072447-15d417efe103/go.mod h1:GHIsn+EohCChsdu5YouNZewqLeV9L2FNw4DEJU3P9qE=
|
github.com/grafana/loki v1.6.2-0.20210520072447-15d417efe103/go.mod h1:GHIsn+EohCChsdu5YouNZewqLeV9L2FNw4DEJU3P9qE=
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
|
@ -30,10 +30,27 @@ func makeNumber(name string, labels data.Labels, f *float64) Number {
|
|||||||
return newNumber
|
return newNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unixTimePointer(sec, nsec int64) *time.Time {
|
||||||
|
t := time.Unix(sec, nsec)
|
||||||
|
return &t
|
||||||
|
}
|
||||||
|
|
||||||
func float64Pointer(f float64) *float64 {
|
func float64Pointer(f float64) *float64 {
|
||||||
return &f
|
return &f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func strPointer(s string) *string {
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
|
||||||
|
func int64Pointer(i int64) *int64 {
|
||||||
|
return &i
|
||||||
|
}
|
||||||
|
|
||||||
|
func boolPointer(b bool) *bool {
|
||||||
|
return &b
|
||||||
|
}
|
||||||
|
|
||||||
var aSeries = Vars{
|
var aSeries = Vars{
|
||||||
"A": Results{
|
"A": Results{
|
||||||
[]Value{
|
[]Value{
|
||||||
|
@ -18,8 +18,6 @@ const seriesTypeValIdx = 1
|
|||||||
// Series has a time.Time and a *float64 fields.
|
// Series has a time.Time and a *float64 fields.
|
||||||
type Series struct {
|
type Series struct {
|
||||||
Frame *data.Frame
|
Frame *data.Frame
|
||||||
// TODO:
|
|
||||||
// - Value can be different number types
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SeriesFromFrame validates that the dataframe can be considered a Series type
|
// SeriesFromFrame validates that the dataframe can be considered a Series type
|
||||||
@ -49,6 +47,26 @@ FIELDS:
|
|||||||
valueNullable = true
|
valueNullable = true
|
||||||
valueIdx = i
|
valueIdx = i
|
||||||
default:
|
default:
|
||||||
|
// Handle default case
|
||||||
|
// try to convert to *float64
|
||||||
|
var convertedField *data.Field
|
||||||
|
for j := 0; j < field.Len(); j++ {
|
||||||
|
ff, err := field.NullableFloatAt(j)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if convertedField == nil { // initialise field
|
||||||
|
convertedField = data.NewFieldFromFieldType(data.FieldTypeNullableFloat64, field.Len())
|
||||||
|
convertedField.Name = field.Name
|
||||||
|
convertedField.Labels = field.Labels
|
||||||
|
}
|
||||||
|
convertedField.Set(j, ff)
|
||||||
|
}
|
||||||
|
if convertedField != nil {
|
||||||
|
frame.Fields[i] = convertedField
|
||||||
|
valueNullable = true
|
||||||
|
valueIdx = i
|
||||||
|
}
|
||||||
if valueIdx != -1 && timeIdx != -1 {
|
if valueIdx != -1 && timeIdx != -1 {
|
||||||
break FIELDS
|
break FIELDS
|
||||||
}
|
}
|
||||||
@ -65,7 +83,7 @@ FIELDS:
|
|||||||
if timeNullable { // make time not nullable if it is in the input
|
if timeNullable { // make time not nullable if it is in the input
|
||||||
timeSlice := make([]time.Time, 0, frame.Fields[timeIdx].Len())
|
timeSlice := make([]time.Time, 0, frame.Fields[timeIdx].Len())
|
||||||
for rowIdx := 0; rowIdx < frame.Fields[timeIdx].Len(); rowIdx++ {
|
for rowIdx := 0; rowIdx < frame.Fields[timeIdx].Len(); rowIdx++ {
|
||||||
val, ok := frame.At(0, rowIdx).(*time.Time)
|
val, ok := frame.At(timeIdx, rowIdx).(*time.Time)
|
||||||
if !ok {
|
if !ok {
|
||||||
return s, fmt.Errorf("unexpected time type, expected *time.Time but got %T", val)
|
return s, fmt.Errorf("unexpected time type, expected *time.Time but got %T", val)
|
||||||
}
|
}
|
||||||
|
@ -136,6 +136,132 @@ func TestSeriesFromFrame(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "[]*int, []*time frame should convert",
|
||||||
|
frame: &data.Frame{
|
||||||
|
Name: "test",
|
||||||
|
Fields: []*data.Field{
|
||||||
|
data.NewField("time", nil, []*time.Time{unixTimePointer(5, 0)}),
|
||||||
|
data.NewField("value", nil, []*int64{int64Pointer(5)}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errIs: assert.NoError,
|
||||||
|
Is: assert.Equal,
|
||||||
|
Series: Series{
|
||||||
|
Frame: &data.Frame{
|
||||||
|
Name: "test",
|
||||||
|
Fields: []*data.Field{
|
||||||
|
data.NewField("time", nil, []time.Time{time.Unix(5, 0)}),
|
||||||
|
data.NewField("value", nil, []*float64{float64Pointer(5)}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "[]int, []*time frame should convert",
|
||||||
|
frame: &data.Frame{
|
||||||
|
Name: "test",
|
||||||
|
Fields: []*data.Field{
|
||||||
|
data.NewField("time", nil, []*time.Time{unixTimePointer(5, 0)}),
|
||||||
|
data.NewField("value", nil, []int64{5}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errIs: assert.NoError,
|
||||||
|
Is: assert.Equal,
|
||||||
|
Series: Series{
|
||||||
|
Frame: &data.Frame{
|
||||||
|
Name: "test",
|
||||||
|
Fields: []*data.Field{
|
||||||
|
data.NewField("time", nil, []time.Time{time.Unix(5, 0)}),
|
||||||
|
data.NewField("value", nil, []*float64{float64Pointer(5)}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "[]string, []*time frame should convert",
|
||||||
|
frame: &data.Frame{
|
||||||
|
Name: "test",
|
||||||
|
Fields: []*data.Field{
|
||||||
|
data.NewField("time", nil, []*time.Time{unixTimePointer(5, 0)}),
|
||||||
|
data.NewField("value", nil, []string{"5"}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errIs: assert.NoError,
|
||||||
|
Is: assert.Equal,
|
||||||
|
Series: Series{
|
||||||
|
Frame: &data.Frame{
|
||||||
|
Name: "test",
|
||||||
|
Fields: []*data.Field{
|
||||||
|
data.NewField("time", nil, []time.Time{time.Unix(5, 0)}),
|
||||||
|
data.NewField("value", nil, []*float64{float64Pointer(5)}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "[]*string, []*time frame should convert",
|
||||||
|
frame: &data.Frame{
|
||||||
|
Name: "test",
|
||||||
|
Fields: []*data.Field{
|
||||||
|
data.NewField("time", nil, []*time.Time{unixTimePointer(5, 0)}),
|
||||||
|
data.NewField("value", nil, []*string{strPointer("5")}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errIs: assert.NoError,
|
||||||
|
Is: assert.Equal,
|
||||||
|
Series: Series{
|
||||||
|
Frame: &data.Frame{
|
||||||
|
Name: "test",
|
||||||
|
Fields: []*data.Field{
|
||||||
|
data.NewField("time", nil, []time.Time{time.Unix(5, 0)}),
|
||||||
|
data.NewField("value", nil, []*float64{float64Pointer(5)}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "[]bool, []*time frame should convert",
|
||||||
|
frame: &data.Frame{
|
||||||
|
Name: "test",
|
||||||
|
Fields: []*data.Field{
|
||||||
|
data.NewField("time", nil, []*time.Time{unixTimePointer(5, 0)}),
|
||||||
|
data.NewField("value", nil, []bool{true}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errIs: assert.NoError,
|
||||||
|
Is: assert.Equal,
|
||||||
|
Series: Series{
|
||||||
|
Frame: &data.Frame{
|
||||||
|
Name: "test",
|
||||||
|
Fields: []*data.Field{
|
||||||
|
data.NewField("time", nil, []time.Time{time.Unix(5, 0)}),
|
||||||
|
data.NewField("value", nil, []*float64{float64Pointer(1)}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "[]*bool, []*time frame should convert",
|
||||||
|
frame: &data.Frame{
|
||||||
|
Name: "test",
|
||||||
|
Fields: []*data.Field{
|
||||||
|
data.NewField("time", nil, []*time.Time{unixTimePointer(5, 0)}),
|
||||||
|
data.NewField("value", nil, []*bool{boolPointer(true)}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errIs: assert.NoError,
|
||||||
|
Is: assert.Equal,
|
||||||
|
Series: Series{
|
||||||
|
Frame: &data.Frame{
|
||||||
|
Name: "test",
|
||||||
|
Fields: []*data.Field{
|
||||||
|
data.NewField("time", nil, []time.Time{time.Unix(5, 0)}),
|
||||||
|
data.NewField("value", nil, []*float64{float64Pointer(1)}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "[]*time, []*time frame should error",
|
name: "[]*time, []*time frame should error",
|
||||||
frame: &data.Frame{
|
frame: &data.Frame{
|
||||||
|
Loading…
Reference in New Issue
Block a user