mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
MSSQL Datasource: Revert functions within macros change (#63592)
* Revert functions within macros change * Add tests for function and macro for mssql * Remove macro support tests --------- Co-authored-by: Oscar Kilhed <oscar.kilhed@grafana.com>
This commit is contained in:
parent
05a9946b18
commit
356e2e1933
@ -13,7 +13,6 @@ import (
|
||||
|
||||
const rsIdentifier = `([_a-zA-Z0-9]+)`
|
||||
const sExpr = `\$` + rsIdentifier + `\(([^\)]*)\)`
|
||||
const argFuncExpr = `[\(|,|\s]([_a-zA-Z0-9]+\([^\(]*?\))`
|
||||
|
||||
type msSQLMacroEngine struct {
|
||||
*sqleng.SQLMacroEngineBase
|
||||
@ -23,45 +22,16 @@ func newMssqlMacroEngine() sqleng.SQLMacroEngine {
|
||||
return &msSQLMacroEngine{SQLMacroEngineBase: sqleng.NewSQLMacroEngineBase()}
|
||||
}
|
||||
|
||||
func replaceFunctionCallArgsWithPlaceholders(sql string) (string, map[string]string) {
|
||||
rExp, _ := regexp.Compile(argFuncExpr)
|
||||
functionCalls := rExp.FindAllString(sql, -1)
|
||||
replacedArgs := make(map[string]string)
|
||||
|
||||
if len(functionCalls) > 0 {
|
||||
sql = strings.Replace(sql, "\n", "", -1)
|
||||
|
||||
for i, functionCall := range functionCalls {
|
||||
key := fmt.Sprintf("$%d", i)
|
||||
formattedVal := functionCall[1:]
|
||||
sql = strings.Replace(sql, formattedVal, key, 1)
|
||||
replacedArgs[key] = formattedVal
|
||||
}
|
||||
|
||||
return sql, replacedArgs
|
||||
}
|
||||
|
||||
return sql, nil
|
||||
}
|
||||
|
||||
func (m *msSQLMacroEngine) Interpolate(query *backend.DataQuery, timeRange backend.TimeRange,
|
||||
sql string) (string, error) {
|
||||
// TODO: Return any error
|
||||
rExp, _ := regexp.Compile(sExpr)
|
||||
var macroError error
|
||||
var fctCallArgsMap map[string]string
|
||||
|
||||
if rExp.FindAllSubmatchIndex([]byte(sql), -1) != nil {
|
||||
sql, fctCallArgsMap = replaceFunctionCallArgsWithPlaceholders(sql)
|
||||
}
|
||||
|
||||
sql = m.ReplaceAllStringSubmatchFunc(rExp, sql, func(groups []string) string {
|
||||
args := strings.Split(groups[2], ",")
|
||||
for i, arg := range args {
|
||||
args[i] = strings.Trim(arg, " ")
|
||||
if fctCallArgsMap != nil && fctCallArgsMap[args[i]] != "" {
|
||||
args[i] = strings.Replace(args[i], args[i], fctCallArgsMap[args[i]], 1)
|
||||
}
|
||||
}
|
||||
res, err := m.evaluateMacro(timeRange, query, groups[1], args)
|
||||
if err != nil && macroError == nil {
|
||||
|
@ -208,148 +208,6 @@ func TestMacroEngine(t *testing.T) {
|
||||
require.Equal(t, fmt.Sprintf("select time_column >= %d AND time_column <= %d", from.UnixNano(), to.UnixNano()), sql)
|
||||
})
|
||||
|
||||
t.Run("interpolate __timeGroup with function calls as params successfully", func(t *testing.T) {
|
||||
//various queries with function calls as params tested with different spacings
|
||||
sqls := []struct {
|
||||
query string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
query: "select $__timeGroup(test, 5m)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', test)/300)*300",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup(try_convert(timestamp, time), 5m)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup(func(), 5m)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', func())/300)*300",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup( try_convert(timestamp, time), 5m)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup( \n try_convert(timestamp, time), 5m)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup( \n\n\ntry_convert(timestamp, time), 5m)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup( try_convert(timestamp, time) , 5m)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup( try_convert(timestamp, time) ,5m)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup(try_convert(timestamp, time),5m)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup(try_convert(timestamp, time), 5m)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup(try_convert(timestamp, time), 5m)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300",
|
||||
},
|
||||
}
|
||||
|
||||
for _, sql := range sqls {
|
||||
actual, err := engine.Interpolate(query, timeRange, sql.query)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, sql.expected, actual)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("interpolate macros with function calls as params successfully", func(t *testing.T) {
|
||||
filterInterpolated := fmt.Sprintf("BETWEEN '%s' AND '%s'", from.Format(time.RFC3339), to.Format(time.RFC3339))
|
||||
unixEpochFilter := fmt.Sprintf("select try_convert(timestamp, time) >= %d AND try_convert(timestamp, time) <= %d", from.Unix(), to.Unix())
|
||||
unixEphocNanoFilter := fmt.Sprintf("select try_convert(timestamp, time) >= %d AND try_convert(timestamp, time) <= %d", from.UnixNano(), to.UnixNano())
|
||||
|
||||
//queries with macros and fct calls as params. fct calls are tested with various params and spaces
|
||||
sqls := []struct {
|
||||
query string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
query: "select $__timeGroup(try_convert(timestamp, time), 5m) from test where $__timeFilter(time)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300 from test where time " + filterInterpolated,
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup(try_convert(timestamp, time), 5m) from test where $__timeFilter(func(time))",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300 from test where func(time) " + filterInterpolated,
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup(try_convert(timestamp, time), 5m) from test where $__timeFilter(func(time));",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300 from test where func(time) " + filterInterpolated + ";",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup(try_convert(timestamp, time), 5m) from test where $__timeFilter(func(time, var2));",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300 from test where func(time, var2) " + filterInterpolated + ";",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup(try_convert(timestamp, time), 5m), $__timeGroup(func2( var1 , var2, var3 ), 15m) from test where $__timeFilter(func(time, var2));",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/300)*300, FLOOR(DATEDIFF(second, '1970-01-01', func2( var1 , var2, var3 ))/900)*900 from test where func(time, var2) " + filterInterpolated + ";",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroupAlias(try_convert(), 5m)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert())/300)*300 AS [time]",
|
||||
},
|
||||
{
|
||||
query: "select $__timeEpoch(try_convert(timestamp, time))",
|
||||
expected: "select DATEDIFF(second, '1970-01-01', try_convert(timestamp, time)) AS time",
|
||||
},
|
||||
{
|
||||
query: "select $__time(try_convert(timestamp, time))",
|
||||
expected: "select try_convert(timestamp, time) AS time",
|
||||
},
|
||||
{
|
||||
query: "select $__timeGroup(try_convert(timestamp, time), 15m, NULL)",
|
||||
expected: "select FLOOR(DATEDIFF(second, '1970-01-01', try_convert(timestamp, time))/900)*900",
|
||||
},
|
||||
{
|
||||
query: "select $__unixEpochFilter(try_convert(timestamp, time))",
|
||||
expected: unixEpochFilter,
|
||||
},
|
||||
{
|
||||
query: "select $__unixEpochNanoFilter(try_convert(timestamp, time))",
|
||||
expected: unixEphocNanoFilter,
|
||||
},
|
||||
{
|
||||
query: "select $__unixEpochGroup(try_convert(timestamp, time), 15m)",
|
||||
expected: "select FLOOR(try_convert(timestamp, time)/900)*900",
|
||||
},
|
||||
{
|
||||
query: "select $__unixEpochGroupAlias(try_convert(timestamp, time), 15m)",
|
||||
expected: "select FLOOR(try_convert(timestamp, time)/900)*900 AS [time]",
|
||||
},
|
||||
}
|
||||
|
||||
for _, sql := range sqls {
|
||||
actual, err := engine.Interpolate(query, timeRange, sql.query)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, sql.expected, actual)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("interpolate macros with function calls as params unsuccessfully", func(t *testing.T) {
|
||||
sqls := []string{
|
||||
"select $__timeGroup(func1(func2()), 5m)", //cannot go beyond 1st level of nested function calls
|
||||
"select $__timeGroup(func1(), func2())", //second param must be interval
|
||||
}
|
||||
|
||||
for _, sql := range sqls {
|
||||
_, err := engine.Interpolate(query, timeRange, sql)
|
||||
require.NotNil(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return unmodified sql if there are no macros present", func(t *testing.T) {
|
||||
sqls := []string{
|
||||
"select * from table",
|
||||
|
Loading…
Reference in New Issue
Block a user