mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Interpolate $__interval in backend for alerting with sql datasources (#13156)
add support for interpolate $__interval and $__interval_ms in sql datasources
This commit is contained in:
committed by
Marcus Efraimsson
parent
bae560717d
commit
0254a29e35
@@ -13,12 +13,13 @@ const rsIdentifier = `([_a-zA-Z0-9]+)`
|
||||
const sExpr = `\$` + rsIdentifier + `\(([^\)]*)\)`
|
||||
|
||||
type msSqlMacroEngine struct {
|
||||
*tsdb.SqlMacroEngineBase
|
||||
timeRange *tsdb.TimeRange
|
||||
query *tsdb.Query
|
||||
}
|
||||
|
||||
func newMssqlMacroEngine() tsdb.SqlMacroEngine {
|
||||
return &msSqlMacroEngine{}
|
||||
return &msSqlMacroEngine{SqlMacroEngineBase: tsdb.NewSqlMacroEngineBase()}
|
||||
}
|
||||
|
||||
func (m *msSqlMacroEngine) Interpolate(query *tsdb.Query, timeRange *tsdb.TimeRange, sql string) (string, error) {
|
||||
@@ -27,7 +28,7 @@ func (m *msSqlMacroEngine) Interpolate(query *tsdb.Query, timeRange *tsdb.TimeRa
|
||||
rExp, _ := regexp.Compile(sExpr)
|
||||
var macroError error
|
||||
|
||||
sql = replaceAllStringSubmatchFunc(rExp, sql, func(groups []string) string {
|
||||
sql = m.ReplaceAllStringSubmatchFunc(rExp, sql, func(groups []string) string {
|
||||
args := strings.Split(groups[2], ",")
|
||||
for i, arg := range args {
|
||||
args[i] = strings.Trim(arg, " ")
|
||||
@@ -47,23 +48,6 @@ func (m *msSqlMacroEngine) Interpolate(query *tsdb.Query, timeRange *tsdb.TimeRa
|
||||
return sql, nil
|
||||
}
|
||||
|
||||
func replaceAllStringSubmatchFunc(re *regexp.Regexp, str string, repl func([]string) string) string {
|
||||
result := ""
|
||||
lastIndex := 0
|
||||
|
||||
for _, v := range re.FindAllSubmatchIndex([]byte(str), -1) {
|
||||
groups := []string{}
|
||||
for i := 0; i < len(v); i += 2 {
|
||||
groups = append(groups, str[v[i]:v[i+1]])
|
||||
}
|
||||
|
||||
result += str[lastIndex:v[0]] + repl(groups)
|
||||
lastIndex = v[1]
|
||||
}
|
||||
|
||||
return result + str[lastIndex:]
|
||||
}
|
||||
|
||||
func (m *msSqlMacroEngine) evaluateMacro(name string, args []string) (string, error) {
|
||||
switch name {
|
||||
case "__time":
|
||||
|
||||
@@ -35,6 +35,11 @@ func TestMSSQL(t *testing.T) {
|
||||
return x, nil
|
||||
}
|
||||
|
||||
origInterpolate := tsdb.Interpolate
|
||||
tsdb.Interpolate = func(query *tsdb.Query, timeRange *tsdb.TimeRange, sql string) (string, error) {
|
||||
return sql, nil
|
||||
}
|
||||
|
||||
endpoint, err := newMssqlQueryEndpoint(&models.DataSource{
|
||||
JsonData: simplejson.New(),
|
||||
SecureJsonData: securejsondata.SecureJsonData{},
|
||||
@@ -47,6 +52,7 @@ func TestMSSQL(t *testing.T) {
|
||||
Reset(func() {
|
||||
sess.Close()
|
||||
tsdb.NewXormEngine = origXormEngine
|
||||
tsdb.Interpolate = origInterpolate
|
||||
})
|
||||
|
||||
Convey("Given a table with different native data types", func() {
|
||||
@@ -295,6 +301,40 @@ func TestMSSQL(t *testing.T) {
|
||||
|
||||
})
|
||||
|
||||
Convey("When doing a metric query using timeGroup and $__interval", func() {
|
||||
mockInterpolate := tsdb.Interpolate
|
||||
tsdb.Interpolate = origInterpolate
|
||||
|
||||
Reset(func() {
|
||||
tsdb.Interpolate = mockInterpolate
|
||||
})
|
||||
|
||||
Convey("Should replace $__interval", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
{
|
||||
DataSource: &models.DataSource{},
|
||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||
"rawSql": "SELECT $__timeGroup(time, $__interval) AS time, avg(value) as value FROM metric GROUP BY $__timeGroup(time, $__interval) ORDER BY 1",
|
||||
"format": "time_series",
|
||||
}),
|
||||
RefId: "A",
|
||||
},
|
||||
},
|
||||
TimeRange: &tsdb.TimeRange{
|
||||
From: fmt.Sprintf("%v", fromStart.Unix()*1000),
|
||||
To: fmt.Sprintf("%v", fromStart.Add(30*time.Minute).Unix()*1000),
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := endpoint.Query(nil, nil, query)
|
||||
So(err, ShouldBeNil)
|
||||
queryResult := resp.Results["A"]
|
||||
So(queryResult.Error, ShouldBeNil)
|
||||
So(queryResult.Meta.Get("sql").MustString(), ShouldEqual, "SELECT FLOOR(DATEDIFF(second, '1970-01-01', time)/60)*60 AS time, avg(value) as value FROM metric GROUP BY FLOOR(DATEDIFF(second, '1970-01-01', time)/60)*60 ORDER BY 1")
|
||||
})
|
||||
})
|
||||
|
||||
Convey("When doing a metric query using timeGroup with float fill enabled", func() {
|
||||
query := &tsdb.TsdbQuery{
|
||||
Queries: []*tsdb.Query{
|
||||
|
||||
Reference in New Issue
Block a user