Merge pull request #12760 from svenklemm/postgres-timegroup
remove alias from postgres $__timeGroup macro add $__timeGroupAlias macro to all sql datasources
This commit is contained in:
@@ -110,6 +110,12 @@ func (m *msSqlMacroEngine) evaluateMacro(name string, args []string) (string, er
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("FLOOR(DATEDIFF(second, '1970-01-01', %s)/%.0f)*%.0f", args[0], interval.Seconds(), interval.Seconds()), nil
|
||||
case "__timeGroupAlias":
|
||||
tg, err := m.evaluateMacro("__timeGroup", args)
|
||||
if err == nil {
|
||||
return tg + " AS [time]", err
|
||||
}
|
||||
return "", err
|
||||
case "__unixEpochFilter":
|
||||
if len(args) == 0 {
|
||||
return "", fmt.Errorf("missing time column argument for macro %v", name)
|
||||
|
||||
@@ -55,15 +55,21 @@ func TestMacroEngine(t *testing.T) {
|
||||
Convey("interpolate __timeGroup function", func() {
|
||||
sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column,'5m')")
|
||||
So(err, ShouldBeNil)
|
||||
sql2, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroupAlias(time_column,'5m')")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(sql, ShouldEqual, "GROUP BY FLOOR(DATEDIFF(second, '1970-01-01', time_column)/300)*300")
|
||||
So(sql2, ShouldEqual, sql+" AS [time]")
|
||||
})
|
||||
|
||||
Convey("interpolate __timeGroup function with spaces around arguments", func() {
|
||||
sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column , '5m')")
|
||||
So(err, ShouldBeNil)
|
||||
sql2, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroupAlias(time_column , '5m')")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(sql, ShouldEqual, "GROUP BY FLOOR(DATEDIFF(second, '1970-01-01', time_column)/300)*300")
|
||||
So(sql2, ShouldEqual, sql+" AS [time]")
|
||||
})
|
||||
|
||||
Convey("interpolate __timeGroup function with fill (value = NULL)", func() {
|
||||
|
||||
@@ -105,6 +105,12 @@ func (m *mySqlMacroEngine) evaluateMacro(name string, args []string) (string, er
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("UNIX_TIMESTAMP(%s) DIV %.0f * %.0f", args[0], interval.Seconds(), interval.Seconds()), nil
|
||||
case "__timeGroupAlias":
|
||||
tg, err := m.evaluateMacro("__timeGroup", args)
|
||||
if err == nil {
|
||||
return tg + " AS \"time\"", err
|
||||
}
|
||||
return "", err
|
||||
case "__unixEpochFilter":
|
||||
if len(args) == 0 {
|
||||
return "", fmt.Errorf("missing time column argument for macro %v", name)
|
||||
|
||||
@@ -38,16 +38,22 @@ func TestMacroEngine(t *testing.T) {
|
||||
|
||||
sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column,'5m')")
|
||||
So(err, ShouldBeNil)
|
||||
sql2, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroupAlias(time_column,'5m')")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(sql, ShouldEqual, "GROUP BY UNIX_TIMESTAMP(time_column) DIV 300 * 300")
|
||||
So(sql2, ShouldEqual, sql+" AS \"time\"")
|
||||
})
|
||||
|
||||
Convey("interpolate __timeGroup function with spaces around arguments", func() {
|
||||
|
||||
sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column , '5m')")
|
||||
So(err, ShouldBeNil)
|
||||
sql2, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroupAlias(time_column , '5m')")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(sql, ShouldEqual, "GROUP BY UNIX_TIMESTAMP(time_column) DIV 300 * 300")
|
||||
So(sql2, ShouldEqual, sql+" AS \"time\"")
|
||||
})
|
||||
|
||||
Convey("interpolate __timeFilter function", func() {
|
||||
|
||||
@@ -30,6 +30,23 @@ func (m *postgresMacroEngine) Interpolate(query *tsdb.Query, timeRange *tsdb.Tim
|
||||
var macroError error
|
||||
|
||||
sql = replaceAllStringSubmatchFunc(rExp, sql, func(groups []string) string {
|
||||
|
||||
// detect if $__timeGroup is supposed to add AS time for pre 5.3 compatibility
|
||||
// if there is a ',' directly after the macro call $__timeGroup is probably used
|
||||
// in the old way. Inside window function ORDER BY $__timeGroup will be followed
|
||||
// by ')'
|
||||
if groups[1] == "__timeGroup" {
|
||||
if index := strings.Index(sql, groups[0]); index >= 0 {
|
||||
index += len(groups[0])
|
||||
if len(sql) > index {
|
||||
// check for character after macro expression
|
||||
if sql[index] == ',' {
|
||||
groups[1] = "__timeGroupAlias"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
args := strings.Split(groups[2], ",")
|
||||
for i, arg := range args {
|
||||
args[i] = strings.Trim(arg, " ")
|
||||
@@ -109,7 +126,13 @@ func (m *postgresMacroEngine) evaluateMacro(name string, args []string) (string,
|
||||
m.query.Model.Set("fillValue", floatVal)
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("floor(extract(epoch from %s)/%v)*%v AS time", args[0], interval.Seconds(), interval.Seconds()), nil
|
||||
return fmt.Sprintf("floor(extract(epoch from %s)/%v)*%v", args[0], interval.Seconds(), interval.Seconds()), nil
|
||||
case "__timeGroupAlias":
|
||||
tg, err := m.evaluateMacro("__timeGroup", args)
|
||||
if err == nil {
|
||||
return tg + " AS \"time\"", err
|
||||
}
|
||||
return "", err
|
||||
case "__unixEpochFilter":
|
||||
if len(args) == 0 {
|
||||
return "", fmt.Errorf("missing time column argument for macro %v", name)
|
||||
|
||||
@@ -48,20 +48,39 @@ func TestMacroEngine(t *testing.T) {
|
||||
So(sql, ShouldEqual, fmt.Sprintf("select '%s'", from.Format(time.RFC3339)))
|
||||
})
|
||||
|
||||
Convey("interpolate __timeGroup function", func() {
|
||||
Convey("interpolate __timeGroup function pre 5.3 compatibility", func() {
|
||||
|
||||
sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column,'5m')")
|
||||
sql, err := engine.Interpolate(query, timeRange, "SELECT $__timeGroup(time_column,'5m'), value")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(sql, ShouldEqual, "GROUP BY floor(extract(epoch from time_column)/300)*300 AS time")
|
||||
So(sql, ShouldEqual, "SELECT floor(extract(epoch from time_column)/300)*300 AS \"time\", value")
|
||||
|
||||
sql, err = engine.Interpolate(query, timeRange, "SELECT $__timeGroup(time_column,'5m') as time, value")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(sql, ShouldEqual, "SELECT floor(extract(epoch from time_column)/300)*300 as time, value")
|
||||
})
|
||||
|
||||
Convey("interpolate __timeGroup function", func() {
|
||||
|
||||
sql, err := engine.Interpolate(query, timeRange, "SELECT $__timeGroup(time_column,'5m')")
|
||||
So(err, ShouldBeNil)
|
||||
sql2, err := engine.Interpolate(query, timeRange, "SELECT $__timeGroupAlias(time_column,'5m')")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(sql, ShouldEqual, "SELECT floor(extract(epoch from time_column)/300)*300")
|
||||
So(sql2, ShouldEqual, sql+" AS \"time\"")
|
||||
})
|
||||
|
||||
Convey("interpolate __timeGroup function with spaces between args", func() {
|
||||
|
||||
sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column , '5m')")
|
||||
sql, err := engine.Interpolate(query, timeRange, "$__timeGroup(time_column , '5m')")
|
||||
So(err, ShouldBeNil)
|
||||
sql2, err := engine.Interpolate(query, timeRange, "$__timeGroupAlias(time_column , '5m')")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(sql, ShouldEqual, "GROUP BY floor(extract(epoch from time_column)/300)*300 AS time")
|
||||
So(sql, ShouldEqual, "floor(extract(epoch from time_column)/300)*300")
|
||||
So(sql2, ShouldEqual, sql+" AS \"time\"")
|
||||
})
|
||||
|
||||
Convey("interpolate __timeTo function", func() {
|
||||
|
||||
@@ -183,7 +183,7 @@ func TestPostgres(t *testing.T) {
|
||||
Queries: []*tsdb.Query{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT $__timeGroup(time, '5m'), avg(value) as value FROM metric GROUP BY 1 ORDER BY 1",
|
||||
"rawSql": "SELECT $__timeGroup(time, '5m') AS time, avg(value) as value FROM metric GROUP BY 1 ORDER BY 1",
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
@@ -227,7 +227,7 @@ func TestPostgres(t *testing.T) {
|
||||
Queries: []*tsdb.Query{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT $__timeGroup(time, '5m', NULL), avg(value) as value FROM metric GROUP BY 1 ORDER BY 1",
|
||||
"rawSql": "SELECT $__timeGroup(time, '5m', NULL) AS time, avg(value) as value FROM metric GROUP BY 1 ORDER BY 1",
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
@@ -281,7 +281,7 @@ func TestPostgres(t *testing.T) {
|
||||
Queries: []*tsdb.Query{
|
||||
{
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT $__timeGroup(time, '5m', 1.5), avg(value) as value FROM metric GROUP BY 1 ORDER BY 1",
|
||||
"rawSql": "SELECT $__timeGroup(time, '5m', 1.5) AS time, avg(value) as value FROM metric GROUP BY 1 ORDER BY 1",
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
|
||||
@@ -253,7 +253,6 @@ func (e *sqlQueryEndpoint) transformToTimeSeries(query *Query, rows *core.Rows,
|
||||
columnType := columnTypes[i].DatabaseTypeName()
|
||||
|
||||
for _, mct := range e.metricColumnTypes {
|
||||
e.log.Info(mct)
|
||||
if columnType == mct {
|
||||
metricIndex = i
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user