InfluxDB: Fix type assertion panics for interface conversion: interface {} is nil (#64556)

* fix type assertions

* fix chk

* add nil and fix tests

* add test for null bool and strings in the JSON response to be parsed as nil in Go

* reduce complexity

* reduce complexity

* reduce complexity again

* switch case for valTypes
This commit is contained in:
Brendan O'Handley 2023-03-10 11:11:00 -05:00 committed by GitHub
parent f76d634ac6
commit 50ef183208
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 16 deletions

View File

@ -23,6 +23,7 @@ func (rp *ResponseParser) Parse(buf io.ReadCloser, queries []Query) *backend.Que
resp := backend.NewQueryDataResponse()
response, jsonErr := parseJSON(buf)
if jsonErr != nil {
resp.Responses["A"] = backend.DataResponse{Error: jsonErr}
return resp
@ -46,10 +47,12 @@ func (rp *ResponseParser) Parse(buf io.ReadCloser, queries []Query) *backend.Que
func parseJSON(buf io.ReadCloser) (Response, error) {
var response Response
dec := json.NewDecoder(buf)
dec.UseNumber()
err := dec.Decode(&response)
return response, err
}
@ -89,8 +92,8 @@ func transformRows(rows []Row, query Query) data.Frames {
var timeArray []time.Time
var floatArray []*float64
var stringArray []string
var boolArray []bool
var stringArray []*string
var boolArray []*bool
valType := typeof(row.Values, colIndex)
name := formatFrameName(row, column, query)
@ -99,16 +102,27 @@ func transformRows(rows []Row, query Query) data.Frames {
// we only add this row if the timestamp is valid
if timestampErr == nil {
timeArray = append(timeArray, timestamp)
if valType == "string" {
value := valuePair[colIndex].(string)
stringArray = append(stringArray, value)
} else if valType == "json.Number" {
switch valType {
case "string":
{
value, chk := valuePair[colIndex].(string)
if chk {
stringArray = append(stringArray, &value)
} else {
stringArray = append(stringArray, nil)
}
}
case "json.Number":
value := parseNumber(valuePair[colIndex])
floatArray = append(floatArray, value)
} else if valType == "bool" {
value := valuePair[colIndex].(bool)
boolArray = append(boolArray, value)
} else if valType == "null" {
case "bool":
value, chk := valuePair[colIndex].(bool)
if chk {
boolArray = append(boolArray, &value)
} else {
boolArray = append(boolArray, nil)
}
case "null":
floatArray = append(floatArray, nil)
}
}

View File

@ -41,7 +41,7 @@ func TestInfluxdbResponseParser(t *testing.T) {
require.Error(t, result.Responses["A"].Error)
})
t.Run("Influxdb response parser should parse everything normally", func(t *testing.T) {
t.Run("Influxdb response parser should parse everything normally including nil bools and nil strings", func(t *testing.T) {
parser := &ResponseParser{}
response := `
@ -54,7 +54,7 @@ func TestInfluxdbResponseParser(t *testing.T) {
"columns": ["time","mean","path","isActive"],
"tags": {"datacenter": "America"},
"values": [
[111,222,"/usr/path",true],
[111,222,null,null],
[111,222,"/usr/path",false],
[111,null,"/usr/path",true]
]
@ -84,8 +84,9 @@ func TestInfluxdbResponseParser(t *testing.T) {
)
floatFrame.Meta = &data.FrameMeta{ExecutedQueryString: "Test raw query"}
stringField := data.NewField("value", labels, []string{
"/usr/path", "/usr/path", "/usr/path",
string_test := "/usr/path"
stringField := data.NewField("value", labels, []*string{
nil, &string_test, &string_test,
})
stringField.Config = &data.FieldConfig{DisplayNameFromDS: "cpu.path { datacenter: America }"}
stringFrame := data.NewFrame("cpu.path { datacenter: America }",
@ -99,8 +100,10 @@ func TestInfluxdbResponseParser(t *testing.T) {
)
stringFrame.Meta = &data.FrameMeta{ExecutedQueryString: "Test raw query"}
boolField := data.NewField("value", labels, []bool{
true, false, true,
bool_true := true
bool_false := false
boolField := data.NewField("value", labels, []*bool{
nil, &bool_false, &bool_true,
})
boolField.Config = &data.FieldConfig{DisplayNameFromDS: "cpu.isActive { datacenter: America }"}
boolFrame := data.NewFrame("cpu.isActive { datacenter: America }",