Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
9d84e6f3
Unverified
Commit
9d84e6f3
authored
Apr 10, 2018
by
Marcus Efraimsson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mssql: fix precision for time columns in time series query mode
parent
0317ecbf
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
359 additions
and
63 deletions
+359
-63
docker/blocks/mssql_tests/dashboard.json
+123
-26
pkg/tsdb/mssql/mssql.go
+8
-7
pkg/tsdb/mssql/mssql_test.go
+228
-30
No files found.
docker/blocks/mssql_tests/dashboard.json
View file @
9d84e6f3
...
...
@@ -100,7 +100,7 @@
"gnetId"
:
null
,
"graphTooltip"
:
0
,
"id"
:
null
,
"iteration"
:
152
1715844826
,
"iteration"
:
152
3320861623
,
"links"
:
[],
"panels"
:
[
{
...
...
@@ -443,7 +443,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -522,7 +526,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -601,7 +609,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -680,7 +692,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -759,7 +775,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -838,7 +858,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -927,7 +951,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -1026,7 +1054,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -1115,7 +1147,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -1196,7 +1232,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -1285,7 +1325,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -1366,7 +1410,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -1455,7 +1503,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -1536,7 +1588,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -1619,7 +1675,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -1702,7 +1762,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -1792,7 +1856,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -1875,7 +1943,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -1965,7 +2037,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -2048,7 +2124,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -2138,7 +2218,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -2221,7 +2305,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -2311,7 +2399,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
},
{
"aliasColors"
:
{},
...
...
@@ -2394,7 +2486,11 @@
"min"
:
null
,
"show"
:
true
}
]
],
"yaxis"
:
{
"align"
:
false
,
"alignLevel"
:
null
}
}
],
"refresh"
:
false
,
...
...
@@ -2504,5 +2600,5 @@
"timezone"
:
""
,
"title"
:
"Microsoft SQL Server Data Source Test"
,
"uid"
:
"GlAqcPgmz"
,
"version"
:
5
7
"version"
:
5
8
}
\ No newline at end of file
pkg/tsdb/mssql/mssql.go
View file @
9d84e6f3
...
...
@@ -8,8 +8,6 @@ import (
"strconv"
"strings"
"time"
"math"
_
"github.com/denisenkom/go-mssqldb"
...
...
@@ -231,15 +229,18 @@ func (e MssqlQueryEndpoint) transformToTimeSeries(query *tsdb.Query, rows *core.
return
err
}
// converts column named time to unix timestamp in milliseconds to make
// native mysql datetime types and epoch dates work in
// annotation and table queries.
tsdb
.
ConvertSqlTimeColumnToEpochMs
(
values
,
timeIndex
)
switch
columnValue
:=
values
[
timeIndex
]
.
(
type
)
{
case
int64
:
timestamp
=
float64
(
columnValue
*
1000
)
timestamp
=
float64
(
columnValue
)
case
float64
:
timestamp
=
columnValue
*
1000
case
time
.
Time
:
timestamp
=
(
float64
(
columnValue
.
Unix
())
*
1000
)
+
float64
(
columnValue
.
Nanosecond
()
/
1e6
)
// in case someone is trying to map times beyond 2262 :D
timestamp
=
columnValue
default
:
return
fmt
.
Errorf
(
"Invalid type for column time, must be of type timestamp or unix timestamp
"
)
return
fmt
.
Errorf
(
"Invalid type for column time, must be of type timestamp or unix timestamp
, got: %T %v"
,
columnValue
,
columnValue
)
}
if
metricIndex
>=
0
{
...
...
pkg/tsdb/mssql/mssql_test.go
View file @
9d84e6f3
...
...
@@ -188,10 +188,8 @@ func TestMSSQL(t *testing.T) {
})
}
for
_
,
s
:=
range
series
{
_
,
err
=
sess
.
Insert
(
s
)
So
(
err
,
ShouldBeNil
)
}
_
,
err
=
sess
.
InsertMulti
(
series
)
So
(
err
,
ShouldBeNil
)
Convey
(
"When doing a metric query using timeGroup"
,
func
()
{
query
:=
&
tsdb
.
TsdbQuery
{
...
...
@@ -312,10 +310,18 @@ func TestMSSQL(t *testing.T) {
Convey
(
"Given a table with metrics having multiple values and measurements"
,
func
()
{
type
metric_values
struct
{
Time
time
.
Time
Measurement
string
ValueOne
int64
`xorm:"integer 'valueOne'"`
ValueTwo
int64
`xorm:"integer 'valueTwo'"`
Time
time
.
Time
TimeInt64
int64
`xorm:"bigint 'timeInt64' not null"`
TimeInt64Nullable
*
int64
`xorm:"bigint 'timeInt64Nullable' null"`
TimeFloat64
float64
`xorm:"float 'timeFloat64' not null"`
TimeFloat64Nullable
*
float64
`xorm:"float 'timeFloat64Nullable' null"`
TimeInt32
int32
`xorm:"int(11) 'timeInt32' not null"`
TimeInt32Nullable
*
int32
`xorm:"int(11) 'timeInt32Nullable' null"`
TimeFloat32
float32
`xorm:"float(11) 'timeFloat32' not null"`
TimeFloat32Nullable
*
float32
`xorm:"float(11) 'timeFloat32Nullable' null"`
Measurement
string
ValueOne
int64
`xorm:"integer 'valueOne'"`
ValueTwo
int64
`xorm:"integer 'valueTwo'"`
}
if
exist
,
err
:=
sess
.
IsTableExist
(
metric_values
{});
err
!=
nil
||
exist
{
...
...
@@ -330,26 +336,219 @@ func TestMSSQL(t *testing.T) {
return
rand
.
Int63n
(
max
-
min
)
+
min
}
var
tInitial
time
.
Time
series
:=
[]
*
metric_values
{}
for
_
,
t
:=
range
genTimeRangeByInterval
(
fromStart
.
Add
(
-
30
*
time
.
Minute
),
90
*
time
.
Minute
,
5
*
time
.
Minute
)
{
series
=
append
(
series
,
&
metric_values
{
Time
:
t
,
Measurement
:
"Metric A"
,
ValueOne
:
rnd
(
0
,
100
),
ValueTwo
:
rnd
(
0
,
100
),
})
series
=
append
(
series
,
&
metric_values
{
Time
:
t
,
Measurement
:
"Metric B"
,
ValueOne
:
rnd
(
0
,
100
),
ValueTwo
:
rnd
(
0
,
100
),
})
for
i
,
t
:=
range
genTimeRangeByInterval
(
fromStart
.
Add
(
-
30
*
time
.
Minute
),
90
*
time
.
Minute
,
5
*
time
.
Minute
)
{
if
i
==
0
{
tInitial
=
t
}
tSeconds
:=
t
.
Unix
()
tSecondsInt32
:=
int32
(
tSeconds
)
tSecondsFloat32
:=
float32
(
tSeconds
)
tMilliseconds
:=
tSeconds
*
1e3
tMillisecondsFloat
:=
float64
(
tMilliseconds
)
first
:=
metric_values
{
Time
:
t
,
TimeInt64
:
tMilliseconds
,
TimeInt64Nullable
:
&
(
tMilliseconds
),
TimeFloat64
:
tMillisecondsFloat
,
TimeFloat64Nullable
:
&
tMillisecondsFloat
,
TimeInt32
:
tSecondsInt32
,
TimeInt32Nullable
:
&
tSecondsInt32
,
TimeFloat32
:
tSecondsFloat32
,
TimeFloat32Nullable
:
&
tSecondsFloat32
,
Measurement
:
"Metric A"
,
ValueOne
:
rnd
(
0
,
100
),
ValueTwo
:
rnd
(
0
,
100
),
}
second
:=
first
second
.
Measurement
=
"Metric B"
second
.
ValueOne
=
rnd
(
0
,
100
)
second
.
ValueTwo
=
rnd
(
0
,
100
)
series
=
append
(
series
,
&
first
)
series
=
append
(
series
,
&
second
)
}
for
_
,
s
:=
range
series
{
_
,
err
=
sess
.
Insert
(
s
)
_
,
err
=
sess
.
InsertMulti
(
series
)
So
(
err
,
ShouldBeNil
)
Convey
(
"When doing a metric query using epoch (int64) as time column should return metric with time in milliseconds"
,
func
()
{
query
:=
&
tsdb
.
TsdbQuery
{
Queries
:
[]
*
tsdb
.
Query
{
{
Model
:
simplejson
.
NewFromAny
(
map
[
string
]
interface
{}{
"rawSql"
:
`SELECT TOP 1 timeInt64 as time, valueOne FROM metric_values ORDER BY time`
,
"format"
:
"time_series"
,
}),
RefId
:
"A"
,
},
},
}
resp
,
err
:=
endpoint
.
Query
(
nil
,
nil
,
query
)
So
(
err
,
ShouldBeNil
)
}
queryResult
:=
resp
.
Results
[
"A"
]
So
(
queryResult
.
Error
,
ShouldBeNil
)
So
(
len
(
queryResult
.
Series
),
ShouldEqual
,
1
)
So
(
queryResult
.
Series
[
0
]
.
Points
[
0
][
1
]
.
Float64
,
ShouldEqual
,
float64
(
tInitial
.
UnixNano
()
/
1e6
))
})
Convey
(
"When doing a metric query using epoch (int64 nullable) as time column should return metric with time in milliseconds"
,
func
()
{
query
:=
&
tsdb
.
TsdbQuery
{
Queries
:
[]
*
tsdb
.
Query
{
{
Model
:
simplejson
.
NewFromAny
(
map
[
string
]
interface
{}{
"rawSql"
:
`SELECT TOP 1 timeInt64Nullable as time, valueOne FROM metric_values ORDER BY time`
,
"format"
:
"time_series"
,
}),
RefId
:
"A"
,
},
},
}
resp
,
err
:=
endpoint
.
Query
(
nil
,
nil
,
query
)
So
(
err
,
ShouldBeNil
)
queryResult
:=
resp
.
Results
[
"A"
]
So
(
queryResult
.
Error
,
ShouldBeNil
)
So
(
len
(
queryResult
.
Series
),
ShouldEqual
,
1
)
So
(
queryResult
.
Series
[
0
]
.
Points
[
0
][
1
]
.
Float64
,
ShouldEqual
,
float64
(
tInitial
.
UnixNano
()
/
1e6
))
})
Convey
(
"When doing a metric query using epoch (float64) as time column should return metric with time in milliseconds"
,
func
()
{
query
:=
&
tsdb
.
TsdbQuery
{
Queries
:
[]
*
tsdb
.
Query
{
{
Model
:
simplejson
.
NewFromAny
(
map
[
string
]
interface
{}{
"rawSql"
:
`SELECT TOP 1 timeFloat64 as time, valueOne FROM metric_values ORDER BY time`
,
"format"
:
"time_series"
,
}),
RefId
:
"A"
,
},
},
}
resp
,
err
:=
endpoint
.
Query
(
nil
,
nil
,
query
)
So
(
err
,
ShouldBeNil
)
queryResult
:=
resp
.
Results
[
"A"
]
So
(
queryResult
.
Error
,
ShouldBeNil
)
So
(
len
(
queryResult
.
Series
),
ShouldEqual
,
1
)
So
(
queryResult
.
Series
[
0
]
.
Points
[
0
][
1
]
.
Float64
,
ShouldEqual
,
float64
(
tInitial
.
UnixNano
()
/
1e6
))
})
Convey
(
"When doing a metric query using epoch (float64 nullable) as time column should return metric with time in milliseconds"
,
func
()
{
query
:=
&
tsdb
.
TsdbQuery
{
Queries
:
[]
*
tsdb
.
Query
{
{
Model
:
simplejson
.
NewFromAny
(
map
[
string
]
interface
{}{
"rawSql"
:
`SELECT TOP 1 timeFloat64Nullable as time, valueOne FROM metric_values ORDER BY time`
,
"format"
:
"time_series"
,
}),
RefId
:
"A"
,
},
},
}
resp
,
err
:=
endpoint
.
Query
(
nil
,
nil
,
query
)
So
(
err
,
ShouldBeNil
)
queryResult
:=
resp
.
Results
[
"A"
]
So
(
queryResult
.
Error
,
ShouldBeNil
)
So
(
len
(
queryResult
.
Series
),
ShouldEqual
,
1
)
So
(
queryResult
.
Series
[
0
]
.
Points
[
0
][
1
]
.
Float64
,
ShouldEqual
,
float64
(
tInitial
.
UnixNano
()
/
1e6
))
})
Convey
(
"When doing a metric query using epoch (int32) as time column should return metric with time in milliseconds"
,
func
()
{
query
:=
&
tsdb
.
TsdbQuery
{
Queries
:
[]
*
tsdb
.
Query
{
{
Model
:
simplejson
.
NewFromAny
(
map
[
string
]
interface
{}{
"rawSql"
:
`SELECT TOP 1 timeInt32 as time, valueOne FROM metric_values ORDER BY time`
,
"format"
:
"time_series"
,
}),
RefId
:
"A"
,
},
},
}
resp
,
err
:=
endpoint
.
Query
(
nil
,
nil
,
query
)
So
(
err
,
ShouldBeNil
)
queryResult
:=
resp
.
Results
[
"A"
]
So
(
queryResult
.
Error
,
ShouldBeNil
)
So
(
len
(
queryResult
.
Series
),
ShouldEqual
,
1
)
So
(
queryResult
.
Series
[
0
]
.
Points
[
0
][
1
]
.
Float64
,
ShouldEqual
,
float64
(
tInitial
.
UnixNano
()
/
1e6
))
})
Convey
(
"When doing a metric query using epoch (int32 nullable) as time column should return metric with time in milliseconds"
,
func
()
{
query
:=
&
tsdb
.
TsdbQuery
{
Queries
:
[]
*
tsdb
.
Query
{
{
Model
:
simplejson
.
NewFromAny
(
map
[
string
]
interface
{}{
"rawSql"
:
`SELECT TOP 1 timeInt32Nullable as time, valueOne FROM metric_values ORDER BY time`
,
"format"
:
"time_series"
,
}),
RefId
:
"A"
,
},
},
}
resp
,
err
:=
endpoint
.
Query
(
nil
,
nil
,
query
)
So
(
err
,
ShouldBeNil
)
queryResult
:=
resp
.
Results
[
"A"
]
So
(
queryResult
.
Error
,
ShouldBeNil
)
So
(
len
(
queryResult
.
Series
),
ShouldEqual
,
1
)
So
(
queryResult
.
Series
[
0
]
.
Points
[
0
][
1
]
.
Float64
,
ShouldEqual
,
float64
(
tInitial
.
UnixNano
()
/
1e6
))
})
Convey
(
"When doing a metric query using epoch (float32) as time column should return metric with time in milliseconds"
,
func
()
{
query
:=
&
tsdb
.
TsdbQuery
{
Queries
:
[]
*
tsdb
.
Query
{
{
Model
:
simplejson
.
NewFromAny
(
map
[
string
]
interface
{}{
"rawSql"
:
`SELECT TOP 1 timeFloat32 as time, valueOne FROM metric_values ORDER BY time`
,
"format"
:
"time_series"
,
}),
RefId
:
"A"
,
},
},
}
resp
,
err
:=
endpoint
.
Query
(
nil
,
nil
,
query
)
So
(
err
,
ShouldBeNil
)
queryResult
:=
resp
.
Results
[
"A"
]
So
(
queryResult
.
Error
,
ShouldBeNil
)
So
(
len
(
queryResult
.
Series
),
ShouldEqual
,
1
)
So
(
queryResult
.
Series
[
0
]
.
Points
[
0
][
1
]
.
Float64
,
ShouldEqual
,
float64
(
float64
(
float32
(
tInitial
.
Unix
())))
*
1e3
)
})
Convey
(
"When doing a metric query using epoch (float32 nullable) as time column should return metric with time in milliseconds"
,
func
()
{
query
:=
&
tsdb
.
TsdbQuery
{
Queries
:
[]
*
tsdb
.
Query
{
{
Model
:
simplejson
.
NewFromAny
(
map
[
string
]
interface
{}{
"rawSql"
:
`SELECT TOP 1 timeFloat32Nullable as time, valueOne FROM metric_values ORDER BY time`
,
"format"
:
"time_series"
,
}),
RefId
:
"A"
,
},
},
}
resp
,
err
:=
endpoint
.
Query
(
nil
,
nil
,
query
)
So
(
err
,
ShouldBeNil
)
queryResult
:=
resp
.
Results
[
"A"
]
So
(
queryResult
.
Error
,
ShouldBeNil
)
So
(
len
(
queryResult
.
Series
),
ShouldEqual
,
1
)
So
(
queryResult
.
Series
[
0
]
.
Points
[
0
][
1
]
.
Float64
,
ShouldEqual
,
float64
(
float64
(
float32
(
tInitial
.
Unix
())))
*
1e3
)
})
Convey
(
"When doing a metric query grouping by time and select metric column should return correct series"
,
func
()
{
query
:=
&
tsdb
.
TsdbQuery
{
...
...
@@ -476,7 +675,6 @@ func TestMSSQL(t *testing.T) {
resp
,
err
:=
endpoint
.
Query
(
nil
,
nil
,
query
)
queryResult
:=
resp
.
Results
[
"A"
]
So
(
err
,
ShouldBeNil
)
fmt
.
Println
(
"query"
,
"sql"
,
queryResult
.
Meta
)
So
(
queryResult
.
Error
,
ShouldBeNil
)
So
(
len
(
queryResult
.
Series
),
ShouldEqual
,
4
)
...
...
@@ -696,7 +894,7 @@ func TestMSSQL(t *testing.T) {
columns
:=
queryResult
.
Tables
[
0
]
.
Rows
[
0
]
//Should be in milliseconds
So
(
columns
[
0
]
.
(
float64
),
ShouldEqual
,
float64
(
dt
.
Unix
()
*
1000
))
So
(
columns
[
0
]
.
(
float64
),
ShouldEqual
,
float64
(
dt
.
Unix
Nano
()
/
1e6
))
})
Convey
(
"When doing an annotation query with a time column in epoch second format should return ms"
,
func
()
{
...
...
@@ -850,15 +1048,15 @@ func TestMSSQL(t *testing.T) {
func
InitMSSQLTestDB
(
t
*
testing
.
T
)
*
xorm
.
Engine
{
x
,
err
:=
xorm
.
NewEngine
(
sqlutil
.
TestDB_Mssql
.
DriverName
,
strings
.
Replace
(
sqlutil
.
TestDB_Mssql
.
ConnStr
,
"localhost"
,
serverIP
,
1
))
if
err
!=
nil
{
t
.
Fatalf
(
"Failed to init mssql db %v"
,
err
)
}
x
.
DatabaseTZ
=
time
.
UTC
x
.
TZLocation
=
time
.
UTC
// x.ShowSQL()
if
err
!=
nil
{
t
.
Fatalf
(
"Failed to init mssql db %v"
,
err
)
}
return
x
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment