mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
mssql: fix precision for time columns in time series query mode
This commit is contained in:
@@ -100,7 +100,7 @@
|
|||||||
"gnetId": null,
|
"gnetId": null,
|
||||||
"graphTooltip": 0,
|
"graphTooltip": 0,
|
||||||
"id": null,
|
"id": null,
|
||||||
"iteration": 1521715844826,
|
"iteration": 1523320861623,
|
||||||
"links": [],
|
"links": [],
|
||||||
"panels": [
|
"panels": [
|
||||||
{
|
{
|
||||||
@@ -443,7 +443,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -522,7 +526,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -601,7 +609,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -680,7 +692,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -759,7 +775,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -838,7 +858,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -927,7 +951,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -1026,7 +1054,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -1115,7 +1147,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -1196,7 +1232,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -1285,7 +1325,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -1366,7 +1410,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -1455,7 +1503,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -1536,7 +1588,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -1619,7 +1675,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -1702,7 +1762,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -1792,7 +1856,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -1875,7 +1943,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -1965,7 +2037,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -2048,7 +2124,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -2138,7 +2218,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -2221,7 +2305,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -2311,7 +2399,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
@@ -2394,7 +2486,11 @@
|
|||||||
"min": null,
|
"min": null,
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"refresh": false,
|
"refresh": false,
|
||||||
@@ -2504,5 +2600,5 @@
|
|||||||
"timezone": "",
|
"timezone": "",
|
||||||
"title": "Microsoft SQL Server Data Source Test",
|
"title": "Microsoft SQL Server Data Source Test",
|
||||||
"uid": "GlAqcPgmz",
|
"uid": "GlAqcPgmz",
|
||||||
"version": 57
|
"version": 58
|
||||||
}
|
}
|
||||||
@@ -8,8 +8,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
_ "github.com/denisenkom/go-mssqldb"
|
_ "github.com/denisenkom/go-mssqldb"
|
||||||
@@ -231,15 +229,18 @@ func (e MssqlQueryEndpoint) transformToTimeSeries(query *tsdb.Query, rows *core.
|
|||||||
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.Unix()) * 1000) + float64(columnValue.Nanosecond()/1e6) // in case someone is trying to map times beyond 2262 :D
|
|
||||||
default:
|
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 {
|
if metricIndex >= 0 {
|
||||||
|
|||||||
@@ -188,10 +188,8 @@ func TestMSSQL(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range series {
|
_, err = sess.InsertMulti(series)
|
||||||
_, err = sess.Insert(s)
|
So(err, ShouldBeNil)
|
||||||
So(err, ShouldBeNil)
|
|
||||||
}
|
|
||||||
|
|
||||||
Convey("When doing a metric query using timeGroup", func() {
|
Convey("When doing a metric query using timeGroup", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
@@ -312,10 +310,18 @@ func TestMSSQL(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:"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 {
|
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
|
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)
|
||||||
series = append(series, &metric_values{
|
tMilliseconds := tSeconds * 1e3
|
||||||
Time: t,
|
tMillisecondsFloat := float64(tMilliseconds)
|
||||||
Measurement: "Metric B",
|
first := metric_values{
|
||||||
ValueOne: rnd(0, 100),
|
Time: t,
|
||||||
ValueTwo: rnd(0, 100),
|
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.InsertMulti(series)
|
||||||
_, err = sess.Insert(s)
|
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)
|
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() {
|
Convey("When doing a metric query grouping by time and select metric column should return correct series", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
@@ -476,7 +675,6 @@ func TestMSSQL(t *testing.T) {
|
|||||||
resp, err := endpoint.Query(nil, nil, query)
|
resp, err := endpoint.Query(nil, nil, query)
|
||||||
queryResult := resp.Results["A"]
|
queryResult := resp.Results["A"]
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
fmt.Println("query", "sql", queryResult.Meta)
|
|
||||||
So(queryResult.Error, ShouldBeNil)
|
So(queryResult.Error, ShouldBeNil)
|
||||||
|
|
||||||
So(len(queryResult.Series), ShouldEqual, 4)
|
So(len(queryResult.Series), ShouldEqual, 4)
|
||||||
@@ -696,7 +894,7 @@ func TestMSSQL(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.UnixNano()/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() {
|
||||||
@@ -850,15 +1048,15 @@ func TestMSSQL(t *testing.T) {
|
|||||||
|
|
||||||
func InitMSSQLTestDB(t *testing.T) *xorm.Engine {
|
func InitMSSQLTestDB(t *testing.T) *xorm.Engine {
|
||||||
x, err := xorm.NewEngine(sqlutil.TestDB_Mssql.DriverName, strings.Replace(sqlutil.TestDB_Mssql.ConnStr, "localhost", serverIP, 1))
|
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.DatabaseTZ = time.UTC
|
||||||
x.TZLocation = time.UTC
|
x.TZLocation = time.UTC
|
||||||
|
|
||||||
// x.ShowSQL()
|
// x.ShowSQL()
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to init mssql db %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user