Skip to content

Commit e8cf32a

Browse files
authored
framestruct: Fix wrong conversion even if the first column contains null values (#601)
1 parent c41c9e1 commit e8cf32a

File tree

2 files changed

+66
-3
lines changed

2 files changed

+66
-3
lines changed

data/framestruct/converter.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ func (c *converter) convertStruct(field reflect.Value, fieldName string) error {
129129

130130
func (c *converter) convertSlice(s reflect.Value, prefix string) error {
131131
for i := 0; i < s.Len(); i++ {
132+
c.maxLen++
132133
v := s.Index(i)
133134
switch v.Kind() {
134135
case reflect.Map:
@@ -259,9 +260,6 @@ func (c *converter) convertField(v reflect.Value, fieldName string) (interface{}
259260

260261
func (c *converter) appendToField(name string, value interface{}) {
261262
c.fields[name].Append(value)
262-
if c.fields[name].Len() > c.maxLen {
263-
c.maxLen++
264-
}
265263
}
266264

267265
func (c *converter) createFrame(name string) *data.Frame {

data/framestruct/converter_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,71 @@ func TestSlices(t *testing.T) {
312312
require.Equal(t, "baz1", fromPointer(frame.Fields[2].At(1)))
313313
})
314314

315+
t.Run("it flattens a slice of maps that are different sizes even if col0 is not fully-defined", func(t *testing.T) {
316+
maps := []map[string]interface{}{
317+
{
318+
"Thing2": int32(36),
319+
},
320+
{
321+
"Thing1": "foo1",
322+
"Thing3": "baz1",
323+
},
324+
}
325+
326+
// result
327+
// | Thing1 | Thing2 | Thing3 |
328+
// |--------+--------+--------|
329+
// | nil | 36 | nil |
330+
// | foo1 | nil | baz1 |
331+
332+
frame, err := framestruct.ToDataFrame("results", maps)
333+
require.Nil(t, err)
334+
335+
require.Len(t, frame.Fields, 3)
336+
require.Equal(t, 2, frame.Fields[0].Len())
337+
require.Equal(t, 2, frame.Fields[1].Len())
338+
require.Equal(t, 2, frame.Fields[2].Len())
339+
340+
require.Nil(t, frame.Fields[0].At(0))
341+
require.Equal(t, "foo1", fromPointer(frame.Fields[0].At(1)))
342+
343+
require.Equal(t, int32(36), fromPointer(frame.Fields[1].At(0)))
344+
require.Nil(t, frame.Fields[1].At(1))
345+
346+
require.Nil(t, frame.Fields[2].At(0))
347+
require.Equal(t, "baz1", fromPointer(frame.Fields[2].At(1)))
348+
})
349+
350+
t.Run("it flattens a slice of maps that are different sizes even if col0 is not fully-defined (minimal)s", func(t *testing.T) {
351+
maps := []map[string]interface{}{
352+
{
353+
"b": true,
354+
},
355+
{
356+
"a": true,
357+
},
358+
}
359+
360+
// result
361+
// | a | b |
362+
// |------+------|
363+
// | nil | true |
364+
// | true | nil |
365+
366+
frame, err := framestruct.ToDataFrame("results", maps)
367+
require.Nil(t, err)
368+
369+
require.Len(t, frame.Fields, 2)
370+
require.Equal(t, 2, frame.Fields[0].Len())
371+
require.Equal(t, 2, frame.Fields[1].Len())
372+
373+
require.Nil(t, frame.Fields[0].At(0))
374+
require.Equal(t, true, fromPointer(frame.Fields[0].At(1)))
375+
376+
require.Equal(t, true, fromPointer(frame.Fields[1].At(0)))
377+
require.Nil(t, frame.Fields[1].At(1))
378+
})
379+
315380
t.Run("it flattens a slice of maps that contains nil values", func(t *testing.T) {
316381
// like the testcase above, just with "nil" instead of non-defined map keys.
317382
maps := []map[string]interface{}{

0 commit comments

Comments
 (0)