mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
add __timeGroup macro for mysql (#9596)
* add __timeGroup macro for mysql * put example __timeGroup query in frontend help * do __timeGroup interval parsing in go similar to mysql * ignore whitespace around interval
This commit is contained in:
parent
6aa0f35012
commit
34da0711ab
@ -3,6 +3,8 @@ package mysql
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/tsdb"
|
"github.com/grafana/grafana/pkg/tsdb"
|
||||||
)
|
)
|
||||||
@ -25,7 +27,7 @@ func (m *MySqlMacroEngine) Interpolate(timeRange *tsdb.TimeRange, sql string) (s
|
|||||||
var macroError error
|
var macroError error
|
||||||
|
|
||||||
sql = replaceAllStringSubmatchFunc(rExp, sql, func(groups []string) string {
|
sql = replaceAllStringSubmatchFunc(rExp, sql, func(groups []string) string {
|
||||||
res, err := m.evaluateMacro(groups[1], groups[2:])
|
res, err := m.evaluateMacro(groups[1], strings.Split(groups[2], ","))
|
||||||
if err != nil && macroError == nil {
|
if err != nil && macroError == nil {
|
||||||
macroError = err
|
macroError = err
|
||||||
return "macro_error()"
|
return "macro_error()"
|
||||||
@ -73,6 +75,15 @@ func (m *MySqlMacroEngine) evaluateMacro(name string, args []string) (string, er
|
|||||||
return fmt.Sprintf("FROM_UNIXTIME(%d)", uint64(m.TimeRange.GetFromAsMsEpoch()/1000)), nil
|
return fmt.Sprintf("FROM_UNIXTIME(%d)", uint64(m.TimeRange.GetFromAsMsEpoch()/1000)), nil
|
||||||
case "__timeTo":
|
case "__timeTo":
|
||||||
return fmt.Sprintf("FROM_UNIXTIME(%d)", uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil
|
return fmt.Sprintf("FROM_UNIXTIME(%d)", uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil
|
||||||
|
case "__timeGroup":
|
||||||
|
if len(args) != 2 {
|
||||||
|
return "", fmt.Errorf("macro %v needs time column and interval", name)
|
||||||
|
}
|
||||||
|
interval, err := time.ParseDuration(strings.Trim(args[1], `'" `))
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error parsing interval %v", args[1])
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("cast(cast(UNIX_TIMESTAMP(%s)/(%.0f) as signed)*%.0f as signed)", args[0], interval.Seconds(), interval.Seconds()), nil
|
||||||
case "__unixEpochFilter":
|
case "__unixEpochFilter":
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return "", fmt.Errorf("missing time column argument for macro %v", name)
|
return "", fmt.Errorf("missing time column argument for macro %v", name)
|
||||||
|
@ -40,6 +40,14 @@ func TestMacroEngine(t *testing.T) {
|
|||||||
So(sql, ShouldEqual, "select FROM_UNIXTIME(18446744066914186738)")
|
So(sql, ShouldEqual, "select FROM_UNIXTIME(18446744066914186738)")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Convey("interpolate __timeGroup function", func() {
|
||||||
|
|
||||||
|
sql, err := engine.Interpolate(timeRange, "GROUP BY $__timeGroup(time_column,'5m')")
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
So(sql, ShouldEqual, "GROUP BY cast(cast(UNIX_TIMESTAMP(time_column)/(300) as signed)*300 as signed)")
|
||||||
|
})
|
||||||
|
|
||||||
Convey("interpolate __timeTo function", func() {
|
Convey("interpolate __timeTo function", func() {
|
||||||
sql, err := engine.Interpolate(timeRange, "select $__timeTo(time_column)")
|
sql, err := engine.Interpolate(timeRange, "select $__timeTo(time_column)")
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/tsdb"
|
"github.com/grafana/grafana/pkg/tsdb"
|
||||||
)
|
)
|
||||||
@ -80,10 +81,14 @@ func (m *PostgresMacroEngine) evaluateMacro(name string, args []string) (string,
|
|||||||
case "__timeTo":
|
case "__timeTo":
|
||||||
return fmt.Sprintf("to_timestamp(%d)", uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil
|
return fmt.Sprintf("to_timestamp(%d)", uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil
|
||||||
case "__timeGroup":
|
case "__timeGroup":
|
||||||
if len(args) < 2 {
|
if len(args) != 2 {
|
||||||
return "", fmt.Errorf("macro %v needs time column and interval", name)
|
return "", fmt.Errorf("macro %v needs time column and interval", name)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("(extract(epoch from \"%s\")/extract(epoch from %s::interval))::int*extract(epoch from %s::interval)", args[0], args[1], args[1]), nil
|
interval, err := time.ParseDuration(strings.Trim(args[1], `' `))
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error parsing interval %v", args[1])
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("(extract(epoch from \"%s\")/%v)::bigint*%v", args[0], interval.Seconds(), interval.Seconds()), nil
|
||||||
case "__unixEpochFilter":
|
case "__unixEpochFilter":
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return "", fmt.Errorf("missing time column argument for macro %v", name)
|
return "", fmt.Errorf("missing time column argument for macro %v", name)
|
||||||
|
@ -45,7 +45,7 @@ func TestMacroEngine(t *testing.T) {
|
|||||||
sql, err := engine.Interpolate(timeRange, "GROUP BY $__timeGroup(time_column,'5m')")
|
sql, err := engine.Interpolate(timeRange, "GROUP BY $__timeGroup(time_column,'5m')")
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
So(sql, ShouldEqual, "GROUP BY (extract(epoch from \"time_column\")/extract(epoch from '5m'::interval))::int*extract(epoch from '5m'::interval)")
|
So(sql, ShouldEqual, "GROUP BY (extract(epoch from \"time_column\")/300)::bigint*300")
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("interpolate __timeTo function", func() {
|
Convey("interpolate __timeTo function", func() {
|
||||||
|
@ -49,7 +49,15 @@ Macros:
|
|||||||
- $__time(column) -> UNIX_TIMESTAMP(column) as time_sec
|
- $__time(column) -> UNIX_TIMESTAMP(column) as time_sec
|
||||||
- $__timeFilter(column) -> UNIX_TIMESTAMP(time_date_time) ≥ 1492750877 AND UNIX_TIMESTAMP(time_date_time) ≤ 1492750877
|
- $__timeFilter(column) -> UNIX_TIMESTAMP(time_date_time) ≥ 1492750877 AND UNIX_TIMESTAMP(time_date_time) ≤ 1492750877
|
||||||
- $__unixEpochFilter(column) -> time_unix_epoch > 1492750877 AND time_unix_epoch < 1492750877
|
- $__unixEpochFilter(column) -> time_unix_epoch > 1492750877 AND time_unix_epoch < 1492750877
|
||||||
- $__timeGroup(column,'5m') -> (extract(epoch from "dateColumn")/extract(epoch from '5m'::interval))::int
|
- $__timeGroup(column,'5m') -> cast(cast(UNIX_TIMESTAMP(column)/(300) as signed)*300 as signed)
|
||||||
|
|
||||||
|
Example of group by and order by with $__timeGroup:
|
||||||
|
SELECT
|
||||||
|
$__timeGroup(timestamp_col, '1h') AS time,
|
||||||
|
sum(value_double) as value
|
||||||
|
FROM yourtable
|
||||||
|
GROUP BY 1
|
||||||
|
ORDER BY 1
|
||||||
|
|
||||||
Or build your own conditionals using these macros which just return the values:
|
Or build your own conditionals using these macros which just return the values:
|
||||||
- $__timeFrom() -> FROM_UNIXTIME(1492750877)
|
- $__timeFrom() -> FROM_UNIXTIME(1492750877)
|
||||||
|
@ -50,17 +50,15 @@ Macros:
|
|||||||
- $__timeEpoch -> extract(epoch from column) as "time"
|
- $__timeEpoch -> extract(epoch from column) as "time"
|
||||||
- $__timeFilter(column) -> column ≥ to_timestamp(1492750877) AND column ≤ to_timestamp(1492750877)
|
- $__timeFilter(column) -> column ≥ to_timestamp(1492750877) AND column ≤ to_timestamp(1492750877)
|
||||||
- $__unixEpochFilter(column) -> column > 1492750877 AND column < 1492750877
|
- $__unixEpochFilter(column) -> column > 1492750877 AND column < 1492750877
|
||||||
|
- $__timeGroup(column,'5m') -> (extract(epoch from "dateColumn")/extract(epoch from '5m'::interval))::int
|
||||||
To group by time use $__timeGroup:
|
|
||||||
-> (extract(epoch from column)/extract(epoch from column::interval))::int
|
|
||||||
|
|
||||||
Example of group by and order by with $__timeGroup:
|
Example of group by and order by with $__timeGroup:
|
||||||
SELECT
|
SELECT
|
||||||
min(date_time_col) AS time_sec,
|
$__timeGroup(date_time_col, '1h') AS time,
|
||||||
sum(value_double) as value
|
sum(value) as value
|
||||||
FROM yourtable
|
FROM yourtable
|
||||||
group by $__timeGroup(date_time_col, '1h')
|
GROUP BY time
|
||||||
order by $__timeGroup(date_time_col, '1h') ASC
|
ORDER BY time
|
||||||
|
|
||||||
Or build your own conditionals using these macros which just return the values:
|
Or build your own conditionals using these macros which just return the values:
|
||||||
- $__timeFrom() -> to_timestamp(1492750877)
|
- $__timeFrom() -> to_timestamp(1492750877)
|
||||||
|
Loading…
Reference in New Issue
Block a user