mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge pull request #11714 from grafana/11703_mysql_ts_datatypes
sql tsdb: fix value columns conversion to float when using timeseries query
This commit is contained in:
@@ -256,16 +256,10 @@ func (e MssqlQueryEndpoint) transformToTimeSeries(query *tsdb.Query, rows *core.
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch columnValue := values[i].(type) {
|
if value, err = tsdb.ConvertSqlValueColumnToFloat(col, values[i]); err != nil {
|
||||||
case int64:
|
return err
|
||||||
value = null.FloatFrom(float64(columnValue))
|
|
||||||
case float64:
|
|
||||||
value = null.FloatFrom(columnValue)
|
|
||||||
case nil:
|
|
||||||
value.Valid = false
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Value column must have numeric datatype, column: %s type: %T value: %v", col, columnValue, columnValue)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if metricIndex == -1 {
|
if metricIndex == -1 {
|
||||||
metric = col
|
metric = col
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -374,12 +374,12 @@ func TestMSSQL(t *testing.T) {
|
|||||||
_, err = sess.InsertMulti(series)
|
_, err = sess.InsertMulti(series)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
Convey("When doing a metric query using epoch (int64) as time column should return metric with time in milliseconds", func() {
|
Convey("When doing a metric query using epoch (int64) as time column and value column (int64) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT TOP 1 timeInt64 as time, valueOne FROM metric_values ORDER BY time`,
|
"rawSql": `SELECT TOP 1 timeInt64 as time, timeInt64 FROM metric_values ORDER BY time`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -396,12 +396,12 @@ func TestMSSQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (int64 nullable) as time column and value column (int64 nullable) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT TOP 1 timeInt64Nullable as time, valueOne FROM metric_values ORDER BY time`,
|
"rawSql": `SELECT TOP 1 timeInt64Nullable as time, timeInt64Nullable FROM metric_values ORDER BY time`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -418,12 +418,12 @@ func TestMSSQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (float64) as time column and value column (float64) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT TOP 1 timeFloat64 as time, valueOne FROM metric_values ORDER BY time`,
|
"rawSql": `SELECT TOP 1 timeFloat64 as time, timeFloat64 FROM metric_values ORDER BY time`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -440,12 +440,12 @@ func TestMSSQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (float64 nullable) as time column and value column (float64 nullable) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT TOP 1 timeFloat64Nullable as time, valueOne FROM metric_values ORDER BY time`,
|
"rawSql": `SELECT TOP 1 timeFloat64Nullable as time, timeFloat64Nullable FROM metric_values ORDER BY time`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -462,12 +462,12 @@ func TestMSSQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (int32) as time column and value column (int32) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT TOP 1 timeInt32 as time, valueOne FROM metric_values ORDER BY time`,
|
"rawSql": `SELECT TOP 1 timeInt32 as time, timeInt32 FROM metric_values ORDER BY time`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -484,12 +484,12 @@ func TestMSSQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (int32 nullable) as time column and value column (int32 nullable) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT TOP 1 timeInt32Nullable as time, valueOne FROM metric_values ORDER BY time`,
|
"rawSql": `SELECT TOP 1 timeInt32Nullable as time, timeInt32Nullable FROM metric_values ORDER BY time`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -506,12 +506,12 @@ func TestMSSQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (float32) as time column and value column (float32) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT TOP 1 timeFloat32 as time, valueOne FROM metric_values ORDER BY time`,
|
"rawSql": `SELECT TOP 1 timeFloat32 as time, timeFloat32 FROM metric_values ORDER BY time`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -528,12 +528,12 @@ func TestMSSQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(float64(float32(tInitial.Unix())))*1e3)
|
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() {
|
Convey("When doing a metric query using epoch (float32 nullable) as time column and value column (float32 nullable) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT TOP 1 timeFloat32Nullable as time, valueOne FROM metric_values ORDER BY time`,
|
"rawSql": `SELECT TOP 1 timeFloat32Nullable as time, timeFloat32Nullable FROM metric_values ORDER BY time`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
|
|||||||
@@ -265,16 +265,10 @@ func (e MysqlQueryEndpoint) transformToTimeSeries(query *tsdb.Query, rows *core.
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch columnValue := values[i].(type) {
|
if value, err = tsdb.ConvertSqlValueColumnToFloat(col, values[i]); err != nil {
|
||||||
case int64:
|
return err
|
||||||
value = null.FloatFrom(float64(columnValue))
|
|
||||||
case float64:
|
|
||||||
value = null.FloatFrom(columnValue)
|
|
||||||
case nil:
|
|
||||||
value.Valid = false
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Value column must have numeric datatype, column: %s type: %T value: %v", col, columnValue, columnValue)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if metricIndex == -1 {
|
if metricIndex == -1 {
|
||||||
metric = col
|
metric = col
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -420,12 +420,12 @@ func TestMySQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("When doing a metric query using epoch (int64) as time column should return metric with time in milliseconds", func() {
|
Convey("When doing a metric query using epoch (int64) as time column and value column (int64) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT timeInt64 as time, valueOne FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT timeInt64 as time, timeInt64 FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -442,12 +442,12 @@ func TestMySQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (int64 nullable) as time column and value column (int64 nullable) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT timeInt64Nullable as time, valueOne FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT timeInt64Nullable as time, timeInt64Nullable FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -464,12 +464,12 @@ func TestMySQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (float64) as time column and value column (float64) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT timeFloat64 as time, valueOne FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT timeFloat64 as time, timeFloat64 FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -486,12 +486,12 @@ func TestMySQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (float64 nullable) as time column and value column (float64 nullable) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT timeFloat64Nullable as time, valueOne FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT timeFloat64Nullable as time, timeFloat64Nullable FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -508,12 +508,12 @@ func TestMySQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
FocusConvey("When doing a metric query using epoch (int32) as time column and value column (int32) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT timeInt32 as time, valueOne FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT timeInt32 as time, timeInt32 FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -530,12 +530,12 @@ func TestMySQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (int32 nullable) as time column and value column (int32 nullable) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT timeInt32Nullable as time, valueOne FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT timeInt32Nullable as time, timeInt32Nullable FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -552,12 +552,12 @@ func TestMySQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (float32) as time column and value column (float32) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT timeFloat32 as time, valueOne FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT timeFloat32 as time, timeFloat32 FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -574,12 +574,12 @@ func TestMySQL(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(float64(float32(tInitial.Unix())))*1e3)
|
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() {
|
Convey("When doing a metric query using epoch (float32 nullable) as time column and value column (float32 nullable) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT timeFloat32Nullable as time, valueOne FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT timeFloat32Nullable as time, timeFloat32Nullable FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
|
|||||||
@@ -245,16 +245,10 @@ func (e PostgresQueryEndpoint) transformToTimeSeries(query *tsdb.Query, rows *co
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch columnValue := values[i].(type) {
|
if value, err = tsdb.ConvertSqlValueColumnToFloat(col, values[i]); err != nil {
|
||||||
case int64:
|
return err
|
||||||
value = null.FloatFrom(float64(columnValue))
|
|
||||||
case float64:
|
|
||||||
value = null.FloatFrom(columnValue)
|
|
||||||
case nil:
|
|
||||||
value.Valid = false
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Value column must have numeric datatype, column: %s type: %T value: %v", col, columnValue, columnValue)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if metricIndex == -1 {
|
if metricIndex == -1 {
|
||||||
metric = col
|
metric = col
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -353,12 +353,12 @@ func TestPostgres(t *testing.T) {
|
|||||||
_, err = sess.InsertMulti(series)
|
_, err = sess.InsertMulti(series)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
Convey("When doing a metric query using epoch (int64) as time column should return metric with time in milliseconds", func() {
|
Convey("When doing a metric query using epoch (int64) as time column and value column (int64) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT "timeInt64" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT "timeInt64" as time, "timeInt64" FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -375,12 +375,12 @@ func TestPostgres(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (int64 nullable) as time column and value column (int64 nullable) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT "timeInt64Nullable" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT "timeInt64Nullable" as time, "timeInt64Nullable" FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -397,12 +397,12 @@ func TestPostgres(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (float64) as time column and value column (float64) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT "timeFloat64" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT "timeFloat64" as time, "timeFloat64" FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -419,12 +419,12 @@ func TestPostgres(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (float64 nullable) as time column and value column (float64 nullable) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT "timeFloat64Nullable" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT "timeFloat64Nullable" as time, "timeFloat64Nullable" FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -441,12 +441,12 @@ func TestPostgres(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (int32) as time column and value column (int32) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT "timeInt32" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT "timeInt32" as time, "timeInt32" FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -463,12 +463,12 @@ func TestPostgres(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (int32 nullable) as time column and value column (int32 nullable) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT "timeInt32Nullable" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT "timeInt32Nullable" as time, "timeInt32Nullable" FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -485,12 +485,12 @@ func TestPostgres(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(tInitial.UnixNano()/1e6))
|
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() {
|
Convey("When doing a metric query using epoch (float32) as time column and value column (float32) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT "timeFloat32" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT "timeFloat32" as time, "timeFloat32" FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
@@ -507,12 +507,12 @@ func TestPostgres(t *testing.T) {
|
|||||||
So(queryResult.Series[0].Points[0][1].Float64, ShouldEqual, float64(float64(float32(tInitial.Unix())))*1e3)
|
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() {
|
Convey("When doing a metric query using epoch (float32 nullable) as time column and value column (float32 nullable) should return metric with time in milliseconds", func() {
|
||||||
query := &tsdb.TsdbQuery{
|
query := &tsdb.TsdbQuery{
|
||||||
Queries: []*tsdb.Query{
|
Queries: []*tsdb.Query{
|
||||||
{
|
{
|
||||||
Model: simplejson.NewFromAny(map[string]interface{}{
|
Model: simplejson.NewFromAny(map[string]interface{}{
|
||||||
"rawSql": `SELECT "timeFloat32Nullable" as time, "valueOne" FROM metric_values ORDER BY time LIMIT 1`,
|
"rawSql": `SELECT "timeFloat32Nullable" as time, "timeFloat32Nullable" FROM metric_values ORDER BY time LIMIT 1`,
|
||||||
"format": "time_series",
|
"format": "time_series",
|
||||||
}),
|
}),
|
||||||
RefId: "A",
|
RefId: "A",
|
||||||
|
|||||||
@@ -2,9 +2,12 @@ package tsdb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/components/null"
|
||||||
|
|
||||||
"github.com/go-xorm/core"
|
"github.com/go-xorm/core"
|
||||||
"github.com/go-xorm/xorm"
|
"github.com/go-xorm/xorm"
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
@@ -185,3 +188,109 @@ func ConvertSqlTimeColumnToEpochMs(values RowValues, timeIndex int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConvertSqlValueColumnToFloat converts timeseries value column to float.
|
||||||
|
func ConvertSqlValueColumnToFloat(columnName string, columnValue interface{}) (null.Float, error) {
|
||||||
|
var value null.Float
|
||||||
|
|
||||||
|
switch typedValue := columnValue.(type) {
|
||||||
|
case int:
|
||||||
|
value = null.FloatFrom(float64(typedValue))
|
||||||
|
case *int:
|
||||||
|
if typedValue == nil {
|
||||||
|
value.Valid = false
|
||||||
|
} else {
|
||||||
|
value = null.FloatFrom(float64(*typedValue))
|
||||||
|
}
|
||||||
|
case int64:
|
||||||
|
value = null.FloatFrom(float64(typedValue))
|
||||||
|
case *int64:
|
||||||
|
if typedValue == nil {
|
||||||
|
value.Valid = false
|
||||||
|
} else {
|
||||||
|
value = null.FloatFrom(float64(*typedValue))
|
||||||
|
}
|
||||||
|
case int32:
|
||||||
|
value = null.FloatFrom(float64(typedValue))
|
||||||
|
case *int32:
|
||||||
|
if typedValue == nil {
|
||||||
|
value.Valid = false
|
||||||
|
} else {
|
||||||
|
value = null.FloatFrom(float64(*typedValue))
|
||||||
|
}
|
||||||
|
case int16:
|
||||||
|
value = null.FloatFrom(float64(typedValue))
|
||||||
|
case *int16:
|
||||||
|
if typedValue == nil {
|
||||||
|
value.Valid = false
|
||||||
|
} else {
|
||||||
|
value = null.FloatFrom(float64(*typedValue))
|
||||||
|
}
|
||||||
|
case int8:
|
||||||
|
value = null.FloatFrom(float64(typedValue))
|
||||||
|
case *int8:
|
||||||
|
if typedValue == nil {
|
||||||
|
value.Valid = false
|
||||||
|
} else {
|
||||||
|
value = null.FloatFrom(float64(*typedValue))
|
||||||
|
}
|
||||||
|
case uint:
|
||||||
|
value = null.FloatFrom(float64(typedValue))
|
||||||
|
case *uint:
|
||||||
|
if typedValue == nil {
|
||||||
|
value.Valid = false
|
||||||
|
} else {
|
||||||
|
value = null.FloatFrom(float64(*typedValue))
|
||||||
|
}
|
||||||
|
case uint64:
|
||||||
|
value = null.FloatFrom(float64(typedValue))
|
||||||
|
case *uint64:
|
||||||
|
if typedValue == nil {
|
||||||
|
value.Valid = false
|
||||||
|
} else {
|
||||||
|
value = null.FloatFrom(float64(*typedValue))
|
||||||
|
}
|
||||||
|
case uint32:
|
||||||
|
value = null.FloatFrom(float64(typedValue))
|
||||||
|
case *uint32:
|
||||||
|
if typedValue == nil {
|
||||||
|
value.Valid = false
|
||||||
|
} else {
|
||||||
|
value = null.FloatFrom(float64(*typedValue))
|
||||||
|
}
|
||||||
|
case uint16:
|
||||||
|
value = null.FloatFrom(float64(typedValue))
|
||||||
|
case *uint16:
|
||||||
|
if typedValue == nil {
|
||||||
|
value.Valid = false
|
||||||
|
} else {
|
||||||
|
value = null.FloatFrom(float64(*typedValue))
|
||||||
|
}
|
||||||
|
case uint8:
|
||||||
|
value = null.FloatFrom(float64(typedValue))
|
||||||
|
case *uint8:
|
||||||
|
if typedValue == nil {
|
||||||
|
value.Valid = false
|
||||||
|
} else {
|
||||||
|
value = null.FloatFrom(float64(*typedValue))
|
||||||
|
}
|
||||||
|
case float64:
|
||||||
|
value = null.FloatFrom(typedValue)
|
||||||
|
case *float64:
|
||||||
|
value = null.FloatFromPtr(typedValue)
|
||||||
|
case float32:
|
||||||
|
value = null.FloatFrom(float64(typedValue))
|
||||||
|
case *float32:
|
||||||
|
if typedValue == nil {
|
||||||
|
value.Valid = false
|
||||||
|
} else {
|
||||||
|
value = null.FloatFrom(float64(*typedValue))
|
||||||
|
}
|
||||||
|
case nil:
|
||||||
|
value.Valid = false
|
||||||
|
default:
|
||||||
|
return null.NewFloat(0, false), fmt.Errorf("Value column must have numeric datatype, column: %s type: %T value: %v", columnName, typedValue, typedValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package tsdb
|
package tsdb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/components/null"
|
||||||
|
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -156,8 +157,6 @@ func TestSqlEngine(t *testing.T) {
|
|||||||
So(fixtures[1].(float64), ShouldEqual, tMilliseconds)
|
So(fixtures[1].(float64), ShouldEqual, tMilliseconds)
|
||||||
So(fixtures[2].(float64), ShouldEqual, tMilliseconds)
|
So(fixtures[2].(float64), ShouldEqual, tMilliseconds)
|
||||||
So(fixtures[3].(float64), ShouldEqual, tMilliseconds)
|
So(fixtures[3].(float64), ShouldEqual, tMilliseconds)
|
||||||
fmt.Println(fixtures[4].(float64))
|
|
||||||
fmt.Println(tMilliseconds)
|
|
||||||
So(fixtures[4].(float64), ShouldEqual, tMilliseconds)
|
So(fixtures[4].(float64), ShouldEqual, tMilliseconds)
|
||||||
So(fixtures[5].(float64), ShouldEqual, tMilliseconds)
|
So(fixtures[5].(float64), ShouldEqual, tMilliseconds)
|
||||||
So(fixtures[6], ShouldBeNil)
|
So(fixtures[6], ShouldBeNil)
|
||||||
@@ -183,5 +182,101 @@ func TestSqlEngine(t *testing.T) {
|
|||||||
So(fixtures[2], ShouldBeNil)
|
So(fixtures[2], ShouldBeNil)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Convey("Given row with value columns", func() {
|
||||||
|
intValue := 1
|
||||||
|
int64Value := int64(1)
|
||||||
|
int32Value := int32(1)
|
||||||
|
int16Value := int16(1)
|
||||||
|
int8Value := int8(1)
|
||||||
|
float64Value := float64(1)
|
||||||
|
float32Value := float32(1)
|
||||||
|
uintValue := uint(1)
|
||||||
|
uint64Value := uint64(1)
|
||||||
|
uint32Value := uint32(1)
|
||||||
|
uint16Value := uint16(1)
|
||||||
|
uint8Value := uint8(1)
|
||||||
|
|
||||||
|
fixtures := make([]interface{}, 24)
|
||||||
|
fixtures[0] = intValue
|
||||||
|
fixtures[1] = &intValue
|
||||||
|
fixtures[2] = int64Value
|
||||||
|
fixtures[3] = &int64Value
|
||||||
|
fixtures[4] = int32Value
|
||||||
|
fixtures[5] = &int32Value
|
||||||
|
fixtures[6] = int16Value
|
||||||
|
fixtures[7] = &int16Value
|
||||||
|
fixtures[8] = int8Value
|
||||||
|
fixtures[9] = &int8Value
|
||||||
|
fixtures[10] = float64Value
|
||||||
|
fixtures[11] = &float64Value
|
||||||
|
fixtures[12] = float32Value
|
||||||
|
fixtures[13] = &float32Value
|
||||||
|
fixtures[14] = uintValue
|
||||||
|
fixtures[15] = &uintValue
|
||||||
|
fixtures[16] = uint64Value
|
||||||
|
fixtures[17] = &uint64Value
|
||||||
|
fixtures[18] = uint32Value
|
||||||
|
fixtures[19] = &uint32Value
|
||||||
|
fixtures[20] = uint16Value
|
||||||
|
fixtures[21] = &uint16Value
|
||||||
|
fixtures[22] = uint8Value
|
||||||
|
fixtures[23] = &uint8Value
|
||||||
|
|
||||||
|
var intNilPointer *int
|
||||||
|
var int64NilPointer *int64
|
||||||
|
var int32NilPointer *int32
|
||||||
|
var int16NilPointer *int16
|
||||||
|
var int8NilPointer *int8
|
||||||
|
var float64NilPointer *float64
|
||||||
|
var float32NilPointer *float32
|
||||||
|
var uintNilPointer *uint
|
||||||
|
var uint64NilPointer *uint64
|
||||||
|
var uint32NilPointer *uint32
|
||||||
|
var uint16NilPointer *uint16
|
||||||
|
var uint8NilPointer *uint8
|
||||||
|
|
||||||
|
nilPointerFixtures := make([]interface{}, 12)
|
||||||
|
nilPointerFixtures[0] = intNilPointer
|
||||||
|
nilPointerFixtures[1] = int64NilPointer
|
||||||
|
nilPointerFixtures[2] = int32NilPointer
|
||||||
|
nilPointerFixtures[3] = int16NilPointer
|
||||||
|
nilPointerFixtures[4] = int8NilPointer
|
||||||
|
nilPointerFixtures[5] = float64NilPointer
|
||||||
|
nilPointerFixtures[6] = float32NilPointer
|
||||||
|
nilPointerFixtures[7] = uintNilPointer
|
||||||
|
nilPointerFixtures[8] = uint64NilPointer
|
||||||
|
nilPointerFixtures[9] = uint32NilPointer
|
||||||
|
nilPointerFixtures[10] = uint16NilPointer
|
||||||
|
nilPointerFixtures[11] = uint8NilPointer
|
||||||
|
|
||||||
|
Convey("When converting values to float should return expected value", func() {
|
||||||
|
for _, f := range fixtures {
|
||||||
|
value, _ := ConvertSqlValueColumnToFloat("col", f)
|
||||||
|
|
||||||
|
if !value.Valid {
|
||||||
|
t.Fatalf("Failed to convert %T value, expected a valid float value", f)
|
||||||
|
}
|
||||||
|
|
||||||
|
if value.Float64 != null.FloatFrom(1).Float64 {
|
||||||
|
t.Fatalf("Failed to convert %T value, expected a float value of 1.000, but got %v", f, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("When converting nil pointer values to float should return expected value", func() {
|
||||||
|
for _, f := range nilPointerFixtures {
|
||||||
|
value, err := ConvertSqlValueColumnToFloat("col", f)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to convert %T value, expected a non nil error, but got %v", f, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if value.Valid {
|
||||||
|
t.Fatalf("Failed to convert %T value, expected an invalid float value", f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user