Commit 3ccadff8 by Marcus Efraimsson

mssql: fix timeGroup macro so that it properly creates correct groups

Earlier the division of interval was done using whole numbers resulting in that important information
was lost/too many time series merged to the same group. Now using division of floating point and rounding
up to solve the problem
parent 42299eb3
...@@ -113,7 +113,7 @@ func (m *MsSqlMacroEngine) evaluateMacro(name string, args []string) (string, er ...@@ -113,7 +113,7 @@ func (m *MsSqlMacroEngine) evaluateMacro(name string, args []string) (string, er
m.Query.Model.Set("fillValue", floatVal) m.Query.Model.Set("fillValue", floatVal)
} }
} }
return fmt.Sprintf("cast(cast(DATEDIFF(second, {d '1970-01-01'}, DATEADD(second, DATEDIFF(second,GETDATE(),GETUTCDATE()), %s))/%.0f as int)*%.0f as int)", args[0], interval.Seconds(), interval.Seconds()), nil return fmt.Sprintf("CAST(ROUND(DATEDIFF(second, '1970-01-01', %s)/%.1f, 0) as bigint)*%.0f", 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)
......
...@@ -57,14 +57,14 @@ func TestMacroEngine(t *testing.T) { ...@@ -57,14 +57,14 @@ func TestMacroEngine(t *testing.T) {
sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column,'5m')") sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column,'5m')")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "GROUP BY cast(cast(DATEDIFF(second, {d '1970-01-01'}, DATEADD(second, DATEDIFF(second,GETDATE(),GETUTCDATE()), time_column))/300 as int)*300 as int)") So(sql, ShouldEqual, "GROUP BY CAST(ROUND(DATEDIFF(second, '1970-01-01', time_column)/300.0, 0) as bigint)*300")
}) })
Convey("interpolate __timeGroup function with spaces around arguments", func() { Convey("interpolate __timeGroup function with spaces around arguments", func() {
sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column , '5m')") sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column , '5m')")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "GROUP BY cast(cast(DATEDIFF(second, {d '1970-01-01'}, DATEADD(second, DATEDIFF(second,GETDATE(),GETUTCDATE()), time_column))/300 as int)*300 as int)") So(sql, ShouldEqual, "GROUP BY CAST(ROUND(DATEDIFF(second, '1970-01-01', time_column)/300.0, 0) as bigint)*300")
}) })
Convey("interpolate __timeGroup function with fill (value = NULL)", func() { Convey("interpolate __timeGroup function with fill (value = NULL)", func() {
......
...@@ -211,22 +211,32 @@ func TestMSSQL(t *testing.T) { ...@@ -211,22 +211,32 @@ func TestMSSQL(t *testing.T) {
} }
resp, err := endpoint.Query(nil, nil, query) resp, err := endpoint.Query(nil, nil, query)
queryResult := resp.Results["A"]
So(err, ShouldBeNil) So(err, ShouldBeNil)
queryResult := resp.Results["A"]
So(queryResult.Error, ShouldBeNil) So(queryResult.Error, ShouldBeNil)
points := queryResult.Series[0].Points points := queryResult.Series[0].Points
So(len(points), ShouldEqual, 6)
So(len(points), ShouldEqual, 4) dt := fromStart
actualValueFirst := points[0][0].Float64
actualTimeFirst := time.Unix(int64(points[0][1].Float64)/1000, 0) for i := 0; i < 3; i++ {
So(actualValueFirst, ShouldEqual, 15) aValue := points[i][0].Float64
So(actualTimeFirst, ShouldEqual, fromStart) aTime := time.Unix(int64(points[i][1].Float64)/1000, 0)
So(aValue, ShouldEqual, 15)
So(aTime, ShouldEqual, dt)
dt = dt.Add(5 * time.Minute)
}
actualValueLast := points[3][0].Float64 // adjust for 5 minute gap
actualTimeLast := time.Unix(int64(points[3][1].Float64)/1000, 0) dt = dt.Add(5 * time.Minute)
So(actualValueLast, ShouldEqual, 20) for i := 3; i < 6; i++ {
So(actualTimeLast, ShouldEqual, fromStart.Add(25*time.Minute)) aValue := points[i][0].Float64
aTime := time.Unix(int64(points[i][1].Float64)/1000, 0)
So(aValue, ShouldEqual, 20)
So(aTime, ShouldEqual, dt)
dt = dt.Add(5 * time.Minute)
}
}) })
Convey("When doing a metric query using timeGroup with NULL fill enabled", func() { Convey("When doing a metric query using timeGroup with NULL fill enabled", func() {
...@@ -247,33 +257,34 @@ func TestMSSQL(t *testing.T) { ...@@ -247,33 +257,34 @@ func TestMSSQL(t *testing.T) {
} }
resp, err := endpoint.Query(nil, nil, query) resp, err := endpoint.Query(nil, nil, query)
queryResult := resp.Results["A"]
So(err, ShouldBeNil) So(err, ShouldBeNil)
queryResult := resp.Results["A"]
So(queryResult.Error, ShouldBeNil) So(queryResult.Error, ShouldBeNil)
points := queryResult.Series[0].Points points := queryResult.Series[0].Points
So(len(points), ShouldEqual, 7) So(len(points), ShouldEqual, 7)
actualValueFirst := points[0][0].Float64
actualTimeFirst := time.Unix(int64(points[0][1].Float64)/1000, 0)
So(actualValueFirst, ShouldEqual, 15)
So(actualTimeFirst, ShouldEqual, fromStart)
actualNullPoint := points[3][0]
actualNullTime := time.Unix(int64(points[3][1].Float64)/1000, 0)
So(actualNullPoint.Valid, ShouldBeFalse)
So(actualNullTime, ShouldEqual, fromStart.Add(15*time.Minute))
actualValueLast := points[5][0].Float64
actualTimeLast := time.Unix(int64(points[5][1].Float64)/1000, 0)
So(actualValueLast, ShouldEqual, 20)
So(actualTimeLast, ShouldEqual, fromStart.Add(25*time.Minute))
actualLastNullPoint := points[6][0]
actualLastNullTime := time.Unix(int64(points[6][1].Float64)/1000, 0)
So(actualLastNullPoint.Valid, ShouldBeFalse)
So(actualLastNullTime, ShouldEqual, fromStart.Add(30*time.Minute))
dt := fromStart
for i := 0; i < 3; i++ {
aValue := points[i][0].Float64
aTime := time.Unix(int64(points[i][1].Float64)/1000, 0)
So(aValue, ShouldEqual, 15)
So(aTime, ShouldEqual, dt)
dt = dt.Add(5 * time.Minute)
}
So(points[3][0].Valid, ShouldBeFalse)
// adjust for 5 minute gap
dt = dt.Add(5 * time.Minute)
for i := 4; i < 7; i++ {
aValue := points[i][0].Float64
aTime := time.Unix(int64(points[i][1].Float64)/1000, 0)
So(aValue, ShouldEqual, 20)
So(aTime, ShouldEqual, dt)
dt = dt.Add(5 * time.Minute)
}
}) })
Convey("When doing a metric query using timeGroup with float fill enabled", func() { Convey("When doing a metric query using timeGroup with float fill enabled", func() {
...@@ -294,13 +305,12 @@ func TestMSSQL(t *testing.T) { ...@@ -294,13 +305,12 @@ func TestMSSQL(t *testing.T) {
} }
resp, err := endpoint.Query(nil, nil, query) resp, err := endpoint.Query(nil, nil, query)
queryResult := resp.Results["A"]
So(err, ShouldBeNil) So(err, ShouldBeNil)
queryResult := resp.Results["A"]
So(queryResult.Error, ShouldBeNil) So(queryResult.Error, ShouldBeNil)
points := queryResult.Series[0].Points points := queryResult.Series[0].Points
So(points[3][0].Float64, ShouldEqual, 1.5)
So(points[6][0].Float64, ShouldEqual, 1.5)
}) })
}) })
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment