console: fix a possible divide by 0 error

This is not the only problem we have.
This commit is contained in:
Vincent Bernat
2022-07-09 08:06:23 +02:00
parent d70f59c70f
commit f5e2e85d0d
4 changed files with 28 additions and 28 deletions

View File

@@ -40,7 +40,7 @@ type graphHandlerOutput struct {
// graphHandlerInputToSQL converts a graph input to an SQL request // graphHandlerInputToSQL converts a graph input to an SQL request
func (input graphHandlerInput) toSQL() (string, error) { func (input graphHandlerInput) toSQL() (string, error) {
interval := int64((input.End.Sub(input.Start).Seconds())) / int64(input.Points) 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 // Filter
where := input.Filter.filter where := input.Filter.filter
@@ -105,7 +105,7 @@ GROUP BY time, dimensions
ORDER BY time WITH FILL ORDER BY time WITH FILL
FROM toStartOfInterval({timefilter.Start}, INTERVAL %s second) FROM toStartOfInterval({timefilter.Start}, INTERVAL %s second)
TO {timefilter.Stop} 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 return sqlQuery, nil
} }

View File

@@ -32,16 +32,16 @@ func TestGraphQuerySQL(t *testing.T) {
}, },
Expected: ` Expected: `
SELECT SELECT
toStartOfInterval(TimeReceived, INTERVAL (intDiv(864, {resolution})*{resolution}) second) AS time, toStartOfInterval(TimeReceived, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) AS time,
SUM(Bytes*SamplingRate*8/(intDiv(864, {resolution})*{resolution})) AS xps, SUM(Bytes*SamplingRate*8/max2(intDiv(864, {resolution})*{resolution}, 1)) AS xps,
emptyArrayString() AS dimensions emptyArrayString() AS dimensions
FROM {table} FROM {table}
WHERE {timefilter} WHERE {timefilter}
GROUP BY time, dimensions GROUP BY time, dimensions
ORDER BY time WITH FILL 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} TO {timefilter.Stop}
STEP (intDiv(864, {resolution})*{resolution})`, STEP toUInt32(max2(intDiv(864, {resolution})*{resolution}, 1))`,
}, { }, {
Description: "no dimensions, no filters, l2 bps", Description: "no dimensions, no filters, l2 bps",
Input: graphHandlerInput{ Input: graphHandlerInput{
@@ -54,16 +54,16 @@ ORDER BY time WITH FILL
}, },
Expected: ` Expected: `
SELECT SELECT
toStartOfInterval(TimeReceived, INTERVAL (intDiv(864, {resolution})*{resolution}) second) AS time, toStartOfInterval(TimeReceived, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) AS time,
SUM((Bytes+18*Packets)*SamplingRate*8/(intDiv(864, {resolution})*{resolution})) AS xps, SUM((Bytes+18*Packets)*SamplingRate*8/max2(intDiv(864, {resolution})*{resolution}, 1)) AS xps,
emptyArrayString() AS dimensions emptyArrayString() AS dimensions
FROM {table} FROM {table}
WHERE {timefilter} WHERE {timefilter}
GROUP BY time, dimensions GROUP BY time, dimensions
ORDER BY time WITH FILL 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} TO {timefilter.Stop}
STEP (intDiv(864, {resolution})*{resolution})`, STEP toUInt32(max2(intDiv(864, {resolution})*{resolution}, 1))`,
}, { }, {
Description: "no dimensions, no filters, pps", Description: "no dimensions, no filters, pps",
Input: graphHandlerInput{ Input: graphHandlerInput{
@@ -76,16 +76,16 @@ ORDER BY time WITH FILL
}, },
Expected: ` Expected: `
SELECT SELECT
toStartOfInterval(TimeReceived, INTERVAL (intDiv(864, {resolution})*{resolution}) second) AS time, toStartOfInterval(TimeReceived, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) AS time,
SUM(Packets*SamplingRate/(intDiv(864, {resolution})*{resolution})) AS xps, SUM(Packets*SamplingRate/max2(intDiv(864, {resolution})*{resolution}, 1)) AS xps,
emptyArrayString() AS dimensions emptyArrayString() AS dimensions
FROM {table} FROM {table}
WHERE {timefilter} WHERE {timefilter}
GROUP BY time, dimensions GROUP BY time, dimensions
ORDER BY time WITH FILL 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} TO {timefilter.Stop}
STEP (intDiv(864, {resolution})*{resolution})`, STEP toUInt32(max2(intDiv(864, {resolution})*{resolution}, 1))`,
}, { }, {
Description: "no dimensions", Description: "no dimensions",
Input: graphHandlerInput{ Input: graphHandlerInput{
@@ -98,16 +98,16 @@ ORDER BY time WITH FILL
}, },
Expected: ` Expected: `
SELECT SELECT
toStartOfInterval(TimeReceived, INTERVAL (intDiv(864, {resolution})*{resolution}) second) AS time, toStartOfInterval(TimeReceived, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) AS time,
SUM(Bytes*SamplingRate*8/(intDiv(864, {resolution})*{resolution})) AS xps, SUM(Bytes*SamplingRate*8/max2(intDiv(864, {resolution})*{resolution}, 1)) AS xps,
emptyArrayString() AS dimensions emptyArrayString() AS dimensions
FROM {table} FROM {table}
WHERE {timefilter} AND (DstCountry = 'FR' AND SrcCountry = 'US') WHERE {timefilter} AND (DstCountry = 'FR' AND SrcCountry = 'US')
GROUP BY time, dimensions GROUP BY time, dimensions
ORDER BY time WITH FILL 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} TO {timefilter.Stop}
STEP (intDiv(864, {resolution})*{resolution})`, STEP toUInt32(max2(intDiv(864, {resolution})*{resolution}, 1))`,
}, { }, {
Description: "no filters", Description: "no filters",
Input: graphHandlerInput{ Input: graphHandlerInput{
@@ -126,16 +126,16 @@ ORDER BY time WITH FILL
WITH WITH
rows AS (SELECT ExporterName, InIfProvider FROM {table} WHERE {timefilter} GROUP BY ExporterName, InIfProvider ORDER BY SUM(Bytes) DESC LIMIT 20) rows AS (SELECT ExporterName, InIfProvider FROM {table} WHERE {timefilter} GROUP BY ExporterName, InIfProvider ORDER BY SUM(Bytes) DESC LIMIT 20)
SELECT SELECT
toStartOfInterval(TimeReceived, INTERVAL (intDiv(864, {resolution})*{resolution}) second) AS time, toStartOfInterval(TimeReceived, INTERVAL max2(intDiv(864, {resolution})*{resolution}, 1) second) AS time,
SUM(Bytes*SamplingRate*8/(intDiv(864, {resolution})*{resolution})) AS xps, SUM(Bytes*SamplingRate*8/max2(intDiv(864, {resolution})*{resolution}, 1)) AS xps,
if((ExporterName, InIfProvider) IN rows, [ExporterName, InIfProvider], ['Other', 'Other']) AS dimensions if((ExporterName, InIfProvider) IN rows, [ExporterName, InIfProvider], ['Other', 'Other']) AS dimensions
FROM {table} FROM {table}
WHERE {timefilter} WHERE {timefilter}
GROUP BY time, dimensions GROUP BY time, dimensions
ORDER BY time WITH FILL 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} TO {timefilter.Stop}
STEP (intDiv(864, {resolution})*{resolution})`, STEP toUInt32(max2(intDiv(864, {resolution})*{resolution}, 1))`,
}, },
} }
for _, tc := range cases { for _, tc := range cases {

View File

@@ -189,7 +189,7 @@ func (c *Component) widgetGraphHandlerFunc(gc *gin.Context) {
params.Points = 200 params.Points = 200
} }
interval := int64((24 * time.Hour).Seconds()) / int64(params.Points) 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() now := c.d.Clock.Now()
query := c.queryFlowsTable(fmt.Sprintf(` query := c.queryFlowsTable(fmt.Sprintf(`
SELECT SELECT
@@ -202,7 +202,7 @@ GROUP BY Time
ORDER BY Time WITH FILL ORDER BY Time WITH FILL
FROM toStartOfInterval({timefilter.Start}, INTERVAL %s second) FROM toStartOfInterval({timefilter.Start}, INTERVAL %s second)
TO {timefilter.Stop} 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) gc.Header("X-SQL-Query", query)
results := []struct { results := []struct {

View File

@@ -231,16 +231,16 @@ func TestWidgetGraph(t *testing.T) {
mockConn.EXPECT(). mockConn.EXPECT().
Select(gomock.Any(), gomock.Any(), ` Select(gomock.Any(), gomock.Any(), `
SELECT SELECT
toStartOfInterval(TimeReceived, INTERVAL (intDiv(864, 1)*1) second) AS Time, toStartOfInterval(TimeReceived, INTERVAL max2(intDiv(864, 1)*1, 1) second) AS Time,
SUM(Bytes*SamplingRate*8/(intDiv(864, 1)*1))/1000/1000/1000 AS Gbps SUM(Bytes*SamplingRate*8/max2(intDiv(864, 1)*1, 1))/1000/1000/1000 AS Gbps
FROM flows FROM flows
WHERE TimeReceived BETWEEN toDateTime('2009-11-10 23:00:00', 'UTC') AND toDateTime('2009-11-11 23:00:00', 'UTC') WHERE TimeReceived BETWEEN toDateTime('2009-11-10 23:00:00', 'UTC') AND toDateTime('2009-11-11 23:00:00', 'UTC')
AND InIfBoundary = 'external' AND InIfBoundary = 'external'
GROUP BY Time GROUP BY Time
ORDER BY Time WITH FILL 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') 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). SetArg(1, expected).
Return(nil) Return(nil)