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
1783c534
Unverified
Commit
1783c534
authored
Apr 10, 2018
by
Marcus Efraimsson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
postgres: fix precision for time columns in time series query mode
parent
af626466
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
227 additions
and
25 deletions
+227
-25
pkg/tsdb/postgres/postgres.go
+7
-5
pkg/tsdb/postgres/postgres_test.go
+220
-20
No files found.
pkg/tsdb/postgres/postgres.go
View file @
1783c534
...
@@ -7,7 +7,6 @@ import (
...
@@ -7,7 +7,6 @@ import (
"math"
"math"
"net/url"
"net/url"
"strconv"
"strconv"
"time"
"github.com/go-xorm/core"
"github.com/go-xorm/core"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/components/null"
...
@@ -219,13 +218,16 @@ func (e PostgresQueryEndpoint) transformToTimeSeries(query *tsdb.Query, rows *co
...
@@ -219,13 +218,16 @@ func (e PostgresQueryEndpoint) transformToTimeSeries(query *tsdb.Query, rows *co
return
err
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
)
{
switch
columnValue
:=
values
[
timeIndex
]
.
(
type
)
{
case
int64
:
case
int64
:
timestamp
=
float64
(
columnValue
*
1000
)
timestamp
=
float64
(
columnValue
)
case
float64
:
case
float64
:
timestamp
=
columnValue
*
1000
timestamp
=
columnValue
case
time
.
Time
:
timestamp
=
float64
(
columnValue
.
UnixNano
()
/
1e6
)
default
:
default
:
return
fmt
.
Errorf
(
"Invalid type for column time, must be of type timestamp or unix timestamp, got: %T %v"
,
columnValue
,
columnValue
)
return
fmt
.
Errorf
(
"Invalid type for column time, must be of type timestamp or unix timestamp, got: %T %v"
,
columnValue
,
columnValue
)
}
}
...
...
pkg/tsdb/postgres/postgres_test.go
View file @
1783c534
...
@@ -156,8 +156,7 @@ func TestPostgres(t *testing.T) {
...
@@ -156,8 +156,7 @@ func TestPostgres(t *testing.T) {
})
})
}
}
for
_
,
s
:=
range
series
{
_
,
err
=
sess
.
InsertMulti
(
series
)
_
,
err
=
sess
.
Insert
(
s
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
}
}
...
@@ -280,10 +279,18 @@ func TestPostgres(t *testing.T) {
...
@@ -280,10 +279,18 @@ func TestPostgres(t *testing.T) {
Convey
(
"Given a table with metrics having multiple values and measurements"
,
func
()
{
Convey
(
"Given a table with metrics having multiple values and measurements"
,
func
()
{
type
metric_values
struct
{
type
metric_values
struct
{
Time
time
.
Time
Time
time
.
Time
Measurement
string
TimeInt64
int64
`xorm:"bigint 'timeInt64' not null"`
ValueOne
int64
`xorm:"integer 'valueOne'"`
TimeInt64Nullable
*
int64
`xorm:"bigint 'timeInt64Nullable' null"`
ValueTwo
int64
`xorm:"integer 'valueTwo'"`
TimeFloat64
float64
`xorm:"double 'timeFloat64' not null"`
TimeFloat64Nullable
*
float64
`xorm:"double 'timeFloat64Nullable' null"`
TimeInt32
int32
`xorm:"int(11) 'timeInt32' not null"`
TimeInt32Nullable
*
int32
`xorm:"int(11) 'timeInt32Nullable' null"`
TimeFloat32
float32
`xorm:"double 'timeFloat32' not null"`
TimeFloat32Nullable
*
float32
`xorm:"double 'timeFloat32Nullable' null"`
Measurement
string
ValueOne
int64
`xorm:"integer 'valueOne'"`
ValueTwo
int64
`xorm:"integer 'valueTwo'"`
}
}
if
exist
,
err
:=
sess
.
IsTableExist
(
metric_values
{});
err
!=
nil
||
exist
{
if
exist
,
err
:=
sess
.
IsTableExist
(
metric_values
{});
err
!=
nil
||
exist
{
...
@@ -298,27 +305,220 @@ func TestPostgres(t *testing.T) {
...
@@ -298,27 +305,220 @@ func TestPostgres(t *testing.T) {
return
rand
.
Int63n
(
max
-
min
)
+
min
return
rand
.
Int63n
(
max
-
min
)
+
min
}
}
var
tInitial
time
.
Time
series
:=
[]
*
metric_values
{}
series
:=
[]
*
metric_values
{}
for
_
,
t
:=
range
genTimeRangeByInterval
(
fromStart
.
Add
(
-
30
*
time
.
Minute
),
90
*
time
.
Minute
,
5
*
time
.
Minute
)
{
for
i
,
t
:=
range
genTimeRangeByInterval
(
fromStart
.
Add
(
-
30
*
time
.
Minute
),
90
*
time
.
Minute
,
5
*
time
.
Minute
)
{
series
=
append
(
series
,
&
metric_values
{
if
i
==
0
{
Time
:
t
,
tInitial
=
t
Measurement
:
"Metric A"
,
}
ValueOne
:
rnd
(
0
,
100
),
tSeconds
:=
t
.
Unix
()
ValueTwo
:
rnd
(
0
,
100
),
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
)
}
_
,
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 "timeInt64" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`
,
"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 "timeInt64Nullable" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`
,
"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 "timeFloat64" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`
,
"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 "timeFloat64Nullable" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`
,
"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 "timeInt32" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`
,
"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
))
})
})
series
=
append
(
series
,
&
metric_values
{
Time
:
t
,
Convey
(
"When doing a metric query using epoch (int32 nullable) as time column should return metric with time in milliseconds"
,
func
()
{
Measurement
:
"Metric B"
,
query
:=
&
tsdb
.
TsdbQuery
{
ValueOne
:
rnd
(
0
,
100
),
Queries
:
[]
*
tsdb
.
Query
{
ValueTwo
:
rnd
(
0
,
100
),
{
Model
:
simplejson
.
NewFromAny
(
map
[
string
]
interface
{}{
"rawSql"
:
`SELECT "timeInt32Nullable" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`
,
"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 "timeFloat32" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`
,
"format"
:
"time_series"
,
}),
RefId
:
"A"
,
},
},
}
}
for
_
,
s
:=
range
series
{
resp
,
err
:=
endpoint
.
Query
(
nil
,
nil
,
query
)
_
,
err
:=
sess
.
Insert
(
s
)
So
(
err
,
ShouldBeNil
)
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 "timeFloat32Nullable" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`
,
"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
()
{
Convey
(
"When doing a metric query grouping by time and select metric column should return correct series"
,
func
()
{
query
:=
&
tsdb
.
TsdbQuery
{
query
:=
&
tsdb
.
TsdbQuery
{
Queries
:
[]
*
tsdb
.
Query
{
Queries
:
[]
*
tsdb
.
Query
{
...
@@ -473,7 +673,7 @@ func TestPostgres(t *testing.T) {
...
@@ -473,7 +673,7 @@ func TestPostgres(t *testing.T) {
columns
:=
queryResult
.
Tables
[
0
]
.
Rows
[
0
]
columns
:=
queryResult
.
Tables
[
0
]
.
Rows
[
0
]
//Should be in milliseconds
//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
()
{
Convey
(
"When doing an annotation query with a time column in epoch second format should return ms"
,
func
()
{
...
...
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