diff --git a/docs/sources/features/datasources/mssql.md b/docs/sources/features/datasources/mssql.md index cd191f14273a..5bab14c05fa1 100644 --- a/docs/sources/features/datasources/mssql.md +++ b/docs/sources/features/datasources/mssql.md @@ -110,6 +110,9 @@ 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* +*$__unixEpochNanoFilter(dateColumn)* | Will be replaced by a time range filter using the specified column name with times represented as nanosecond timestamp. For example, *dateColumn > 1494410783152415214 AND dateColumn < 1494497183142514872* +*$__unixEpochNanoFrom()* | Will be replaced by the start of the currently active time selection as nanosecond timestamp. For example, *1494410783152415214* +*$__unixEpochNanoTo()* | Will be replaced by the end of the currently active time selection as nanosecond timestamp. For example, *1494497183142514872* *$__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+). diff --git a/docs/sources/features/datasources/mysql.md b/docs/sources/features/datasources/mysql.md index 371c92cde707..bafe79bd09ab 100644 --- a/docs/sources/features/datasources/mysql.md +++ b/docs/sources/features/datasources/mysql.md @@ -144,6 +144,9 @@ 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* +*$__unixEpochNanoFilter(dateColumn)* | Will be replaced by a time range filter using the specified column name with times represented as nanosecond timestamp. For example, *dateColumn > 1494410783152415214 AND dateColumn < 1494497183142514872* +*$__unixEpochNanoFrom()* | Will be replaced by the start of the currently active time selection as nanosecond timestamp. For example, *1494410783152415214* +*$__unixEpochNanoTo()* | Will be replaced by the end of the currently active time selection as nanosecond timestamp. For example, *1494497183142514872* *$__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+). diff --git a/docs/sources/features/datasources/postgres.md b/docs/sources/features/datasources/postgres.md index 52f8804f27fa..df6bf5550777 100644 --- a/docs/sources/features/datasources/postgres.md +++ b/docs/sources/features/datasources/postgres.md @@ -154,6 +154,9 @@ Macro example | Description *$__unixEpochFilter(dateColumn)* | Will be replaced by a time range filter using the specified column name with times represented as unix timestamps. 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* +*$__unixEpochNanoFilter(dateColumn)* | Will be replaced by a time range filter using the specified column name with times represented as nanosecond timestamps. For example, *dateColumn >= 1494410783152415214 AND dateColumn <= 1494497183142514872* +*$__unixEpochNanoFrom()* | Will be replaced by the start of the currently active time selection as nanosecond timestamp. For example, *1494410783152415214* +*$__unixEpochNanoTo()* | Will be replaced by the end of the currently active time selection as unix timestamp. For example, *1494497183142514872* *$__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+). diff --git a/pkg/tsdb/mssql/macros.go b/pkg/tsdb/mssql/macros.go index dac18f3ac037..ec3f103a4ef2 100644 --- a/pkg/tsdb/mssql/macros.go +++ b/pkg/tsdb/mssql/macros.go @@ -96,6 +96,15 @@ func (m *msSqlMacroEngine) evaluateMacro(name string, args []string) (string, er return "", fmt.Errorf("missing time column argument for macro %v", name) } return fmt.Sprintf("%s >= %d AND %s <= %d", args[0], m.timeRange.GetFromAsSecondsEpoch(), args[0], m.timeRange.GetToAsSecondsEpoch()), nil + case "__unixEpochNanoFilter": + if len(args) == 0 { + return "", fmt.Errorf("missing time column argument for macro %v", name) + } + return fmt.Sprintf("%s >= %d AND %s <= %d", args[0], m.timeRange.GetFromAsTimeUTC().UnixNano(), args[0], m.timeRange.GetToAsTimeUTC().UnixNano()), nil + case "__unixEpochNanoFrom": + return fmt.Sprintf("%d", m.timeRange.GetFromAsTimeUTC().UnixNano()), nil + case "__unixEpochNanoTo": + return fmt.Sprintf("%d", m.timeRange.GetToAsTimeUTC().UnixNano()), nil case "__unixEpochGroup": if len(args) < 2 { return "", fmt.Errorf("macro %v needs time column and interval and optional fill value", name) diff --git a/pkg/tsdb/mssql/macros_test.go b/pkg/tsdb/mssql/macros_test.go index 43cbe9fefda3..829a8b1ff1a8 100644 --- a/pkg/tsdb/mssql/macros_test.go +++ b/pkg/tsdb/mssql/macros_test.go @@ -132,6 +132,26 @@ func TestMacroEngine(t *testing.T) { So(sql, ShouldEqual, fmt.Sprintf("select time_column >= %d AND time_column <= %d", from.Unix(), to.Unix())) }) + Convey("interpolate __unixEpochNanoFilter function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoFilter(time_column)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select time_column >= %d AND time_column <= %d", from.UnixNano(), to.UnixNano())) + }) + Convey("interpolate __unixEpochNanoFrom function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoFrom()") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select %d", from.UnixNano())) + }) + + Convey("interpolate __unixEpochNanoTo function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoTo()") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select %d", to.UnixNano())) + }) + Convey("interpolate __unixEpochGroup function", func() { sql, err := engine.Interpolate(query, timeRange, "SELECT $__unixEpochGroup(time_column,'5m')") @@ -163,6 +183,13 @@ func TestMacroEngine(t *testing.T) { So(sql, ShouldEqual, fmt.Sprintf("select time_column >= %d AND time_column <= %d", from.Unix(), to.Unix())) }) + + Convey("interpolate __unixEpochNanoFilter function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoFilter(time_column)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select time_column >= %d AND time_column <= %d", from.UnixNano(), to.UnixNano())) + }) }) Convey("Given a time range between 1960-02-01 07:00 and 1980-02-03 08:00", func() { @@ -183,6 +210,13 @@ func TestMacroEngine(t *testing.T) { So(sql, ShouldEqual, fmt.Sprintf("select time_column >= %d AND time_column <= %d", from.Unix(), to.Unix())) }) + + Convey("interpolate __unixEpochNanoFilter function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoFilter(time_column)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select time_column >= %d AND time_column <= %d", from.UnixNano(), to.UnixNano())) + }) }) }) } diff --git a/pkg/tsdb/mysql/macros.go b/pkg/tsdb/mysql/macros.go index c0ed64aa65c2..bbd928b05631 100644 --- a/pkg/tsdb/mysql/macros.go +++ b/pkg/tsdb/mysql/macros.go @@ -91,6 +91,15 @@ func (m *mySqlMacroEngine) evaluateMacro(name string, args []string) (string, er return "", fmt.Errorf("missing time column argument for macro %v", name) } return fmt.Sprintf("%s >= %d AND %s <= %d", args[0], m.timeRange.GetFromAsSecondsEpoch(), args[0], m.timeRange.GetToAsSecondsEpoch()), nil + case "__unixEpochNanoFilter": + if len(args) == 0 { + return "", fmt.Errorf("missing time column argument for macro %v", name) + } + return fmt.Sprintf("%s >= %d AND %s <= %d", args[0], m.timeRange.GetFromAsTimeUTC().UnixNano(), args[0], m.timeRange.GetToAsTimeUTC().UnixNano()), nil + case "__unixEpochNanoFrom": + return fmt.Sprintf("%d", m.timeRange.GetFromAsTimeUTC().UnixNano()), nil + case "__unixEpochNanoTo": + return fmt.Sprintf("%d", m.timeRange.GetToAsTimeUTC().UnixNano()), nil case "__unixEpochGroup": if len(args) < 2 { return "", fmt.Errorf("macro %v needs time column and interval and optional fill value", name) diff --git a/pkg/tsdb/mysql/macros_test.go b/pkg/tsdb/mysql/macros_test.go index 49633347a4c9..7d129e845b13 100644 --- a/pkg/tsdb/mysql/macros_test.go +++ b/pkg/tsdb/mysql/macros_test.go @@ -84,6 +84,27 @@ func TestMacroEngine(t *testing.T) { So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.Unix(), to.Unix())) }) + Convey("interpolate __unixEpochNanoFilter function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoFilter(time)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.UnixNano(), to.UnixNano())) + }) + + Convey("interpolate __unixEpochNanoFrom function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoFrom()") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select %d", from.UnixNano())) + }) + + Convey("interpolate __unixEpochNanoTo function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoTo()") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select %d", to.UnixNano())) + }) + Convey("interpolate __unixEpochGroup function", func() { sql, err := engine.Interpolate(query, timeRange, "SELECT $__unixEpochGroup(time_column,'5m')") diff --git a/pkg/tsdb/postgres/macros.go b/pkg/tsdb/postgres/macros.go index 0b3685c26104..fbba582c2629 100644 --- a/pkg/tsdb/postgres/macros.go +++ b/pkg/tsdb/postgres/macros.go @@ -122,6 +122,15 @@ func (m *postgresMacroEngine) evaluateMacro(name string, args []string) (string, return "", fmt.Errorf("missing time column argument for macro %v", name) } return fmt.Sprintf("%s >= %d AND %s <= %d", args[0], m.timeRange.GetFromAsSecondsEpoch(), args[0], m.timeRange.GetToAsSecondsEpoch()), nil + case "__unixEpochNanoFilter": + if len(args) == 0 { + return "", fmt.Errorf("missing time column argument for macro %v", name) + } + return fmt.Sprintf("%s >= %d AND %s <= %d", args[0], m.timeRange.GetFromAsTimeUTC().UnixNano(), args[0], m.timeRange.GetToAsTimeUTC().UnixNano()), nil + case "__unixEpochNanoFrom": + return fmt.Sprintf("%d", m.timeRange.GetFromAsTimeUTC().UnixNano()), nil + case "__unixEpochNanoTo": + return fmt.Sprintf("%d", m.timeRange.GetToAsTimeUTC().UnixNano()), nil case "__unixEpochGroup": if len(args) < 2 { return "", fmt.Errorf("macro %v needs time column and interval and optional fill value", name) diff --git a/pkg/tsdb/postgres/macros_test.go b/pkg/tsdb/postgres/macros_test.go index 90f6c6d879af..eb14656c5468 100644 --- a/pkg/tsdb/postgres/macros_test.go +++ b/pkg/tsdb/postgres/macros_test.go @@ -115,6 +115,25 @@ func TestMacroEngine(t *testing.T) { So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.Unix(), to.Unix())) }) + Convey("interpolate __unixEpochNanoFilter function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoFilter(time)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.UnixNano(), to.UnixNano())) + }) + Convey("interpolate __unixEpochNanoFrom function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoFrom()") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select %d", from.UnixNano())) + }) + + Convey("interpolate __unixEpochNanoTo function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoTo()") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select %d", to.UnixNano())) + }) Convey("interpolate __unixEpochGroup function", func() { @@ -147,6 +166,12 @@ func TestMacroEngine(t *testing.T) { So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.Unix(), to.Unix())) }) + Convey("interpolate __unixEpochNanoFilter function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoFilter(time)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.UnixNano(), to.UnixNano())) + }) }) Convey("Given a time range between 1960-02-01 07:00 and 1980-02-03 08:00", func() { @@ -167,6 +192,12 @@ func TestMacroEngine(t *testing.T) { So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.Unix(), to.Unix())) }) + Convey("interpolate __unixEpochNanoFilter function", func() { + sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochNanoFilter(time)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.UnixNano(), to.UnixNano())) + }) }) Convey("Given a time range between 1960-02-01 07:00:00.5 and 1980-02-03 08:00:00.5", func() { diff --git a/public/app/plugins/datasource/mssql/partials/annotations.editor.html b/public/app/plugins/datasource/mssql/partials/annotations.editor.html index 0ad8b0c01f0d..f1c549cefa46 100644 --- a/public/app/plugins/datasource/mssql/partials/annotations.editor.html +++ b/public/app/plugins/datasource/mssql/partials/annotations.editor.html @@ -30,12 +30,15 @@ Macros: - $__timeEpoch(column) -> DATEDIFF(second, '1970-01-01', column) AS time - $__timeFilter(column) -> column BETWEEN '2017-04-21T05:01:17Z' AND '2017-04-21T05:01:17Z' - $__unixEpochFilter(column) -> column >= 1492750877 AND column <= 1492750877 +- $__unixEpochNanoFilter(column) -> column >= 1494410783152415214 AND column <= 1494497183142514872 Or build your own conditionals using these macros which just return the values: - $__timeFrom() -> '2017-04-21T05:01:17Z' - $__timeTo() -> '2017-04-21T05:01:17Z' - $__unixEpochFrom() -> 1492750877 - $__unixEpochTo() -> 1492750877 +- $__unixEpochNanoFrom() -> 1494410783152415214 +- $__unixEpochNanoTo() -> 1494497183142514872 diff --git a/public/app/plugins/datasource/mssql/partials/query.editor.html b/public/app/plugins/datasource/mssql/partials/query.editor.html index ba3bb6a4b82d..f48af291216e 100644 --- a/public/app/plugins/datasource/mssql/partials/query.editor.html +++ b/public/app/plugins/datasource/mssql/partials/query.editor.html @@ -55,6 +55,7 @@ Macros: - $__timeEpoch(column) -> DATEDIFF(second, '1970-01-01', column) AS time - $__timeFilter(column) -> column BETWEEN '2017-04-21T05:01:17Z' AND '2017-04-21T05:01:17Z' - $__unixEpochFilter(column) -> column >= 1492750877 AND column <= 1492750877 +- $__unixEpochNanoFilter(column) -> column >= 1494410783152415214 AND column <= 1494497183142514872 - $__timeGroup(column, '5m'[, fillvalue]) -> CAST(ROUND(DATEDIFF(second, '1970-01-01', column)/300.0, 0) as bigint)*300. 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 @@ -75,6 +76,8 @@ Or build your own conditionals using these macros which just return the values: - $__timeTo() -> '2017-04-21T05:01:17Z' - $__unixEpochFrom() -> 1492750877 - $__unixEpochTo() -> 1492750877 +- $__unixEpochNanoFrom() -> 1494410783152415214 +- $__unixEpochNanoTo() -> 1494497183142514872 diff --git a/public/app/plugins/datasource/mysql/partials/annotations.editor.html b/public/app/plugins/datasource/mysql/partials/annotations.editor.html index 79f3c7828987..25d2f969ceef 100644 --- a/public/app/plugins/datasource/mysql/partials/annotations.editor.html +++ b/public/app/plugins/datasource/mysql/partials/annotations.editor.html @@ -30,12 +30,15 @@ Macros: - $__timeEpoch(column) -> UNIX_TIMESTAMP(column) as time (or as time_sec) - $__timeFilter(column) -> column BETWEEN FROM_UNIXTIME(1492750877) AND FROM_UNIXTIME(1492750877) - $__unixEpochFilter(column) -> time_unix_epoch > 1492750877 AND time_unix_epoch < 1492750877 +- $__unixEpochNanoFilter(column) -> column >= 1494410783152415214 AND column <= 1494497183142514872 Or build your own conditionals using these macros which just return the values: - $__timeFrom() -> FROM_UNIXTIME(1492750877) - $__timeTo() -> FROM_UNIXTIME(1492750877) - $__unixEpochFrom() -> 1492750877 - $__unixEpochTo() -> 1492750877 +- $__unixEpochNanoFrom() -> 1494410783152415214 +- $__unixEpochNanoTo() -> 1494497183142514872 diff --git a/public/app/plugins/datasource/mysql/partials/query.editor.html b/public/app/plugins/datasource/mysql/partials/query.editor.html index 90680ed104f7..0cb47061a9e9 100644 --- a/public/app/plugins/datasource/mysql/partials/query.editor.html +++ b/public/app/plugins/datasource/mysql/partials/query.editor.html @@ -153,6 +153,7 @@ Macros: - $__timeEpoch(column) -> UNIX_TIMESTAMP(column) as time_sec - $__timeFilter(column) -> column BETWEEN FROM_UNIXTIME(1492750877) AND FROM_UNIXTIME(1492750877) - $__unixEpochFilter(column) -> time_unix_epoch > 1492750877 AND time_unix_epoch < 1492750877 +- $__unixEpochNanoFilter(column) -> column >= 1494410783152415214 AND column <= 1494497183142514872 - $__timeGroup(column,'5m'[, fillvalue]) -> cast(cast(UNIX_TIMESTAMP(column)/(300) as signed)*300 as signed) 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 @@ -173,6 +174,8 @@ Or build your own conditionals using these macros which just return the values: - $__timeTo() -> FROM_UNIXTIME(1492750877) - $__unixEpochFrom() -> 1492750877 - $__unixEpochTo() -> 1492750877 +- $__unixEpochNanoFrom() -> 1494410783152415214 +- $__unixEpochNanoTo() -> 1494497183142514872 diff --git a/public/app/plugins/datasource/postgres/partials/annotations.editor.html b/public/app/plugins/datasource/postgres/partials/annotations.editor.html index b83f5a148329..0b7180c0eafe 100644 --- a/public/app/plugins/datasource/postgres/partials/annotations.editor.html +++ b/public/app/plugins/datasource/postgres/partials/annotations.editor.html @@ -30,12 +30,15 @@ Macros: - $__timeEpoch -> extract(epoch from column) as "time" - $__timeFilter(column) -> column BETWEEN '2017-04-21T05:01:17Z' AND '2017-04-21T05:01:17Z' - $__unixEpochFilter(column) -> column >= 1492750877 AND column <= 1492750877 +- $__unixEpochNanoFilter(column) -> column >= 1494410783152415214 AND column <= 1494497183142514872 Or build your own conditionals using these macros which just return the values: - $__timeFrom() -> '2017-04-21T05:01:17Z' - $__timeTo() -> '2017-04-21T05:01:17Z' - $__unixEpochFrom() -> 1492750877 - $__unixEpochTo() -> 1492750877 +- $__unixEpochNanoFrom() -> 1494410783152415214 +- $__unixEpochNanoTo() -> 1494497183142514872 diff --git a/public/app/plugins/datasource/postgres/partials/query.editor.html b/public/app/plugins/datasource/postgres/partials/query.editor.html index 5d866245aff6..b5e2b5d87ed0 100644 --- a/public/app/plugins/datasource/postgres/partials/query.editor.html +++ b/public/app/plugins/datasource/postgres/partials/query.editor.html @@ -153,6 +153,7 @@ Macros: - $__timeEpoch -> extract(epoch from column) as "time" - $__timeFilter(column) -> column BETWEEN '2017-04-21T05:01:17Z' AND '2017-04-21T05:01:17Z' - $__unixEpochFilter(column) -> column >= 1492750877 AND column <= 1492750877 +- $__unixEpochNanoFilter(column) -> column >= 1494410783152415214 AND column <= 1494497183142514872 - $__timeGroup(column,'5m'[, fillvalue]) -> (extract(epoch from column)/300)::bigint*300 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 @@ -173,6 +174,8 @@ Or build your own conditionals using these macros which just return the values: - $__timeTo() -> '2017-04-21T05:01:17Z' - $__unixEpochFrom() -> 1492750877 - $__unixEpochTo() -> 1492750877 +- $__unixEpochNanoFrom() -> 1494410783152415214 +- $__unixEpochNanoTo() -> 1494497183142514872