From bfe28ee061ea42b27057c582f0b436cf12c46e88 Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Mon, 13 Aug 2018 12:08:14 +0200 Subject: [PATCH] Add $__unixEpochGroup macro to postgres datasource --- docs/sources/features/datasources/postgres.md | 2 ++ pkg/tsdb/postgres/macros.go | 21 +++++++++++++++++++ pkg/tsdb/postgres/macros_test.go | 12 +++++++++++ .../postgres/partials/query.editor.html | 2 ++ 4 files changed, 37 insertions(+) diff --git a/docs/sources/features/datasources/postgres.md b/docs/sources/features/datasources/postgres.md index 2be2db0837b..cf77643f06b 100644 --- a/docs/sources/features/datasources/postgres.md +++ b/docs/sources/features/datasources/postgres.md @@ -68,6 +68,8 @@ Macro example | Description *$__unixEpochFilter(dateColumn)* | Will be replaced by a time range filter using the specified column name with times represented as unix timestamp. For example, *dateColumn >= 1494410783 AND dateColumn <= 1494497183* *$__unixEpochFrom()* | Will be replaced by the start of the currently active time selection as unix timestamp. For example, *1494410783* *$__unixEpochTo()* | Will be replaced by the end of the currently active time selection as unix timestamp. For example, *1494497183* +*$__unixEpochGroup(dateColumn,'5m', [fillmode])* | Same as $__timeGroup but for times stored as unix timestamp (only available in Grafana 5.3+). +*$__unixEpochGroupAlias(dateColumn,'5m', [fillmode])* | Same as above but also adds a column alias (only available in Grafana 5.3+). We plan to add many more macros. If you have suggestions for what macros you would like to see, please [open an issue](https://github.com/grafana/grafana) in our GitHub repo. diff --git a/pkg/tsdb/postgres/macros.go b/pkg/tsdb/postgres/macros.go index a4b4aaa9d1e..d2a3d599441 100644 --- a/pkg/tsdb/postgres/macros.go +++ b/pkg/tsdb/postgres/macros.go @@ -134,6 +134,27 @@ func (m *postgresMacroEngine) evaluateMacro(name string, args []string) (string, return fmt.Sprintf("%d", m.timeRange.GetFromAsSecondsEpoch()), nil case "__unixEpochTo": return fmt.Sprintf("%d", m.timeRange.GetToAsSecondsEpoch()), nil + case "__unixEpochGroup": + if len(args) < 2 { + return "", fmt.Errorf("macro %v needs time column and interval and optional fill value", name) + } + interval, err := time.ParseDuration(strings.Trim(args[1], `'`)) + if err != nil { + return "", fmt.Errorf("error parsing interval %v", args[1]) + } + if len(args) == 3 { + err := tsdb.SetupFillmode(m.query, interval, args[2]) + if err != nil { + return "", err + } + } + return fmt.Sprintf("floor(%s/%v)*%v", args[0], interval.Seconds(), interval.Seconds()), nil + case "__unixEpochGroupAlias": + tg, err := m.evaluateMacro("__unixEpochGroup", args) + if err == nil { + return tg + " AS \"time\"", err + } + return "", err default: return "", fmt.Errorf("Unknown macro %v", name) } diff --git a/pkg/tsdb/postgres/macros_test.go b/pkg/tsdb/postgres/macros_test.go index beeea93893b..a029fc49ee0 100644 --- a/pkg/tsdb/postgres/macros_test.go +++ b/pkg/tsdb/postgres/macros_test.go @@ -110,6 +110,18 @@ func TestMacroEngine(t *testing.T) { So(sql, ShouldEqual, fmt.Sprintf("select %d", to.Unix())) }) + + Convey("interpolate __unixEpochGroup function", func() { + + sql, err := engine.Interpolate(query, timeRange, "SELECT $__unixEpochGroup(time_column,'5m')") + So(err, ShouldBeNil) + sql2, err := engine.Interpolate(query, timeRange, "SELECT $__unixEpochGroupAlias(time_column,'5m')") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, "SELECT floor(time_column/300)*300") + So(sql2, ShouldEqual, sql+" AS \"time\"") + }) + }) Convey("Given a time range between 1960-02-01 07:00 and 1965-02-03 08:00", func() { diff --git a/public/app/plugins/datasource/postgres/partials/query.editor.html b/public/app/plugins/datasource/postgres/partials/query.editor.html index 20353b81ba2..763fd6a6e96 100644 --- a/public/app/plugins/datasource/postgres/partials/query.editor.html +++ b/public/app/plugins/datasource/postgres/partials/query.editor.html @@ -57,6 +57,8 @@ Macros: by setting fillvalue grafana will fill in missing values according to the interval fillvalue can be either a literal value, NULL or previous; previous will fill in the previous seen value or NULL if none has been seen yet - $__timeGroupAlias(column,'5m') -> (extract(epoch from column)/300)::bigint*300 AS "time" +- $__unixEpochGroup(column,'5m') -> floor(column/300)*300 +- $__unixEpochGroupAlias(column,'5m') -> floor(column/300)*300 AS "time" Example of group by and order by with $__timeGroup: SELECT