diff --git a/pkg/tsdb/influxdb/flux/executor.go b/pkg/tsdb/influxdb/flux/executor.go index 991e3fde6ad..79d6d68b589 100644 --- a/pkg/tsdb/influxdb/flux/executor.go +++ b/pkg/tsdb/influxdb/flux/executor.go @@ -18,11 +18,7 @@ const maxPointsEnforceFactor float64 = 10 func executeQuery(ctx context.Context, query queryModel, runner queryRunner, maxSeries int) (dr backend.DataResponse) { dr = backend.DataResponse{} - flux, err := interpolate(query) - if err != nil { - dr.Error = err - return - } + flux := interpolate(query) glog.Debug("Executing Flux query", "flux", flux) diff --git a/pkg/tsdb/influxdb/flux/macros.go b/pkg/tsdb/influxdb/flux/macros.go index 8962a5f6ac5..ed3a34d2d20 100644 --- a/pkg/tsdb/influxdb/flux/macros.go +++ b/pkg/tsdb/influxdb/flux/macros.go @@ -2,18 +2,32 @@ package flux import ( "regexp" + "strconv" "strings" "time" + + "github.com/grafana/grafana/pkg/tsdb/intervalv2" ) -const variableFilter = `(?m)([a-zA-Z]+)\.([a-zA-Z]+)` +// $__interval_ms is the exact value in milliseconds +// $__interval is rounded to nice whole values +// v.windowPeriod is the exact value string-formatted -// interpolate processes macros -func interpolate(query queryModel) (string, error) { +func interpolateInterval(flux string, interval time.Duration) string { + intervalMs := int64(interval / time.Millisecond) + intervalText := intervalv2.FormatDuration(interval) + + flux = strings.ReplaceAll(flux, "$__interval_ms", strconv.FormatInt(intervalMs, 10)) + flux = strings.ReplaceAll(flux, "$__interval", intervalText) + return flux +} + +var fluxVariableFilterExp = regexp.MustCompile(`(?m)([a-zA-Z]+)\.([a-zA-Z]+)`) + +func interpolateFluxSpecificVariables(query queryModel) string { flux := query.RawQuery - variableFilterExp, err := regexp.Compile(variableFilter) - matches := variableFilterExp.FindAllStringSubmatch(flux, -1) + matches := fluxVariableFilterExp.FindAllStringSubmatch(flux, -1) if matches != nil { timeRange := query.TimeRange from := timeRange.From.UTC().Format(time.RFC3339Nano) @@ -35,5 +49,11 @@ func interpolate(query queryModel) (string, error) { } } } - return flux, err + return flux +} + +func interpolate(query queryModel) string { + flux := interpolateFluxSpecificVariables(query) + flux = interpolateInterval(flux, query.Interval) + return flux } diff --git a/pkg/tsdb/influxdb/flux/macros_test.go b/pkg/tsdb/influxdb/flux/macros_test.go index c1f48102360..9bf0fa3570a 100644 --- a/pkg/tsdb/influxdb/flux/macros_test.go +++ b/pkg/tsdb/influxdb/flux/macros_test.go @@ -7,7 +7,6 @@ import ( "github.com/google/go-cmp/cmp" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestInterpolate(t *testing.T) { @@ -29,8 +28,8 @@ func TestInterpolate(t *testing.T) { }{ { name: "interpolate flux variables", - before: `v.timeRangeStart, something.timeRangeStop, XYZ.bucket, uuUUu.defaultBucket, aBcDefG.organization, window.windowPeriod, a91{}.bucket`, - after: `2021-09-22T10:12:51.310985041Z, 2021-09-22T11:12:51.310985042Z, "grafana2", "grafana3", "grafana1", 1s, a91{}.bucket`, + before: `v.timeRangeStart, something.timeRangeStop, XYZ.bucket, uuUUu.defaultBucket, aBcDefG.organization, window.windowPeriod, a91{}.bucket, $__interval, $__interval_ms`, + after: `2021-09-22T10:12:51.310985041Z, 2021-09-22T11:12:51.310985042Z, "grafana2", "grafana3", "grafana1", 1m1.258s, a91{}.bucket, 1m, 61258`, }, } for _, tt := range tests { @@ -40,10 +39,9 @@ func TestInterpolate(t *testing.T) { Options: options, TimeRange: timeRange, MaxDataPoints: 1, - Interval: 1000 * 1000 * 1000, + Interval: 61258 * 1000 * 1000, } - interpolatedQuery, err := interpolate(query) - require.NoError(t, err) + interpolatedQuery := interpolate(query) diff := cmp.Diff(tt.after, interpolatedQuery) assert.Equal(t, "", diff) }) diff --git a/public/app/plugins/datasource/influxdb/datasource.ts b/public/app/plugins/datasource/influxdb/datasource.ts index ce1e95f6a22..5bd878ac911 100644 --- a/public/app/plugins/datasource/influxdb/datasource.ts +++ b/public/app/plugins/datasource/influxdb/datasource.ts @@ -188,9 +188,12 @@ export default class InfluxDatasource extends DataSourceWithBackend