This is an automated email from the ASF dual-hosted git repository.

zeroshade pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/master by this push:
     new 6655c86  ARROW-8452: [Go] support proper nested nullable flags
6655c86 is described below

commit 6655c86760b90bf1df953ffbd72b360462f20688
Author: Matthew Topol <[email protected]>
AuthorDate: Tue Oct 12 11:30:32 2021 -0400

    ARROW-8452: [Go] support proper nested nullable flags
    
    Closes #11314 from zeroshade/arrow-8452-nested-nullable
    
    Lead-authored-by: Matthew Topol <[email protected]>
    Co-authored-by: Matt Topol <[email protected]>
    Signed-off-by: Matthew Topol <[email protected]>
---
 go/arrow/cdata/cdata.go                |  2 +
 go/arrow/cdata/cdata_exports.go        |  6 +--
 go/arrow/cdata/cdata_fulltest.c        |  3 +-
 go/arrow/cdata/cdata_test.go           | 15 +++---
 go/arrow/cdata/cdata_test_framework.go | 15 ++++--
 go/arrow/compare.go                    | 10 +++-
 go/arrow/datatype_nested.go            | 83 ++++++++++++++++++++++++++++++----
 go/arrow/datatype_nested_test.go       |  4 +-
 go/arrow/example_test.go               |  5 +-
 go/arrow/internal/arrjson/arrjson.go   | 10 ++--
 go/arrow/ipc/cmd/arrow-ls/main_test.go |  8 ++--
 go/arrow/ipc/metadata.go               | 12 +++--
 12 files changed, 133 insertions(+), 40 deletions(-)

diff --git a/go/arrow/cdata/cdata.go b/go/arrow/cdata/cdata.go
index 2f108e2..a8d1a5d 100644
--- a/go/arrow/cdata/cdata.go
+++ b/go/arrow/cdata/cdata.go
@@ -224,6 +224,7 @@ func importSchema(schema *CArrowSchema) (ret arrow.Field, 
err error) {
                switch f[1] {
                case 'l': // list
                        dt = arrow.ListOf(childFields[0].Type)
+                       dt.(*arrow.ListType).NullableElem = 
childFields[0].Nullable
                case 'w': // fixed size list is w:# where # is the list size.
                        listSize, err := strconv.Atoi(strings.Split(f, ":")[1])
                        if err != nil {
@@ -231,6 +232,7 @@ func importSchema(schema *CArrowSchema) (ret arrow.Field, 
err error) {
                        }
 
                        dt = arrow.FixedSizeListOf(int32(listSize), 
childFields[0].Type)
+                       dt.(*arrow.FixedSizeListType).NullableElem = 
childFields[0].Nullable
                case 's': // struct
                        dt = arrow.StructOf(childFields...)
                case 'm': // map type is basically a list of structs.
diff --git a/go/arrow/cdata/cdata_exports.go b/go/arrow/cdata/cdata_exports.go
index 0143725..8565952 100644
--- a/go/arrow/cdata/cdata_exports.go
+++ b/go/arrow/cdata/cdata_exports.go
@@ -233,7 +233,7 @@ func (exp *schemaExporter) export(field arrow.Field) {
        switch dt := field.Type.(type) {
        case *arrow.ListType:
                exp.children = make([]schemaExporter, 1)
-               exp.children[0].export(arrow.Field{Name: "item", Type: 
dt.Elem(), Nullable: field.Nullable})
+               exp.children[0].export(dt.ElemField())
        case *arrow.StructType:
                exp.children = make([]schemaExporter, len(dt.Fields()))
                for i, f := range dt.Fields() {
@@ -241,10 +241,10 @@ func (exp *schemaExporter) export(field arrow.Field) {
                }
        case *arrow.MapType:
                exp.children = make([]schemaExporter, 1)
-               exp.children[0].export(arrow.Field{Name: "keyvalue", Type: 
dt.ValueType(), Nullable: field.Nullable})
+               exp.children[0].export(dt.ValueField())
        case *arrow.FixedSizeListType:
                exp.children = make([]schemaExporter, 1)
-               exp.children[0].export(arrow.Field{Name: "item", Type: 
dt.Elem(), Nullable: field.Nullable})
+               exp.children[0].export(dt.ElemField())
        }
 
        exp.exportMeta(&field.Metadata)
diff --git a/go/arrow/cdata/cdata_fulltest.c b/go/arrow/cdata/cdata_fulltest.c
index 5c4ca49..06ea477 100644
--- a/go/arrow/cdata/cdata_fulltest.c
+++ b/go/arrow/cdata/cdata_fulltest.c
@@ -151,7 +151,7 @@ void free_malloced_schemas(struct ArrowSchema** schemas) {
     free(schemas);
 }
 
-struct ArrowSchema** test_lists(const char** fmts, const char** names, const 
int n) {
+struct ArrowSchema** test_lists(const char** fmts, const char** names, const 
int* nullflags, const int n) {
     struct ArrowSchema** schemas = malloc(sizeof(struct ArrowSchema*)*n);
     for (int i = 0; i < n; ++i) {
         schemas[i] = malloc(sizeof(struct ArrowSchema));
@@ -168,6 +168,7 @@ struct ArrowSchema** test_lists(const char** fmts, const 
char** names, const int
         if (i != 0) {
             schemas[i-1]->n_children = 1;
             schemas[i-1]->children = &schemas[i];
+            schemas[i]->flags = nullflags[i-1];
         }
     }    
     return schemas;
diff --git a/go/arrow/cdata/cdata_test.go b/go/arrow/cdata/cdata_test.go
index d29bf04..47cd334 100644
--- a/go/arrow/cdata/cdata_test.go
+++ b/go/arrow/cdata/cdata_test.go
@@ -175,18 +175,19 @@ func TestImportTemporalSchema(t *testing.T) {
 
 func TestListSchemas(t *testing.T) {
        tests := []struct {
-               typ   arrow.DataType
-               fmts  []string
-               names []string
+               typ    arrow.DataType
+               fmts   []string
+               names  []string
+               isnull []bool
        }{
-               {arrow.ListOf(arrow.PrimitiveTypes.Int8), []string{"+l", "c"}, 
[]string{"", "item"}},
-               {arrow.FixedSizeListOf(2, arrow.PrimitiveTypes.Int64), 
[]string{"+w:2", "l"}, []string{"", "item"}},
-               {arrow.ListOf(arrow.ListOf(arrow.PrimitiveTypes.Int32)), 
[]string{"+l", "+l", "i"}, []string{"", "item", "item"}},
+               {arrow.ListOf(arrow.PrimitiveTypes.Int8), []string{"+l", "c"}, 
[]string{"", "item"}, []bool{true}},
+               {arrow.FixedSizeListOfNonNullable(2, 
arrow.PrimitiveTypes.Int64), []string{"+w:2", "l"}, []string{"", "item"}, 
[]bool{false}},
+               
{arrow.ListOfNonNullable(arrow.ListOf(arrow.PrimitiveTypes.Int32)), 
[]string{"+l", "+l", "i"}, []string{"", "item", "item"}, []bool{false, true}},
        }
 
        for _, tt := range tests {
                t.Run(tt.typ.Name(), func(t *testing.T) {
-                       sc := testNested(tt.fmts, tt.names)
+                       sc := testNested(tt.fmts, tt.names, tt.isnull)
                        defer freeMallocedSchemas(sc)
 
                        top := (*[1]*CArrowSchema)(unsafe.Pointer(sc))[0]
diff --git a/go/arrow/cdata/cdata_test_framework.go 
b/go/arrow/cdata/cdata_test_framework.go
index 68dbeb0..048d950 100644
--- a/go/arrow/cdata/cdata_test_framework.go
+++ b/go/arrow/cdata/cdata_test_framework.go
@@ -44,7 +44,7 @@ package cdata
 // int test1_is_released();
 // void test_primitive(struct ArrowSchema* schema, const char* fmt);
 // void free_malloced_schemas(struct ArrowSchema**);
-// struct ArrowSchema** test_lists(const char** fmts, const char** names, 
const int n);
+// struct ArrowSchema** test_lists(const char** fmts, const char** names, 
const int* nullflags, const int n);
 // struct ArrowSchema** test_struct(const char** fmts, const char** names, 
int64_t* flags, const int n);
 // struct ArrowSchema** test_map(const char** fmts, const char** names, 
int64_t* flags, const int n);
 // struct ArrowSchema** test_schema(const char** fmts, const char** names, 
int64_t* flags, const int n);
@@ -117,19 +117,28 @@ func freeMallocedSchemas(schemas **CArrowSchema) {
        C.free_malloced_schemas(schemas)
 }
 
-func testNested(fmts, names []string) **CArrowSchema {
+func testNested(fmts, names []string, isnull []bool) **CArrowSchema {
        if len(fmts) != len(names) {
                panic("testing nested lists must have same size fmts and names")
        }
        cfmts := make([]*C.char, len(fmts))
        cnames := make([]*C.char, len(names))
+       nulls := make([]C.int, len(isnull))
 
        for i := range fmts {
                cfmts[i] = C.CString(fmts[i])
                cnames[i] = C.CString(names[i])
        }
 
-       return C.test_lists((**C.char)(unsafe.Pointer(&cfmts[0])), 
(**C.char)(unsafe.Pointer(&cnames[0])), C.int(len(fmts)))
+       for i, v := range isnull {
+               if v {
+                       nulls[i] = C.ARROW_FLAG_NULLABLE
+               } else {
+                       nulls[i] = 0
+               }
+       }
+
+       return C.test_lists((**C.char)(unsafe.Pointer(&cfmts[0])), 
(**C.char)(unsafe.Pointer(&cnames[0])), (*C.int)(unsafe.Pointer(&nulls[0])), 
C.int(len(fmts)))
 }
 
 func testStruct(fmts, names []string, flags []int64) **CArrowSchema {
diff --git a/go/arrow/compare.go b/go/arrow/compare.go
index 5acfd94..afb4a3d 100644
--- a/go/arrow/compare.go
+++ b/go/arrow/compare.go
@@ -61,7 +61,15 @@ func TypeEqual(left, right DataType, opts 
...TypeEqualOption) bool {
                if cfg.metadata {
                        return l.Meta.Equal(right.(*ListType).Meta)
                }
-               return true
+               return l.NullableElem == right.(*ListType).NullableElem
+       case *FixedSizeListType:
+               if !TypeEqual(l.Elem(), right.(*FixedSizeListType).Elem(), 
opts...) {
+                       return false
+               }
+               if cfg.metadata {
+                       return l.Meta.Equal(right.(*FixedSizeListType).Meta)
+               }
+               return l.n == right.(*FixedSizeListType).n && l.NullableElem == 
right.(*FixedSizeListType).NullableElem
        case *StructType:
                r := right.(*StructType)
                switch {
diff --git a/go/arrow/datatype_nested.go b/go/arrow/datatype_nested.go
index 993950a..63dabf4 100644
--- a/go/arrow/datatype_nested.go
+++ b/go/arrow/datatype_nested.go
@@ -24,24 +24,41 @@ import (
 // ListType describes a nested type in which each array slot contains
 // a variable-size sequence of values, all having the same relative type.
 type ListType struct {
-       elem DataType // DataType of the list's elements
-       Meta Metadata
+       elem         DataType // DataType of the list's elements
+       Meta         Metadata
+       NullableElem bool
 }
 
 // ListOf returns the list type with element type t.
 // For example, if t represents int32, ListOf(t) represents []int32.
 //
-// ListOf panics if t is nil or invalid.
+// ListOf panics if t is nil or invalid. NullableElem defaults to true
 func ListOf(t DataType) *ListType {
        if t == nil {
                panic("arrow: nil DataType")
        }
-       return &ListType{elem: t}
+       return &ListType{elem: t, NullableElem: true}
+}
+
+// ListOfNonNullable is like ListOf but NullableElem defaults to false, 
indicating
+// that the child type should be marked as non-nullable.
+func ListOfNonNullable(t DataType) *ListType {
+       if t == nil {
+               panic("arrow: nil DataType")
+       }
+       return &ListType{elem: t, NullableElem: false}
+}
+
+func (*ListType) ID() Type     { return LIST }
+func (*ListType) Name() string { return "list" }
+
+func (t *ListType) String() string {
+       if t.NullableElem {
+               return fmt.Sprintf("list<item: %v, nullable>", t.elem)
+       }
+       return fmt.Sprintf("list<item: %v>", t.elem)
 }
 
-func (*ListType) ID() Type         { return LIST }
-func (*ListType) Name() string     { return "list" }
-func (t *ListType) String() string { return fmt.Sprintf("list<item: %v>", 
t.elem) }
 func (t *ListType) Fingerprint() string {
        child := t.elem.Fingerprint()
        if len(child) > 0 {
@@ -53,11 +70,22 @@ func (t *ListType) Fingerprint() string {
 // Elem returns the ListType's element type.
 func (t *ListType) Elem() DataType { return t.elem }
 
+func (t *ListType) ElemField() Field {
+       return Field{
+               Name:     "item",
+               Type:     t.elem,
+               Metadata: t.Meta,
+               Nullable: t.NullableElem,
+       }
+}
+
 // FixedSizeListType describes a nested type in which each array slot contains
 // a fixed-size sequence of values, all having the same relative type.
 type FixedSizeListType struct {
-       n    int32    // number of elements in the list
-       elem DataType // DataType of the list's elements
+       n            int32    // number of elements in the list
+       elem         DataType // DataType of the list's elements
+       Meta         Metadata
+       NullableElem bool
 }
 
 // FixedSizeListOf returns the list type with element type t.
@@ -65,6 +93,7 @@ type FixedSizeListType struct {
 //
 // FixedSizeListOf panics if t is nil or invalid.
 // FixedSizeListOf panics if n is <= 0.
+// NullableElem defaults to true
 func FixedSizeListOf(n int32, t DataType) *FixedSizeListType {
        if t == nil {
                panic("arrow: nil DataType")
@@ -72,12 +101,27 @@ func FixedSizeListOf(n int32, t DataType) 
*FixedSizeListType {
        if n <= 0 {
                panic("arrow: invalid size")
        }
-       return &FixedSizeListType{elem: t, n: n}
+       return &FixedSizeListType{elem: t, n: n, NullableElem: true}
+}
+
+// FixedSizeListOfNonNullable is like FixedSizeListOf but NullableElem 
defaults to false
+// indicating that the child type should be marked as non-nullable.
+func FixedSizeListOfNonNullable(n int32, t DataType) *FixedSizeListType {
+       if t == nil {
+               panic("arrow: nil DataType")
+       }
+       if n <= 0 {
+               panic("arrow: invalid size")
+       }
+       return &FixedSizeListType{elem: t, n: n, NullableElem: false}
 }
 
 func (*FixedSizeListType) ID() Type     { return FIXED_SIZE_LIST }
 func (*FixedSizeListType) Name() string { return "fixed_size_list" }
 func (t *FixedSizeListType) String() string {
+       if t.NullableElem {
+               return fmt.Sprintf("fixed_size_list<item: %v, nullable>[%d]", 
t.elem, t.n)
+       }
        return fmt.Sprintf("fixed_size_list<item: %v>[%d]", t.elem, t.n)
 }
 
@@ -87,6 +131,15 @@ func (t *FixedSizeListType) Elem() DataType { return t.elem 
}
 // Len returns the FixedSizeListType's size.
 func (t *FixedSizeListType) Len() int32 { return t.n }
 
+func (t *FixedSizeListType) ElemField() Field {
+       return Field{
+               Name:     "item",
+               Type:     t.elem,
+               Metadata: t.Meta,
+               Nullable: t.NullableElem,
+       }
+}
+
 func (t *FixedSizeListType) Fingerprint() string {
        child := t.elem.Fingerprint()
        if len(child) > 0 {
@@ -217,6 +270,16 @@ func (t *MapType) KeyType() DataType      { return 
t.KeyField().Type }
 func (t *MapType) ItemField() Field       { return 
t.value.Elem().(*StructType).Field(1) }
 func (t *MapType) ItemType() DataType     { return t.ItemField().Type }
 func (t *MapType) ValueType() *StructType { return 
t.value.Elem().(*StructType) }
+func (t *MapType) ValueField() Field {
+       return Field{
+               Name: "entries",
+               Type: t.ValueType(),
+       }
+}
+
+func (t *MapType) SetItemNullable(nullable bool) {
+       t.value.Elem().(*StructType).fields[1].Nullable = nullable
+}
 
 func (t *MapType) Fingerprint() string {
        keyFingerprint := t.KeyType().Fingerprint()
diff --git a/go/arrow/datatype_nested_test.go b/go/arrow/datatype_nested_test.go
index 94c6a71..7fe0303 100644
--- a/go/arrow/datatype_nested_test.go
+++ b/go/arrow/datatype_nested_test.go
@@ -40,7 +40,7 @@ func TestListOf(t *testing.T) {
        } {
                t.Run(tc.Name(), func(t *testing.T) {
                        got := ListOf(tc)
-                       want := &ListType{elem: tc}
+                       want := &ListType{elem: tc, NullableElem: true}
                        if !reflect.DeepEqual(got, want) {
                                t.Fatalf("got=%#v, want=%#v", got, want)
                        }
@@ -313,7 +313,7 @@ func TestFixedSizeListOf(t *testing.T) {
                t.Run(tc.Name(), func(t *testing.T) {
                        const size = 3
                        got := FixedSizeListOf(size, tc)
-                       want := &FixedSizeListType{elem: tc, n: size}
+                       want := &FixedSizeListType{elem: tc, n: size, 
NullableElem: true}
                        if !reflect.DeepEqual(got, want) {
                                t.Fatalf("got=%#v, want=%#v", got, want)
                        }
diff --git a/go/arrow/example_test.go b/go/arrow/example_test.go
index bb4bf78..8748072 100644
--- a/go/arrow/example_test.go
+++ b/go/arrow/example_test.go
@@ -162,9 +162,11 @@ func Example_listArray() {
        arr := lb.NewArray().(*array.List)
        defer arr.Release()
 
+       arr.DataType().(*arrow.ListType).NullableElem = false
        fmt.Printf("NullN()   = %d\n", arr.NullN())
        fmt.Printf("Len()     = %d\n", arr.Len())
        fmt.Printf("Offsets() = %v\n", arr.Offsets())
+       fmt.Printf("Type()    = %v\n", arr.DataType())
 
        offsets := arr.Offsets()[1:]
 
@@ -192,6 +194,7 @@ func Example_listArray() {
        // NullN()   = 2
        // Len()     = 7
        // Offsets() = [0 3 3 4 6 9 9 10]
+       // Type()    = list<item: int64>
        // List[0]   = [0, 1, 2]
        // List[1]   = (null)
        // List[2]   = [3]
@@ -245,7 +248,7 @@ func Example_fixedSizeListArray() {
        // Output:
        // NullN()   = 2
        // Len()     = 5
-       // Type()    = fixed_size_list<item: int64>[3]
+       // Type()    = fixed_size_list<item: int64, nullable>[3]
        // List      = [[0 1 2] (null) [3 4 5] [6 7 8] (null)]
 }
 
diff --git a/go/arrow/internal/arrjson/arrjson.go 
b/go/arrow/internal/arrjson/arrjson.go
index 3d5247b..a8209ea 100644
--- a/go/arrow/internal/arrjson/arrjson.go
+++ b/go/arrow/internal/arrjson/arrjson.go
@@ -353,7 +353,7 @@ func (f *FieldWrapper) UnmarshalJSON(data []byte) error {
        case "list":
                f.arrowType = arrow.ListOf(f.Children[0].arrowType)
                f.arrowType.(*arrow.ListType).Meta = f.Children[0].arrowMeta
-
+               f.arrowType.(*arrow.ListType).NullableElem = 
f.Children[0].Nullable
        case "map":
                t := mapJSON{}
                if err := json.Unmarshal(f.Type, &t); err != nil {
@@ -376,6 +376,8 @@ func (f *FieldWrapper) UnmarshalJSON(data []byte) error {
                        return err
                }
                f.arrowType = arrow.FixedSizeListOf(t.ListSize, 
f.Children[0].arrowType)
+               f.arrowType.(*arrow.FixedSizeListType).NullableElem = 
f.Children[0].Nullable
+               f.arrowType.(*arrow.FixedSizeListType).Meta = 
f.Children[0].arrowMeta
        case "interval":
                t := unitZoneJSON{}
                if err := json.Unmarshal(f.Type, &t); err != nil {
@@ -548,13 +550,13 @@ func fieldsToJSON(fields []arrow.Field) []FieldWrapper {
                }}
                switch dt := f.Type.(type) {
                case *arrow.ListType:
-                       o[i].Children = fieldsToJSON([]arrow.Field{{Name: 
"item", Type: dt.Elem(), Nullable: f.Nullable, Metadata: dt.Meta}})
+                       o[i].Children = 
fieldsToJSON([]arrow.Field{dt.ElemField()})
                case *arrow.FixedSizeListType:
-                       o[i].Children = fieldsToJSON([]arrow.Field{{Name: 
"item", Type: dt.Elem(), Nullable: f.Nullable}})
+                       o[i].Children = 
fieldsToJSON([]arrow.Field{dt.ElemField()})
                case *arrow.StructType:
                        o[i].Children = fieldsToJSON(dt.Fields())
                case *arrow.MapType:
-                       o[i].Children = fieldsToJSON([]arrow.Field{{Name: 
"entries", Type: dt.ValueType()}})
+                       o[i].Children = 
fieldsToJSON([]arrow.Field{dt.ValueField()})
                }
        }
        return o
diff --git a/go/arrow/ipc/cmd/arrow-ls/main_test.go 
b/go/arrow/ipc/cmd/arrow-ls/main_test.go
index 1ea9580..508ea68 100644
--- a/go/arrow/ipc/cmd/arrow-ls/main_test.go
+++ b/go/arrow/ipc/cmd/arrow-ls/main_test.go
@@ -72,7 +72,7 @@ records: 2
                        name: "lists",
                        want: `schema:
   fields: 1
-    - list_nullable: type=list<item: int32>, nullable
+    - list_nullable: type=list<item: int32, nullable>, nullable
 records: 4
 `,
                },
@@ -89,7 +89,7 @@ records: 3
                        name: "fixed_size_lists",
                        want: `schema:
   fields: 1
-    - fixed_size_list_nullable: type=fixed_size_list<item: int32>[3], nullable
+    - fixed_size_list_nullable: type=fixed_size_list<item: int32, 
nullable>[3], nullable
 records: 3
 `,
                },
@@ -248,7 +248,7 @@ records: 2
                        name:   "lists",
                        want: `schema:
   fields: 1
-    - list_nullable: type=list<item: int32>, nullable
+    - list_nullable: type=list<item: int32, nullable>, nullable
 records: 4
 `,
                },
@@ -257,7 +257,7 @@ records: 4
                        want: `version: V5
 schema:
   fields: 1
-    - list_nullable: type=list<item: int32>, nullable
+    - list_nullable: type=list<item: int32, nullable>, nullable
 records: 4
 `,
                },
diff --git a/go/arrow/ipc/metadata.go b/go/arrow/ipc/metadata.go
index ccc231d..9f6333b 100644
--- a/go/arrow/ipc/metadata.go
+++ b/go/arrow/ipc/metadata.go
@@ -347,13 +347,13 @@ func (fv *fieldVisitor) visit(field arrow.Field) {
 
        case *arrow.ListType:
                fv.dtype = flatbuf.TypeList
-               fv.kids = append(fv.kids, fieldToFB(fv.b, arrow.Field{Name: 
"item", Type: dt.Elem(), Nullable: field.Nullable, Metadata: dt.Meta}, fv.memo))
+               fv.kids = append(fv.kids, fieldToFB(fv.b, dt.ElemField(), 
fv.memo))
                flatbuf.ListStart(fv.b)
                fv.offset = flatbuf.ListEnd(fv.b)
 
        case *arrow.FixedSizeListType:
                fv.dtype = flatbuf.TypeFixedSizeList
-               fv.kids = append(fv.kids, fieldToFB(fv.b, arrow.Field{Name: 
"item", Type: dt.Elem(), Nullable: field.Nullable}, fv.memo))
+               fv.kids = append(fv.kids, fieldToFB(fv.b, dt.ElemField(), 
fv.memo))
                flatbuf.FixedSizeListStart(fv.b)
                flatbuf.FixedSizeListAddListSize(fv.b, dt.Len())
                fv.offset = flatbuf.FixedSizeListEnd(fv.b)
@@ -379,7 +379,7 @@ func (fv *fieldVisitor) visit(field arrow.Field) {
 
        case *arrow.MapType:
                fv.dtype = flatbuf.TypeMap
-               fv.kids = append(fv.kids, fieldToFB(fv.b, arrow.Field{Name: 
"entries", Type: dt.ValueType()}, fv.memo))
+               fv.kids = append(fv.kids, fieldToFB(fv.b, dt.ValueField(), 
fv.memo))
                flatbuf.MapStart(fv.b)
                flatbuf.MapAddKeysSorted(fv.b, dt.KeysSorted)
                fv.offset = flatbuf.MapEnd(fv.b)
@@ -607,6 +607,7 @@ func concreteTypeFromFB(typ flatbuf.Type, data 
flatbuffers.Table, children []arr
                }
                dt := arrow.ListOf(children[0].Type)
                dt.Meta = children[0].Metadata
+               dt.NullableElem = children[0].Nullable
                return dt, nil
 
        case flatbuf.TypeFixedSizeList:
@@ -615,7 +616,10 @@ func concreteTypeFromFB(typ flatbuf.Type, data 
flatbuffers.Table, children []arr
                if len(children) != 1 {
                        return nil, xerrors.Errorf("arrow/ipc: FixedSizeList 
must have exactly 1 child field (got=%d)", len(children))
                }
-               return arrow.FixedSizeListOf(dt.ListSize(), children[0].Type), 
nil
+               ret := arrow.FixedSizeListOf(dt.ListSize(), children[0].Type)
+               ret.Meta = children[0].Metadata
+               ret.NullableElem = children[0].Nullable
+               return ret, nil
 
        case flatbuf.TypeStruct_:
                return arrow.StructOf(children...), nil

Reply via email to