Commit f0f8006d by Marcus Efraimsson

mssql: support money, smallmoney and decimal data types

parent a6e4ac54
...@@ -5,17 +5,19 @@ import ( ...@@ -5,17 +5,19 @@ import (
"context" "context"
"database/sql" "database/sql"
"fmt" "fmt"
"strconv"
"strings" "strings"
"time" "time"
"math"
_ "github.com/denisenkom/go-mssqldb" _ "github.com/denisenkom/go-mssqldb"
"github.com/go-xorm/core" "github.com/go-xorm/core"
"github.com/grafana/grafana/pkg/components/null" "github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/tsdb" "github.com/grafana/grafana/pkg/tsdb"
"math"
) )
type MssqlQueryEndpoint struct { type MssqlQueryEndpoint struct {
...@@ -133,6 +135,24 @@ func (e MssqlQueryEndpoint) getTypedRowData(types []*sql.ColumnType, rows *core. ...@@ -133,6 +135,24 @@ func (e MssqlQueryEndpoint) getTypedRowData(types []*sql.ColumnType, rows *core.
return nil, err return nil, err
} }
// convert types not handled by denisenkom/go-mssqldb
// unhandled types are returned as []byte
for i := 0; i < len(types); i++ {
if value, ok := values[i].([]byte); ok == true {
switch types[i].DatabaseTypeName() {
case "MONEY", "SMALLMONEY", "DECIMAL":
if v, err := strconv.ParseFloat(string(value), 64); err == nil {
values[i] = v
} else {
e.log.Debug("Rows", "Error converting numeric to float", value)
}
default:
e.log.Debug("Rows", "Unknown database type", types[i].DatabaseTypeName(), "value", value)
values[i] = string(value)
}
}
}
return values, nil return values, nil
} }
......
...@@ -34,6 +34,8 @@ func TestMSSQL(t *testing.T) { ...@@ -34,6 +34,8 @@ func TestMSSQL(t *testing.T) {
sess := x.NewSession() sess := x.NewSession()
defer sess.Close() defer sess.Close()
fromStart := time.Date(2018, 3, 15, 13, 0, 0, 0, time.UTC)
Convey("Given a table with different native data types", func() { Convey("Given a table with different native data types", func() {
sql := ` sql := `
IF OBJECT_ID('dbo.[mssql_types]', 'U') IS NOT NULL IF OBJECT_ID('dbo.[mssql_types]', 'U') IS NOT NULL
...@@ -41,14 +43,15 @@ func TestMSSQL(t *testing.T) { ...@@ -41,14 +43,15 @@ func TestMSSQL(t *testing.T) {
CREATE TABLE [mssql_types] ( CREATE TABLE [mssql_types] (
c_bit bit, c_bit bit,
c_tinyint tinyint, c_tinyint tinyint,
c_smallint smallint, c_smallint smallint,
c_int int, c_int int,
c_bigint bigint, c_bigint bigint,
c_money money, c_money money,
c_smallmoney smallmoney, c_smallmoney smallmoney,
c_numeric numeric(10,5), c_numeric numeric(10,5),
c_real real, c_real real,
c_decimal decimal(10,2), c_decimal decimal(10,2),
c_float float, c_float float,
...@@ -113,17 +116,17 @@ func TestMSSQL(t *testing.T) { ...@@ -113,17 +116,17 @@ func TestMSSQL(t *testing.T) {
column := queryResult.Tables[0].Rows[0] column := queryResult.Tables[0].Rows[0]
So(column[0].(bool), ShouldEqual, true) So(column[0].(bool), ShouldEqual, true)
So(column[1].(int64), ShouldEqual, 5) So(column[1].(int64), ShouldEqual, 5)
So(column[2].(int64), ShouldEqual, 20020) So(column[2].(int64), ShouldEqual, 20020)
So(column[3].(int64), ShouldEqual, 980300) So(column[3].(int64), ShouldEqual, 980300)
So(column[4].(int64), ShouldEqual, 1420070400) So(column[4].(int64), ShouldEqual, 1420070400)
// So(column[5].(float64), ShouldEqual, 20000.15)
// So(column[6].(float64), ShouldEqual, 2.15)
//So(column[7].(float64), ShouldEqual, 12345.12)
So(column[8].(float64), ShouldEqual, 1.1100000143051147) // MSSQL dose not have precision for "real" datatype So(column[5].(float64), ShouldEqual, 20000.15)
// fix me: MSSQL driver puts the decimal inside an array of chars. and the test fails despite the values are correct. So(column[6].(float64), ShouldEqual, 2.15)
//So(column[9].([]uint8), ShouldEqual, []uint8{'2', '.', '2', '2'}) So(column[7].(float64), ShouldEqual, 12345.12)
So(column[8].(float64), ShouldEqual, 1.1100000143051147)
So(column[9].(float64), ShouldEqual, 2.22)
So(column[10].(float64), ShouldEqual, 3.33) So(column[10].(float64), ShouldEqual, 3.33)
So(column[11].(string), ShouldEqual, "char10 ") So(column[11].(string), ShouldEqual, "char10 ")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment