Skip to content

Commit

Permalink
fix: dynamic frame panic (#958)
Browse files Browse the repository at this point in the history
fix: dynamic frame panic
---------

Co-authored-by: Andres Martinez Gotor <andres.martinez@grafana.com>
Co-authored-by: Zoltán Bedi <zoltan.bedi@gmail.com>
  • Loading branch information
3 people authored Apr 29, 2024
1 parent ceadf1f commit 0f6f235
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 4 deletions.
11 changes: 8 additions & 3 deletions data/sqlutil/dynamic_frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ import (

const STRING = "string"

func isDynamic(converters []Converter) bool {
// removeDynamicConverter filters out the dynamic converter. It is not a valid converter.
func removeDynamicConverter(converters []Converter) (bool, []Converter) {
var filtered []Converter
var isDynamic bool
for _, conv := range converters {
if conv.Dynamic {
return true
isDynamic = true
} else {
filtered = append(filtered, conv)
}
}
return false
return isDynamic, filtered
}

func findDataTypes(rows Rows, rowLimit int64, types []*sql.ColumnType) ([]Field, [][]interface{}, error) {
Expand Down
40 changes: 40 additions & 0 deletions data/sqlutil/dynamic_frame_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func TestDynamicFrame(t *testing.T) {
itr: mock,
}

_, converters = removeDynamicConverter(converters)
frame, err := frameDynamic(rows, 100, types, converters)
assert.Nil(t, err)
assert.NotNil(t, frame)
Expand Down Expand Up @@ -64,3 +65,42 @@ func (rs *MockRows) Scan(dest ...interface{}) error {
}
return nil
}

func TestDynamicFrameShouldNotPanic(t *testing.T) {
kind := &sql.ColumnType{}
types := []*sql.ColumnType{}
types = append(types, kind)
converters := []Converter{dynamic()}
data := [][]interface{}{}
mockRow := []interface{}{}
val := string("foo")
mockRow = append(mockRow, val)
data = append(data, mockRow)
mock := &MockRows{
data: data,
index: -1,
}
rows := Rows{
itr: mock,
}

_, converters = removeDynamicConverter(converters)
frame, err := frameDynamic(rows, 100, types, converters)
assert.Nil(t, err)
assert.NotNil(t, frame)

assert.Equal(t, 1, frame.Rows())

actual := frame.Fields[0].At(0).(*string)
assert.Equal(t, val, *actual)
}

// dynamic is the converter that uses the results to determine data types
func dynamic() Converter {
kind := "dynamic"
return Converter{
Name: kind,
InputTypeName: kind,
Dynamic: true,
}
}
4 changes: 3 additions & 1 deletion data/sqlutil/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ func FrameFromRows(rows *sql.Rows, rowLimit int64, converters ...Converter) (*da
return nil, err
}

if isDynamic(converters) {
// If there is a dynamic converter, we need to use the dynamic framer
// and remove the dynamic converter from the list of converters ( it is not valid, just a flag )
if isDynamic, converters := removeDynamicConverter(converters); isDynamic {
rows := Rows{itr: rows}
return frameDynamic(rows, rowLimit, types, converters)
}
Expand Down

0 comments on commit 0f6f235

Please sign in to comment.