diff --git a/go/arrow/ipc/file_reader.go b/go/arrow/ipc/file_reader.go index fef552d0088..1765e381241 100644 --- a/go/arrow/ipc/file_reader.go +++ b/go/arrow/ipc/file_reader.go @@ -364,6 +364,9 @@ func (ctx *arrayLoaderContext) loadArray(dt arrow.DataType) array.Interface { case *arrow.BinaryType, *arrow.StringType: return ctx.loadBinary(dt) + case *arrow.ListType: + return ctx.loadList(dt) + default: panic(errors.Errorf("array type %T not handled yet", dt)) } @@ -385,6 +388,16 @@ func (ctx *arrayLoaderContext) loadCommon(nbufs int) (*flatbuf.FieldNode, []*mem return field, buffers } +func (ctx *arrayLoaderContext) loadChild(dt arrow.DataType) array.Interface { + if ctx.max == 0 { + panic("arrow/ipc: nested type limit reached") + } + ctx.max-- + sub := ctx.loadArray(dt) + ctx.max++ + return sub +} + func (ctx *arrayLoaderContext) loadNull() array.Interface { field, buffers := ctx.loadCommon(1) buffers = append(buffers, ctx.buffer()) @@ -422,6 +435,19 @@ func (ctx *arrayLoaderContext) loadBinary(dt arrow.DataType) array.Interface { return array.MakeFromData(data) } +func (ctx *arrayLoaderContext) loadList(dt *arrow.ListType) array.Interface { + field, buffers := ctx.loadCommon(2) + buffers = append(buffers, ctx.buffer()) + + sub := ctx.loadChild(dt.Elem()) + defer sub.Release() + + data := array.NewData(dt, int(field.Length()), buffers, []*array.Data{sub.Data()}, int(field.NullCount()), 0) + defer data.Release() + + return array.NewListData(data) +} + func readDictionary(meta *memory.Buffer, types dictTypeMap, r ReadAtSeeker) (int64, array.Interface, error) { // msg := flatbuf.GetRootAsMessage(meta.Bytes(), 0) // var dictBatch flatbuf.DictionaryBatch diff --git a/go/arrow/ipc/metadata.go b/go/arrow/ipc/metadata.go index f3ecc2e54fc..cfbfd248144 100644 --- a/go/arrow/ipc/metadata.go +++ b/go/arrow/ipc/metadata.go @@ -248,6 +248,12 @@ func concreteTypeFromFB(typ flatbuf.Type, data flatbuffers.Table, children []arr case flatbuf.TypeBool: return arrow.FixedWidthTypes.Boolean, nil + case flatbuf.TypeList: + if len(children) != 1 { + return nil, errors.Errorf("arrow/ipc: List must have exactly 1 child field (got=%d)", len(children)) + } + return arrow.ListOf(children[0].Type), nil + default: // FIXME(sbinet): implement all the other types. panic(fmt.Errorf("arrow/ipc: type %v not implemented", flatbuf.EnumNamesType[typ]))