diff --git a/console/graph.go b/console/graph.go index d31c230d..f99ea9c9 100644 --- a/console/graph.go +++ b/console/graph.go @@ -40,7 +40,7 @@ type graphHandlerOutput struct { // graphHandlerInputToSQL converts a graph input to an SQL request func (input graphHandlerInput) toSQL() (string, error) { interval := int64((input.End.Sub(input.Start).Seconds())) / int64(input.Points) - slot := fmt.Sprintf(`(intDiv(%d, {resolution})*{resolution})`, interval) + slot := fmt.Sprintf(`max2(intDiv(%d, {resolution})*{resolution}, 1)`, interval) // Filter where := input.Filter.filter @@ -105,7 +105,7 @@ GROUP BY time, dimensions ORDER BY time WITH FILL FROM toStartOfInterval({timefilter.Start}, INTERVAL %s second) TO {timefilter.Stop} - STEP %s`, withStr, strings.Join(fields, ",\n "), where, slot, slot) + STEP toUInt32(%s)`, withStr, strings.Join(fields, ",\n "), where, slot, slot) return sqlQuery, nil } diff --git a/console/graph_test.go b/console/graph_test.go index 1df496aa..e431232f 100644 --- a/console/graph_test.go +++ b/console/graph_test.go @@ -32,16 +32,16 @@ func TestGraphQuerySQL(t *testing.T) { }, Expected: ` SELECT - toStartOfInterval(TimeReceived, INTERVAL (intDiv(864, {resolution})*{resolution}) second) AS time, - SUM(Bytes*SamplingRate*8/(intDiv(864, {resolution})*{resolution})) AS xps, + toStartOfInterval(TimeReceived, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) AS time, + SUM(Bytes*SamplingRate*8/max2(intDiv(864, {resolution})*{resolution}, 1)) AS xps, emptyArrayString() AS dimensions FROM {table} WHERE {timefilter} GROUP BY time, dimensions ORDER BY time WITH FILL - FROM toStartOfInterval({timefilter.Start}, INTERVAL (intDiv(864, {resolution})*{resolution}) second) + FROM toStartOfInterval({timefilter.Start}, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) TO {timefilter.Stop} - STEP (intDiv(864, {resolution})*{resolution})`, + STEP toUInt32(max2(intDiv(864, {resolution})*{resolution}, 1))`, }, { Description: "no dimensions, no filters, l2 bps", Input: graphHandlerInput{ @@ -54,16 +54,16 @@ ORDER BY time WITH FILL }, Expected: ` SELECT - toStartOfInterval(TimeReceived, INTERVAL (intDiv(864, {resolution})*{resolution}) second) AS time, - SUM((Bytes+18*Packets)*SamplingRate*8/(intDiv(864, {resolution})*{resolution})) AS xps, + toStartOfInterval(TimeReceived, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) AS time, + SUM((Bytes+18*Packets)*SamplingRate*8/max2(intDiv(864, {resolution})*{resolution}, 1)) AS xps, emptyArrayString() AS dimensions FROM {table} WHERE {timefilter} GROUP BY time, dimensions ORDER BY time WITH FILL - FROM toStartOfInterval({timefilter.Start}, INTERVAL (intDiv(864, {resolution})*{resolution}) second) + FROM toStartOfInterval({timefilter.Start}, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) TO {timefilter.Stop} - STEP (intDiv(864, {resolution})*{resolution})`, + STEP toUInt32(max2(intDiv(864, {resolution})*{resolution}, 1))`, }, { Description: "no dimensions, no filters, pps", Input: graphHandlerInput{ @@ -76,16 +76,16 @@ ORDER BY time WITH FILL }, Expected: ` SELECT - toStartOfInterval(TimeReceived, INTERVAL (intDiv(864, {resolution})*{resolution}) second) AS time, - SUM(Packets*SamplingRate/(intDiv(864, {resolution})*{resolution})) AS xps, + toStartOfInterval(TimeReceived, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) AS time, + SUM(Packets*SamplingRate/max2(intDiv(864, {resolution})*{resolution}, 1)) AS xps, emptyArrayString() AS dimensions FROM {table} WHERE {timefilter} GROUP BY time, dimensions ORDER BY time WITH FILL - FROM toStartOfInterval({timefilter.Start}, INTERVAL (intDiv(864, {resolution})*{resolution}) second) + FROM toStartOfInterval({timefilter.Start}, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) TO {timefilter.Stop} - STEP (intDiv(864, {resolution})*{resolution})`, + STEP toUInt32(max2(intDiv(864, {resolution})*{resolution}, 1))`, }, { Description: "no dimensions", Input: graphHandlerInput{ @@ -98,16 +98,16 @@ ORDER BY time WITH FILL }, Expected: ` SELECT - toStartOfInterval(TimeReceived, INTERVAL (intDiv(864, {resolution})*{resolution}) second) AS time, - SUM(Bytes*SamplingRate*8/(intDiv(864, {resolution})*{resolution})) AS xps, + toStartOfInterval(TimeReceived, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) AS time, + SUM(Bytes*SamplingRate*8/max2(intDiv(864, {resolution})*{resolution}, 1)) AS xps, emptyArrayString() AS dimensions FROM {table} WHERE {timefilter} AND (DstCountry = 'FR' AND SrcCountry = 'US') GROUP BY time, dimensions ORDER BY time WITH FILL - FROM toStartOfInterval({timefilter.Start}, INTERVAL (intDiv(864, {resolution})*{resolution}) second) + FROM toStartOfInterval({timefilter.Start}, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) TO {timefilter.Stop} - STEP (intDiv(864, {resolution})*{resolution})`, + STEP toUInt32(max2(intDiv(864, {resolution})*{resolution}, 1))`, }, { Description: "no filters", Input: graphHandlerInput{ @@ -126,16 +126,16 @@ ORDER BY time WITH FILL WITH rows AS (SELECT ExporterName, InIfProvider FROM {table} WHERE {timefilter} GROUP BY ExporterName, InIfProvider ORDER BY SUM(Bytes) DESC LIMIT 20) SELECT - toStartOfInterval(TimeReceived, INTERVAL (intDiv(864, {resolution})*{resolution}) second) AS time, - SUM(Bytes*SamplingRate*8/(intDiv(864, {resolution})*{resolution})) AS xps, + toStartOfInterval(TimeReceived, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) AS time, + SUM(Bytes*SamplingRate*8/max2(intDiv(864, {resolution})*{resolution}, 1)) AS xps, if((ExporterName, InIfProvider) IN rows, [ExporterName, InIfProvider], ['Other', 'Other']) AS dimensions FROM {table} WHERE {timefilter} GROUP BY time, dimensions ORDER BY time WITH FILL - FROM toStartOfInterval({timefilter.Start}, INTERVAL (intDiv(864, {resolution})*{resolution}) second) + FROM toStartOfInterval({timefilter.Start}, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) TO {timefilter.Stop} - STEP (intDiv(864, {resolution})*{resolution})`, + STEP toUInt32(max2(intDiv(864, {resolution})*{resolution}, 1))`, }, } for _, tc := range cases { diff --git a/console/widgets.go b/console/widgets.go index eaa05c09..fe4208d3 100644 --- a/console/widgets.go +++ b/console/widgets.go @@ -189,7 +189,7 @@ func (c *Component) widgetGraphHandlerFunc(gc *gin.Context) { params.Points = 200 } interval := int64((24 * time.Hour).Seconds()) / int64(params.Points) - slot := fmt.Sprintf(`(intDiv(%d, {resolution})*{resolution})`, interval) + slot := fmt.Sprintf(`max2(intDiv(%d, {resolution})*{resolution}, 1)`, interval) now := c.d.Clock.Now() query := c.queryFlowsTable(fmt.Sprintf(` SELECT @@ -202,7 +202,7 @@ GROUP BY Time ORDER BY Time WITH FILL FROM toStartOfInterval({timefilter.Start}, INTERVAL %s second) TO {timefilter.Stop} - STEP %s`, slot, slot, slot, slot), now.Add(-24*time.Hour), now, time.Duration(interval)*time.Second) + STEP toUInt32(%s)`, slot, slot, slot, slot), now.Add(-24*time.Hour), now, time.Duration(interval)*time.Second) gc.Header("X-SQL-Query", query) results := []struct { diff --git a/console/widgets_test.go b/console/widgets_test.go index 695519b7..fd09fccb 100644 --- a/console/widgets_test.go +++ b/console/widgets_test.go @@ -231,16 +231,16 @@ func TestWidgetGraph(t *testing.T) { mockConn.EXPECT(). Select(gomock.Any(), gomock.Any(), ` SELECT - toStartOfInterval(TimeReceived, INTERVAL (intDiv(864, 1)*1) second) AS Time, - SUM(Bytes*SamplingRate*8/(intDiv(864, 1)*1))/1000/1000/1000 AS Gbps + toStartOfInterval(TimeReceived, INTERVAL max2(intDiv(864, 1)*1, 1) second) AS Time, + SUM(Bytes*SamplingRate*8/max2(intDiv(864, 1)*1, 1))/1000/1000/1000 AS Gbps FROM flows WHERE TimeReceived BETWEEN toDateTime('2009-11-10 23:00:00', 'UTC') AND toDateTime('2009-11-11 23:00:00', 'UTC') AND InIfBoundary = 'external' GROUP BY Time ORDER BY Time WITH FILL - FROM toStartOfInterval(toDateTime('2009-11-10 23:00:00', 'UTC'), INTERVAL (intDiv(864, 1)*1) second) + FROM toStartOfInterval(toDateTime('2009-11-10 23:00:00', 'UTC'), INTERVAL max2(intDiv(864, 1)*1, 1) second) TO toDateTime('2009-11-11 23:00:00', 'UTC') - STEP (intDiv(864, 1)*1)`). + STEP toUInt32(max2(intDiv(864, 1)*1, 1))`). SetArg(1, expected). Return(nil)