diff --git a/pkg/tsdb/mssql/macros.go b/pkg/tsdb/mssql/macros.go index 3bb35a80939..9a137ce496d 100644 --- a/pkg/tsdb/mssql/macros.go +++ b/pkg/tsdb/mssql/macros.go @@ -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 { diff --git a/pkg/tsdb/mssql/macros_test.go b/pkg/tsdb/mssql/macros_test.go index 7966a08a963..b7d1ce9a87d 100644 --- a/pkg/tsdb/mssql/macros_test.go +++ b/pkg/tsdb/mssql/macros_test.go @@ -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",