Skip to content

Commit 05f97c9

Browse files
authored
BUGFIX (dataframes): support nil values in maps (#602)
While the code supports undefined map keys (converting them to `nil` as expected), it crashes when the map value is `nil`. This change handles `nil` map values in the same way as undefined map keys.
1 parent 20cdc15 commit 05f97c9

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

data/framestruct/converter.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ func (c *converter) convertMap(toConvert interface{}, tags, prefix string) error
196196

197197
for _, name := range sortedKeys(m) {
198198
value := m[name]
199+
if value == nil {
200+
// skip nil values (as they will lead to "nil" values later on anyways);
201+
// and the reflection code below crashes on nil.
202+
continue
203+
}
199204
fieldName := c.fieldName(name, tags, prefix)
200205
v := c.ensureValue(reflect.ValueOf(value))
201206
if err := c.handleValue(v, "", fieldName); err != nil {

data/framestruct/converter_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,45 @@ func TestSlices(t *testing.T) {
311311
require.Nil(t, frame.Fields[2].At(0))
312312
require.Equal(t, "baz1", fromPointer(frame.Fields[2].At(1)))
313313
})
314+
315+
t.Run("it flattens a slice of maps that contains nil values", func(t *testing.T) {
316+
// like the testcase above, just with "nil" instead of non-defined map keys.
317+
maps := []map[string]interface{}{
318+
{
319+
"Thing1": "foo",
320+
"Thing2": int32(36),
321+
"Thing3": nil,
322+
},
323+
{
324+
"Thing1": "foo1",
325+
"Thing2": nil,
326+
"Thing3": "baz1",
327+
},
328+
}
329+
330+
// result
331+
// | Thing1 | Thing2 | Thing3 |
332+
// |--------+--------+--------|
333+
// | foo | 36 | nil |
334+
// | foo1 | nil | baz1 |
335+
336+
frame, err := framestruct.ToDataFrame("results", maps)
337+
require.Nil(t, err)
338+
339+
require.Len(t, frame.Fields, 3)
340+
require.Equal(t, 2, frame.Fields[0].Len())
341+
require.Equal(t, 2, frame.Fields[1].Len())
342+
require.Equal(t, 2, frame.Fields[2].Len())
343+
344+
require.Equal(t, "foo", fromPointer(frame.Fields[0].At(0)))
345+
require.Equal(t, "foo1", fromPointer(frame.Fields[0].At(1)))
346+
347+
require.Equal(t, int32(36), fromPointer(frame.Fields[1].At(0)))
348+
require.Nil(t, frame.Fields[1].At(1))
349+
350+
require.Nil(t, frame.Fields[2].At(0))
351+
require.Equal(t, "baz1", fromPointer(frame.Fields[2].At(1)))
352+
})
314353
}
315354

316355
func TestMaps(t *testing.T) {

0 commit comments

Comments
 (0)