Skip to content

Commit

Permalink
[MYSQL] convert explicitely smallint and tinyint (grafana#35897)
Browse files Browse the repository at this point in the history
* [MYSQL] convert explicitely smallint and tinyint

* clean up code

* fix comments
  • Loading branch information
ying-jeanne authored and bryanuribe committed Aug 6, 2021
1 parent 66af99c commit ded9450
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 2 deletions.
38 changes: 38 additions & 0 deletions pkg/tsdb/mysql/mysql.go
Expand Up @@ -265,6 +265,44 @@ func (t *mysqlQueryResultTransformer) GetConverterList() []sqlutil.StringConvert
},
},
},
{
Name: "handle TINYINT",
InputScanKind: reflect.Struct,
InputTypeName: "TINYINT",
ConversionFunc: func(in *string) (*string, error) { return in, nil },
Replacer: &sqlutil.StringFieldReplacer{
OutputFieldType: data.FieldTypeNullableInt64,
ReplaceFunc: func(in *string) (interface{}, error) {
if in == nil {
return nil, nil
}
v, err := strconv.ParseInt(*in, 10, 64)
if err != nil {
return nil, err
}
return &v, nil
},
},
},
{
Name: "handle SMALLINT",
InputScanKind: reflect.Struct,
InputTypeName: "SMALLINT",
ConversionFunc: func(in *string) (*string, error) { return in, nil },
Replacer: &sqlutil.StringFieldReplacer{
OutputFieldType: data.FieldTypeNullableInt64,
ReplaceFunc: func(in *string) (interface{}, error) {
if in == nil {
return nil, nil
}
v, err := strconv.ParseInt(*in, 10, 64)
if err != nil {
return nil, err
}
return &v, nil
},
},
},
{
Name: "handle INT",
InputScanKind: reflect.Struct,
Expand Down
58 changes: 56 additions & 2 deletions pkg/tsdb/mysql/mysql_test.go
Expand Up @@ -146,11 +146,11 @@ func TestMySQL(t *testing.T) {
require.Len(t, frames, 1)
frameOne := frames[0]
require.Len(t, frames[0].Fields, 31)
require.Equal(t, int8(1), frameOne.Fields[0].At(0).(int8))
require.Equal(t, int64(1), *(frameOne.Fields[0].At(0).(*int64)))
require.Equal(t, "abc", *frameOne.Fields[1].At(0).(*string))
require.Equal(t, "def", *frameOne.Fields[2].At(0).(*string))
require.Equal(t, int32(1), frameOne.Fields[3].At(0).(int32))
require.Equal(t, int16(10), frameOne.Fields[4].At(0).(int16))
require.Equal(t, int64(10), *(frameOne.Fields[4].At(0).(*int64)))
require.Equal(t, int64(100), *(frameOne.Fields[5].At(0).(*int64)))
require.Equal(t, int64(1420070400), *(frameOne.Fields[6].At(0).(*int64)))
require.Equal(t, 1.11, *frameOne.Fields[7].At(0).(*float64))
Expand Down Expand Up @@ -422,6 +422,8 @@ func TestMySQL(t *testing.T) {
Measurement string
ValueOne int64 `xorm:"integer 'valueOne'"`
ValueTwo int64 `xorm:"integer 'valueTwo'"`
ValueThree int64 `xorm:"tinyint(1) null 'valueThree'"`
ValueFour int64 `xorm:"smallint(1) null 'valueFour'"`
}

exists, err := sess.IsTableExist(metric_values{})
Expand Down Expand Up @@ -465,11 +467,15 @@ func TestMySQL(t *testing.T) {
Measurement: "Metric A",
ValueOne: rnd(0, 100),
ValueTwo: rnd(0, 100),
ValueThree: int64(6),
ValueFour: int64(8),
}
second := first
second.Measurement = "Metric B"
second.ValueOne = rnd(0, 100)
second.ValueTwo = rnd(0, 100)
second.ValueThree = int64(6)
second.ValueFour = int64(8)

series = append(series, &first)
series = append(series, &second)
Expand Down Expand Up @@ -502,6 +508,54 @@ func TestMySQL(t *testing.T) {
require.True(t, tInitial.Equal(*frames[0].Fields[0].At(0).(*time.Time)))
})

t.Run("When doing a metric query using tinyint as value column should return metric with value in *float64", func(t *testing.T) {
query := plugins.DataQuery{
Queries: []plugins.DataSubQuery{
{
Model: simplejson.NewFromAny(map[string]interface{}{
"rawSql": `SELECT time, valueThree FROM metric_values ORDER BY time LIMIT 1`,
"format": "time_series",
}),
RefID: "A",
},
},
}

resp, err := exe.DataQuery(context.Background(), nil, query)
require.NoError(t, err)
queryResult := resp.Results["A"]
require.NoError(t, queryResult.Error)

frames, err := queryResult.Dataframes.Decoded()
require.NoError(t, err)
require.Len(t, frames, 1)
require.Equal(t, float64(6), *frames[0].Fields[1].At(0).(*float64))
})

t.Run("When doing a metric query using smallint as value column should return metric with value in *float64", func(t *testing.T) {
query := plugins.DataQuery{
Queries: []plugins.DataSubQuery{
{
Model: simplejson.NewFromAny(map[string]interface{}{
"rawSql": `SELECT time, valueFour FROM metric_values ORDER BY time LIMIT 1`,
"format": "time_series",
}),
RefID: "A",
},
},
}

resp, err := exe.DataQuery(context.Background(), nil, query)
require.NoError(t, err)
queryResult := resp.Results["A"]
require.NoError(t, queryResult.Error)

frames, err := queryResult.Dataframes.Decoded()
require.NoError(t, err)
require.Len(t, frames, 1)
require.Equal(t, float64(8), *frames[0].Fields[1].At(0).(*float64))
})

t.Run("When doing a metric query using time (nullable) as time column should return metric with time in time.Time", func(t *testing.T) {
query := plugins.DataQuery{
Queries: []plugins.DataSubQuery{
Expand Down

0 comments on commit ded9450

Please sign in to comment.