You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ko...@apache.org on 2023/06/23 21:19:42 UTC

[arrow] branch main updated: GH-35969: [Swift] use ArrowType instead of ArrowType.info and add binary, time32 and time64 types (#35985)

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

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


The following commit(s) were added to refs/heads/main by this push:
     new 4cbab52a3e GH-35969: [Swift] use ArrowType instead of ArrowType.info and add binary, time32 and time64 types (#35985)
4cbab52a3e is described below

commit 4cbab52a3e0a6a9b590632534093a4a230d9862f
Author: abandy <ab...@live.com>
AuthorDate: Fri Jun 23 17:19:35 2023 -0400

    GH-35969: [Swift] use ArrowType instead of ArrowType.info and add binary, time32 and time64 types (#35985)
    
    Changes:
    - Updated code to use ArrowType instead of ArrowType.info to store the arrow type in classes and structs.  This was done due to Time32 and Time64 requiring additional information beyond just the basic enum info.
    - Add binary, time32 and time64 types.
    * Closes: #35969
    
    Lead-authored-by: Alva Bandy <ab...@live.com>
    Co-authored-by: Sutou Kouhei <ko...@cozmixng.org>
    Signed-off-by: Sutou Kouhei <ko...@clear-code.com>
---
 docs/source/status.rst                             |   4 +-
 swift/Arrow/Sources/Arrow/ArrowArray.swift         |  63 ++++++-
 swift/Arrow/Sources/Arrow/ArrowArrayBuilder.swift  |  50 ++++--
 swift/Arrow/Sources/Arrow/ArrowBufferBuilder.swift |  49 ++----
 swift/Arrow/Sources/Arrow/ArrowData.swift          |  29 ++--
 swift/Arrow/Sources/Arrow/ArrowReader.swift        |  44 +++--
 swift/Arrow/Sources/Arrow/ArrowReaderHelper.swift  |  93 +++++++---
 swift/Arrow/Sources/Arrow/ArrowSchema.swift        |   6 +-
 swift/Arrow/Sources/Arrow/ArrowTable.swift         |   2 +-
 swift/Arrow/Sources/Arrow/ArrowType.swift          |  62 +++++--
 swift/Arrow/Sources/Arrow/ArrowWriter.swift        |  33 +++-
 swift/Arrow/Sources/Arrow/ArrowWriterHelper.swift  |  29 +++-
 swift/Arrow/Sources/Arrow/ChunkedArray.swift       |   4 +-
 swift/Arrow/Tests/ArrowTests/ArrayTests.swift      |  84 +++++++++
 swift/Arrow/Tests/ArrowTests/IPCTests.swift        | 191 ++++++++++++++++++---
 .../Arrow/Tests/ArrowTests/RecordBatchTests.swift  |   4 +-
 swift/Arrow/Tests/ArrowTests/TableTests.swift      |  24 +--
 17 files changed, 594 insertions(+), 177 deletions(-)

diff --git a/docs/source/status.rst b/docs/source/status.rst
index a73de815b7..6c55b4bd3e 100644
--- a/docs/source/status.rst
+++ b/docs/source/status.rst
@@ -50,7 +50,7 @@ Data Types
 +-------------------+-------+-------+-------+------------+-------+-------+-------+-------+
 | Date32/64         | ✓     | ✓     | ✓     | ✓          |  ✓    |  ✓    | ✓     | ✓     |
 +-------------------+-------+-------+-------+------------+-------+-------+-------+-------+
-| Time32/64         | ✓     | ✓     | ✓     | ✓          |  ✓    |  ✓    | ✓     |       |
+| Time32/64         | ✓     | ✓     | ✓     | ✓          |  ✓    |  ✓    | ✓     | ✓     |
 +-------------------+-------+-------+-------+------------+-------+-------+-------+-------+
 | Timestamp         | ✓     | ✓     | ✓     | ✓          |  ✓    |  ✓    | ✓     |       |
 +-------------------+-------+-------+-------+------------+-------+-------+-------+-------+
@@ -60,7 +60,7 @@ Data Types
 +-------------------+-------+-------+-------+------------+-------+-------+-------+-------+
 | Fixed Size Binary | ✓     | ✓     | ✓     | ✓          |  ✓    |  ✓    | ✓     |       |
 +-------------------+-------+-------+-------+------------+-------+-------+-------+-------+
-| Binary            | ✓     | ✓     | ✓     | ✓          |  ✓    |  ✓    | ✓     |       |
+| Binary            | ✓     | ✓     | ✓     | ✓          |  ✓    |  ✓    | ✓     | ✓     |
 +-------------------+-------+-------+-------+------------+-------+-------+-------+-------+
 | Large Binary      | ✓     | ✓     | ✓     | ✓          |       |  ✓    | ✓     |       |
 +-------------------+-------+-------+-------+------------+-------+-------+-------+-------+
diff --git a/swift/Arrow/Sources/Arrow/ArrowArray.swift b/swift/Arrow/Sources/Arrow/ArrowArray.swift
index 07a66dafe0..1d41cc7e37 100644
--- a/swift/Arrow/Sources/Arrow/ArrowArray.swift
+++ b/swift/Arrow/Sources/Arrow/ArrowArray.swift
@@ -18,7 +18,7 @@
 import Foundation
 
 public class ArrowArrayHolder {
-    public let type: ArrowType.Info
+    public let type: ArrowType
     public let length: UInt
     public let nullCount: UInt
     public let array: Any
@@ -89,7 +89,7 @@ public class ArrowArray<T>: AsString {
     }
 
     public subscript(_ index: UInt) -> T? {
-        get{
+        get {
             fatalError("subscript() has not been implemented")
         }
     }
@@ -105,7 +105,7 @@ public class ArrowArray<T>: AsString {
 
 public class FixedArray<T>: ArrowArray<T> {
     public override subscript(_ index: UInt) -> T? {
-        get{
+        get {
             if self.arrowData.isNull(index) {
                 return nil
             }
@@ -118,7 +118,7 @@ public class FixedArray<T>: ArrowArray<T> {
 
 public class StringArray: ArrowArray<String> {
     public override subscript(_ index: UInt) -> String? {
-        get{
+        get {
             let offsetIndex = MemoryLayout<Int32>.stride * Int(index)
             if self.arrowData.isNull(index) {
                 return nil
@@ -144,7 +144,7 @@ public class StringArray: ArrowArray<String> {
 
 public class BoolArray: ArrowArray<Bool> {
     public override subscript(_ index: UInt) -> Bool? {
-        get{
+        get {
             if self.arrowData.isNull(index) {
                 return nil
             }
@@ -157,7 +157,7 @@ public class BoolArray: ArrowArray<Bool> {
 
 public class Date32Array: ArrowArray<Date> {
     public override subscript(_ index: UInt) -> Date? {
-        get{
+        get {
             if self.arrowData.isNull(index) {
                 return nil
             }
@@ -171,7 +171,7 @@ public class Date32Array: ArrowArray<Date> {
 
 public class Date64Array: ArrowArray<Date> {
     public override subscript(_ index: UInt) -> Date? {
-        get{
+        get {
             if self.arrowData.isNull(index) {
                 return nil
             }
@@ -182,3 +182,52 @@ public class Date64Array: ArrowArray<Date> {
         }
     }
 }
+
+public class Time32Array: FixedArray<Time32> {}
+public class Time64Array: FixedArray<Time64> {}
+
+public class BinaryArray: ArrowArray<Data> {
+    public struct Options {
+        public var printAsHex = false
+        public var printEncoding: String.Encoding = .utf8;
+    }
+    
+    public var options = Options()
+    
+    public override subscript(_ index: UInt) -> Data? {
+        get {
+            let offsetIndex = MemoryLayout<Int32>.stride * Int(index)
+            if self.arrowData.isNull(index) {
+                return nil
+            }
+            
+            let offsets = self.arrowData.buffers[1]
+            let values = self.arrowData.buffers[2]
+
+            var startIndex: Int32 = 0
+            if index > 0 {
+                startIndex = offsets.rawPointer.advanced(by: offsetIndex).load(as: Int32.self)
+            }
+
+            let endIndex = offsets.rawPointer.advanced(by: offsetIndex + MemoryLayout<Int32>.stride ).load(as: Int32.self)
+            let arrayLength = Int(endIndex - startIndex);
+            let rawPointer =  values.rawPointer.advanced(by: Int(startIndex)).bindMemory(to: UInt8.self, capacity: arrayLength)
+            let buffer = UnsafeBufferPointer<UInt8>(start: rawPointer, count: arrayLength);
+            let byteArray = Array(buffer)
+            return Data(byteArray)
+        }
+    }
+    
+    public override func asString(_ index: UInt) -> String {
+        if self[index] == nil {
+            return ""
+        }
+        
+        let data = self[index]!
+        if options.printAsHex {
+            return data.hexEncodedString()
+        } else {
+            return String(data: data, encoding: .utf8)!
+        }
+    }
+}
diff --git a/swift/Arrow/Sources/Arrow/ArrowArrayBuilder.swift b/swift/Arrow/Sources/Arrow/ArrowArrayBuilder.swift
index c456f5a00b..4c1c060463 100644
--- a/swift/Arrow/Sources/Arrow/ArrowArrayBuilder.swift
+++ b/swift/Arrow/Sources/Arrow/ArrowArrayBuilder.swift
@@ -18,14 +18,14 @@
 import Foundation
 
 public class ArrowArrayBuilder<T: ArrowBufferBuilder, U: ArrowArray<T.ItemType>> {
-    let type: ArrowType.Info
+    let type: ArrowType
     let bufferBuilder: T
     var length: UInt {get{return self.bufferBuilder.length}}
     var capacity: UInt {get{return self.bufferBuilder.capacity}}
     var nullCount : UInt {get{return self.bufferBuilder.nullCount}}
     var offset: UInt {get{return self.bufferBuilder.offset}}
     
-    fileprivate init(_ type: ArrowType.Info) throws {
+    fileprivate init(_ type: ArrowType) throws {
         self.type = type;
         self.bufferBuilder = try T()
     }
@@ -36,8 +36,8 @@ public class ArrowArrayBuilder<T: ArrowBufferBuilder, U: ArrowArray<T.ItemType>>
 
     func finish() throws -> ArrowArray<T.ItemType> {
         let buffers = self.bufferBuilder.finish();
-        let arrowData = try ArrowData(self.type, buffers: buffers, nullCount: self.nullCount, stride: self.getStride());
-        return U(arrowData);
+        let arrowData = try ArrowData(self.type, buffers: buffers, nullCount: self.nullCount, stride: self.getStride())
+        return U(arrowData)
     }
     
     func getStride() -> Int {
@@ -47,25 +47,31 @@ public class ArrowArrayBuilder<T: ArrowBufferBuilder, U: ArrowArray<T.ItemType>>
 
 public class NumberArrayBuilder<T> : ArrowArrayBuilder<FixedBufferBuilder<T>, FixedArray<T>> {
     fileprivate convenience init() throws {
-        try self.init(ArrowType.infoForNumericType(T.self));
+        try self.init(ArrowType(ArrowType.infoForNumericType(T.self)))
     }
 }
 
 public class StringArrayBuilder : ArrowArrayBuilder<VariableBufferBuilder<String>, StringArray> {
     fileprivate convenience init() throws {
-        try self.init(ArrowType.ArrowString);
+        try self.init(ArrowType(ArrowType.ArrowString))
+    }
+}
+
+public class BinaryArrayBuilder : ArrowArrayBuilder<VariableBufferBuilder<Data>, BinaryArray> {
+    fileprivate convenience init() throws {
+        try self.init(ArrowType(ArrowType.ArrowBinary))
     }
 }
 
 public class BoolArrayBuilder : ArrowArrayBuilder<BoolBufferBuilder, BoolArray> {
     fileprivate convenience init() throws {
-        try self.init(ArrowType.ArrowBool);
+        try self.init(ArrowType(ArrowType.ArrowBool))
     }
 }
 
 public class Date32ArrayBuilder : ArrowArrayBuilder<Date32BufferBuilder, Date32Array> {
     fileprivate convenience init() throws {
-        try self.init(ArrowType.ArrowDate32)
+        try self.init(ArrowType(ArrowType.ArrowDate32))
     }
     
     override func getStride() -> Int {
@@ -75,7 +81,7 @@ public class Date32ArrayBuilder : ArrowArrayBuilder<Date32BufferBuilder, Date32A
 
 public class Date64ArrayBuilder : ArrowArrayBuilder<Date64BufferBuilder, Date64Array> {
     fileprivate convenience init() throws {
-        try self.init(ArrowType.ArrowDate64)
+        try self.init(ArrowType(ArrowType.ArrowDate64))
     }
 
     override func getStride() -> Int {
@@ -83,6 +89,18 @@ public class Date64ArrayBuilder : ArrowArrayBuilder<Date64BufferBuilder, Date64A
     }
 }
 
+public class Time32ArrayBuilder : ArrowArrayBuilder<FixedBufferBuilder<Time32>, Time32Array> {
+    fileprivate convenience init(_ unit: ArrowTime32Unit) throws {
+        try self.init(ArrowTypeTime32(unit))
+    }
+}
+
+public class Time64ArrayBuilder : ArrowArrayBuilder<FixedBufferBuilder<Time64>, Time64Array> {
+    fileprivate convenience init(_ unit: ArrowTime64Unit) throws {
+        try self.init(ArrowTypeTime64(unit))
+    }
+}
+
 public class ArrowArrayBuilders {
     public static func loadNumberArrayBuilder<T>() throws -> NumberArrayBuilder<T> {
         let t = T.self
@@ -107,7 +125,7 @@ public class ArrowArrayBuilders {
         } else if t == Double.self {
             return try NumberArrayBuilder<T>()
         } else {
-            throw ArrowError.unknownType
+            throw ArrowError.unknownType("Type is invalid for NumberArrayBuilder")
         }
     }
 
@@ -126,4 +144,16 @@ public class ArrowArrayBuilders {
     public static func loadDate64ArrayBuilder() throws -> Date64ArrayBuilder {
         return try Date64ArrayBuilder()
     }
+    
+    public static func loadBinaryArrayBuilder() throws -> BinaryArrayBuilder {
+        return try BinaryArrayBuilder()
+    }
+
+    public static func loadTime32ArrayBuilder(_ unit: ArrowTime32Unit) throws -> Time32ArrayBuilder {
+        return try Time32ArrayBuilder(unit)
+    }
+
+    public static func loadTime64ArrayBuilder(_ unit: ArrowTime64Unit) throws -> Time64ArrayBuilder {
+        return try Time64ArrayBuilder(unit)
+    }
 }
diff --git a/swift/Arrow/Sources/Arrow/ArrowBufferBuilder.swift b/swift/Arrow/Sources/Arrow/ArrowBufferBuilder.swift
index 587c55dab5..39b0434c3c 100644
--- a/swift/Arrow/Sources/Arrow/ArrowBufferBuilder.swift
+++ b/swift/Arrow/Sources/Arrow/ArrowBufferBuilder.swift
@@ -134,7 +134,7 @@ public class FixedBufferBuilder<T>: BaseBufferBuilder<T>, ArrowBufferBuilder {
             return Double(0) as! T
         }
         
-        throw ArrowError.unknownType
+        throw ArrowError.unknownType("Unable to determine default value")
     }
 }
 
@@ -276,24 +276,19 @@ public class VariableBufferBuilder<T>: BaseBufferBuilder<T>, ArrowBufferBuilder
     }
 }
 
-public class Date32BufferBuilder: ArrowBufferBuilder {
-    public typealias ItemType = Date
+public class AbstractWrapperBufferBuilder<T, U>: ArrowBufferBuilder {
+    public typealias ItemType = T
     public var capacity: UInt {get{return self.bufferBuilder.capacity}}
     public var length: UInt {get{return self.bufferBuilder.length}}
     public var nullCount : UInt {get{return self.bufferBuilder.nullCount}}
     public var offset: UInt {get{return self.bufferBuilder.offset}}
-    private let bufferBuilder: FixedBufferBuilder<Int32>
+    let bufferBuilder: FixedBufferBuilder<U>
     public required init() throws {
         self.bufferBuilder = try FixedBufferBuilder()
     }
 
     public func append(_ newValue: ItemType?) {
-        if let val = newValue {
-            let daysSinceEpoch = Int32(val.timeIntervalSince1970 / 86400)
-            self.bufferBuilder.append(daysSinceEpoch)
-        } else {
-            self.bufferBuilder.append(nil)
-        }
+        fatalError("Method is not implemented")
     }
 
     public func isNull(_ index: UInt) -> Bool {
@@ -309,35 +304,25 @@ public class Date32BufferBuilder: ArrowBufferBuilder {
     }
 }
 
-public class Date64BufferBuilder: ArrowBufferBuilder {
-    public typealias ItemType = Date
-    public var capacity: UInt {get{return self.bufferBuilder.capacity}}
-    public var length: UInt {get{return self.bufferBuilder.length}}
-    public var nullCount : UInt {get{return self.bufferBuilder.nullCount}}
-    public var offset: UInt {get{return self.bufferBuilder.offset}}
-    private let bufferBuilder: FixedBufferBuilder<Int64>
-    public required init() throws {
-        self.bufferBuilder = try FixedBufferBuilder()
-    }
 
-    public func append(_ newValue: ItemType?) {
+public class Date32BufferBuilder: AbstractWrapperBufferBuilder<Date,Int32> {
+    public override func append(_ newValue: ItemType?) {
         if let val = newValue {
-            let daysSinceEpoch = Int64(val.timeIntervalSince1970 * 1000)
+            let daysSinceEpoch = Int32(val.timeIntervalSince1970 / 86400)
             self.bufferBuilder.append(daysSinceEpoch)
         } else {
             self.bufferBuilder.append(nil)
         }
     }
+}
 
-    public func isNull(_ index: UInt) -> Bool {
-        return self.bufferBuilder.isNull(index)
-    }
-    
-    public func resize(_ length: UInt) {
-        self.bufferBuilder.resize(length)
-    }
-    
-    public func finish() -> [ArrowBuffer] {
-        return self.bufferBuilder.finish()
+public class Date64BufferBuilder: AbstractWrapperBufferBuilder<Date,Int64> {
+    public override func append(_ newValue: ItemType?) {
+        if let val = newValue {
+            let daysSinceEpoch = Int64(val.timeIntervalSince1970 * 1000)
+            self.bufferBuilder.append(daysSinceEpoch)
+        } else {
+            self.bufferBuilder.append(nil)
+        }
     }
 }
diff --git a/swift/Arrow/Sources/Arrow/ArrowData.swift b/swift/Arrow/Sources/Arrow/ArrowData.swift
index ead76b1c87..4d50ef75c3 100644
--- a/swift/Arrow/Sources/Arrow/ArrowData.swift
+++ b/swift/Arrow/Sources/Arrow/ArrowData.swift
@@ -18,25 +18,30 @@
 import Foundation
 
 public class ArrowData {
-    public let type: ArrowType.Info
+    public let type: ArrowType
     public let buffers: [ArrowBuffer]
     public let nullCount: UInt
     public let length: UInt
     public let stride: Int
 
-    init(_ type: ArrowType.Info, buffers: [ArrowBuffer], nullCount: UInt, stride: Int) throws {
-        switch(type) {
-            case let .PrimitiveInfo(typeId):
-                if typeId == ArrowTypeId.Unknown {
-                    throw ArrowError.unknownType
-                }
-            case let .VariableInfo(typeId):
-                if typeId == ArrowTypeId.Unknown {
-                    throw ArrowError.unknownType
-                }
+    init(_ arrowType: ArrowType, buffers: [ArrowBuffer], nullCount: UInt, stride: Int) throws {
+        let infoType = arrowType.info
+        switch(infoType) {
+        case let .PrimitiveInfo(typeId):
+            if typeId == ArrowTypeId.Unknown {
+                throw ArrowError.unknownType("Unknown primitive type for data")
+            }
+        case let .VariableInfo(typeId):
+            if typeId == ArrowTypeId.Unknown {
+                throw ArrowError.unknownType("Unknown variable type for data")
+            }
+        case let .TimeInfo(typeId):
+            if typeId == ArrowTypeId.Unknown {
+                throw ArrowError.unknownType("Unknown time type for data")
+            }
         }
 
-        self.type = type
+        self.type = arrowType
         self.buffers = buffers
         self.nullCount = nullCount
         self.length = buffers[1].length
diff --git a/swift/Arrow/Sources/Arrow/ArrowReader.swift b/swift/Arrow/Sources/Arrow/ArrowReader.swift
index 151e0d1fd2..953ba540d1 100644
--- a/swift/Arrow/Sources/Arrow/ArrowReader.swift
+++ b/swift/Arrow/Sources/Arrow/ArrowReader.swift
@@ -31,15 +31,21 @@ public class ArrowReader {
         let messageOffset: Int64
     }
 
+    public class ArrowReaderResult {
+        public var schema: ArrowSchema?
+        public var batches = [RecordBatch]()
+    }
+    
     private func loadSchema(_ schema: org_apache_arrow_flatbuf_Schema) -> Result<ArrowSchema, ArrowError> {
         let builder = ArrowSchema.Builder()
         for index in 0 ..< schema.fieldsCount {
             let field = schema.fields(at: index)!
-            let arrowField = ArrowField(field.name!, type: findArrowType(field), isNullable: field.nullable)
-            builder.addField(arrowField)
-            if field.typeType == .struct_ {
-                return .failure(.unknownType)
+            let fieldType = findArrowType(field)
+            if fieldType.info == ArrowType.ArrowUnknown {
+                return .failure(.unknownType("Unsupported field type found: \(field.typeType)"))
             }
+            let arrowField = ArrowField(field.name!, type: fieldType, isNullable: field.nullable)
+            builder.addField(arrowField)
         }
 
         return .success(builder.finish())
@@ -88,7 +94,7 @@ public class ArrowReader {
     }
 
     private func loadRecordBatch(_ message: org_apache_arrow_flatbuf_Message, schema: org_apache_arrow_flatbuf_Schema,
-                                 data: Data, messageEndOffset: Int64) -> Result<RecordBatch, ArrowError> {
+                                 arrowSchema: ArrowSchema, data: Data, messageEndOffset: Int64) -> Result<RecordBatch, ArrowError> {
         let recordBatch = message.header(type: org_apache_arrow_flatbuf_RecordBatch.self)
         let nodesCount = recordBatch?.nodesCount ?? 0
         var bufferIndex: Int32 = 0
@@ -116,25 +122,27 @@ public class ArrowReader {
             
         }
         
-        let schemaResult = loadSchema(schema)
-        switch schemaResult {
-        case .success(let arrowSchema):
-            return .success(RecordBatch(arrowSchema, columns: columns))
-        case .failure(let error):
-            return .failure(error)
-        }
+        return .success(RecordBatch(arrowSchema, columns: columns))
     }
 
-    public func fromStream(_ fileData: Data) -> Result<[RecordBatch], ArrowError> {
+    public func fromStream(_ fileData: Data) -> Result<ArrowReaderResult, ArrowError> {
         let footerLength = fileData.withUnsafeBytes { rawBuffer in
             rawBuffer.loadUnaligned(fromByteOffset: fileData.count - 4, as: Int32.self)
         }
 
-        var recordBatchs: [RecordBatch] = []
+        let result = ArrowReaderResult()
         let footerStartOffset = fileData.count - Int(footerLength + 4)
         let footerData = fileData[footerStartOffset...]
         let footerBuffer = ByteBuffer(data: footerData)
         let footer = org_apache_arrow_flatbuf_Footer.getRootAsFooter(bb: footerBuffer)
+        let schemaResult = loadSchema(footer.schema!)
+        switch schemaResult {
+        case .success(let schema):
+            result.schema = schema
+        case .failure(let error):
+            return .failure(error)
+        }
+
         for index in 0 ..< footer.recordBatchesCount {
             let recordBatch = footer.recordBatches(at: index)!
             var messageLength = fileData.withUnsafeBytes { rawBuffer in
@@ -159,9 +167,9 @@ public class ArrowReader {
             switch message.headerType {
             case .recordbatch:
                 do {
-                    let recordBatch = try loadRecordBatch(message, schema: footer.schema!,
+                    let recordBatch = try loadRecordBatch(message, schema: footer.schema!, arrowSchema: result.schema!,
                                                           data: fileData, messageEndOffset: messageEndOffset).get()
-                    recordBatchs.append(recordBatch)
+                    result.batches.append(recordBatch)
                 } catch let error as ArrowError {
                     return .failure(error)
                 } catch {
@@ -172,10 +180,10 @@ public class ArrowReader {
             }
         }
 
-        return .success(recordBatchs)
+        return .success(result)
     }
 
-    public func fromFile(_ fileURL: URL) -> Result<[RecordBatch], ArrowError> {
+    public func fromFile(_ fileURL: URL) -> Result<ArrowReaderResult, ArrowError> {
         do {
             let fileData = try Data(contentsOf: fileURL)
             if !validateFileData(fileData) {
diff --git a/swift/Arrow/Sources/Arrow/ArrowReaderHelper.swift b/swift/Arrow/Sources/Arrow/ArrowReaderHelper.swift
index 604b93f766..ca635723bc 100644
--- a/swift/Arrow/Sources/Arrow/ArrowReaderHelper.swift
+++ b/swift/Arrow/Sources/Arrow/ArrowReaderHelper.swift
@@ -18,9 +18,21 @@
 import FlatBuffers
 import Foundation
 
+fileprivate func makeBinaryHolder(_ buffers: [ArrowBuffer]) -> Result<ArrowArrayHolder, ArrowError> {
+    do {
+        let arrowData = try ArrowData(ArrowType(ArrowType.ArrowBinary), buffers: buffers,
+                                      nullCount: buffers[0].length, stride: MemoryLayout<Int8>.stride)
+        return .success(ArrowArrayHolder(BinaryArray(arrowData)))
+    } catch let error as ArrowError {
+        return .failure(error)
+    } catch {
+        return .failure(.unknownError("\(error)"))
+    }
+}
+
 fileprivate func makeStringHolder(_ buffers: [ArrowBuffer]) -> Result<ArrowArrayHolder, ArrowError> {
     do {
-        let arrowData = try ArrowData(ArrowType.ArrowString, buffers: buffers,
+        let arrowData = try ArrowData(ArrowType(ArrowType.ArrowString), buffers: buffers,
                                       nullCount: buffers[0].length, stride: MemoryLayout<Int8>.stride)
         return .success(ArrowArrayHolder(StringArray(arrowData)))
     } catch let error as ArrowError {
@@ -37,19 +49,19 @@ fileprivate func makeFloatHolder(_ floatType: org_apache_arrow_flatbuf_FloatingP
     case .double:
         return makeFixedHolder(Double.self, buffers: buffers)
     default:
-        return .failure(.unknownType)
+        return .failure(.unknownType("Float precision \(floatType.precision) currently not supported"))
     }
 }
 
 fileprivate func makeDateHolder(_ dateType: org_apache_arrow_flatbuf_Date, buffers: [ArrowBuffer]) -> Result<ArrowArrayHolder, ArrowError> {
     do  {
         if dateType.unit == .day {
-            let arrowData = try ArrowData(ArrowType.ArrowString, buffers: buffers,
+            let arrowData = try ArrowData(ArrowType(ArrowType.ArrowString), buffers: buffers,
                                           nullCount: buffers[0].length, stride: MemoryLayout<Date>.stride)
             return .success(ArrowArrayHolder(Date32Array(arrowData)))
         }
         
-        let arrowData = try ArrowData(ArrowType.ArrowString, buffers: buffers,
+        let arrowData = try ArrowData(ArrowType(ArrowType.ArrowString), buffers: buffers,
                                       nullCount: buffers[0].length, stride: MemoryLayout<Date>.stride)
         return .success(ArrowArrayHolder(Date64Array(arrowData)))
     } catch let error as ArrowError {
@@ -59,9 +71,30 @@ fileprivate func makeDateHolder(_ dateType: org_apache_arrow_flatbuf_Date, buffe
     }
 }
 
+fileprivate func makeTimeHolder(_ timeType: org_apache_arrow_flatbuf_Time, buffers: [ArrowBuffer]) -> Result<ArrowArrayHolder, ArrowError> {
+    do  {
+        if timeType.unit == .second || timeType.unit == .millisecond {
+            let arrowUnit: ArrowTime32Unit = timeType.unit == .second ? .Seconds : .Milliseconds
+            let arrowData = try ArrowData(ArrowTypeTime32(arrowUnit), buffers: buffers,
+                                          nullCount: buffers[0].length, stride: MemoryLayout<Time32>.stride)
+            
+            return .success(ArrowArrayHolder(FixedArray<Time32>(arrowData)))
+        }
+        
+        let arrowUnit: ArrowTime64Unit = timeType.unit == .microsecond ? .Microseconds : .Nanoseconds
+        let arrowData = try ArrowData(ArrowTypeTime64(arrowUnit), buffers: buffers,
+                                      nullCount: buffers[0].length, stride: MemoryLayout<Time64>.stride)
+        return .success(ArrowArrayHolder(FixedArray<Time64>(arrowData)))
+    } catch let error as ArrowError {
+        return .failure(error)
+    } catch {
+        return .failure(.unknownError("\(error)"))
+    }
+}
+
 fileprivate func makeBoolHolder(_ buffers: [ArrowBuffer]) -> Result<ArrowArrayHolder, ArrowError> {
     do {
-        let arrowData = try ArrowData(ArrowType.ArrowInt32, buffers: buffers,
+        let arrowData = try ArrowData(ArrowType(ArrowType.ArrowInt32), buffers: buffers,
                                       nullCount: buffers[0].length, stride: MemoryLayout<UInt8>.stride)
         return .success(ArrowArrayHolder(BoolArray(arrowData)))
     } catch let error as ArrowError {
@@ -73,7 +106,7 @@ fileprivate func makeBoolHolder(_ buffers: [ArrowBuffer]) -> Result<ArrowArrayHo
 
 fileprivate func makeFixedHolder<T>(_: T.Type, buffers: [ArrowBuffer]) -> Result<ArrowArrayHolder, ArrowError> {
     do {
-        let arrowData = try ArrowData(ArrowType.ArrowInt32, buffers: buffers,
+        let arrowData = try ArrowData(ArrowType(ArrowType.ArrowInt32), buffers: buffers,
                                       nullCount: buffers[0].length, stride: MemoryLayout<T>.stride)
         return .success(ArrowArrayHolder(FixedArray<T>(arrowData)))
     } catch let error as ArrowError {
@@ -114,7 +147,7 @@ func makeArrayHolder(_ field: org_apache_arrow_flatbuf_Field, buffers: [ArrowBuf
                 return makeFixedHolder(UInt64.self, buffers: buffers)
             }
         }
-        return .failure(.unknownType)
+        return .failure(.unknownType("Int width \(bitWidth) currently not supported"))
     case .bool:
         return makeBoolHolder(buffers)
     case .floatingpoint:
@@ -122,11 +155,16 @@ func makeArrayHolder(_ field: org_apache_arrow_flatbuf_Field, buffers: [ArrowBuf
         return makeFloatHolder(floatType, buffers: buffers)
     case .utf8:
         return makeStringHolder(buffers)
+    case .binary:
+        return makeBinaryHolder(buffers)
     case .date:
         let dateType = field.type(type: org_apache_arrow_flatbuf_Date.self)!
         return makeDateHolder(dateType, buffers: buffers)
+    case .time:
+        let timeType = field.type(type: org_apache_arrow_flatbuf_Time.self)!
+        return makeTimeHolder(timeType, buffers: buffers)
     default:
-        return .failure(.unknownType)
+        return .failure(.unknownType("Type \(type) currently not supported"))
     }
 }
 
@@ -140,47 +178,56 @@ func makeBuffer(_ buffer: org_apache_arrow_flatbuf_Buffer, fileData: Data,
 
 func isFixedPrimitive(_ type: org_apache_arrow_flatbuf_Type_) -> Bool {
     switch type {
-    case .int, .bool, .floatingpoint, .date:
+    case .int, .bool, .floatingpoint, .date, .time:
         return true
     default:
         return false
     }
 }
 
-func findArrowType(_ field: org_apache_arrow_flatbuf_Field) -> ArrowType.Info {
+func findArrowType(_ field: org_apache_arrow_flatbuf_Field) -> ArrowType {
     let type = field.typeType
     switch type {
     case .int:
         let intType = field.type(type: org_apache_arrow_flatbuf_Int.self)!
         let bitWidth = intType.bitWidth
-        if bitWidth == 8 { return intType.isSigned ? ArrowType.ArrowInt8 : ArrowType.ArrowUInt8 }
-        if bitWidth == 16 { return intType.isSigned ? ArrowType.ArrowInt16 : ArrowType.ArrowUInt16 }
-        if bitWidth == 32 { return intType.isSigned ? ArrowType.ArrowInt32 : ArrowType.ArrowUInt32 }
-        if bitWidth == 64 { return intType.isSigned ? ArrowType.ArrowInt64 : ArrowType.ArrowUInt64 }
-        return ArrowType.ArrowUnknown
+        if bitWidth == 8 { return ArrowType(intType.isSigned ? ArrowType.ArrowInt8 : ArrowType.ArrowUInt8) }
+        if bitWidth == 16 { return ArrowType(intType.isSigned ? ArrowType.ArrowInt16 : ArrowType.ArrowUInt16) }
+        if bitWidth == 32 { return ArrowType(intType.isSigned ? ArrowType.ArrowInt32 : ArrowType.ArrowUInt32) }
+        if bitWidth == 64 { return ArrowType(intType.isSigned ? ArrowType.ArrowInt64 : ArrowType.ArrowUInt64) }
+        return ArrowType(ArrowType.ArrowUnknown)
     case .bool:
-        return ArrowType.ArrowBool
+        return ArrowType(ArrowType.ArrowBool)
     case .floatingpoint:
         let floatType = field.type(type: org_apache_arrow_flatbuf_FloatingPoint.self)!
         switch floatType.precision {
         case .single:
-            return ArrowType.ArrowFloat
+            return ArrowType(ArrowType.ArrowFloat)
         case .double:
-            return ArrowType.ArrowDouble
+            return ArrowType(ArrowType.ArrowDouble)
         default:
-            return ArrowType.ArrowUnknown
+            return ArrowType(ArrowType.ArrowUnknown)
         }
     case .utf8:
-        return ArrowType.ArrowString
+        return ArrowType(ArrowType.ArrowString)
+    case .binary:
+        return ArrowType(ArrowType.ArrowBinary)
     case .date:
         let dateType = field.type(type: org_apache_arrow_flatbuf_Date.self)!
         if dateType.unit == .day {
-            return ArrowType.ArrowDate32
+            return ArrowType(ArrowType.ArrowDate32)
+        }
+        
+        return ArrowType(ArrowType.ArrowDate64)
+    case .time:
+        let timeType = field.type(type: org_apache_arrow_flatbuf_Time.self)!
+        if timeType.unit == .second || timeType.unit == .millisecond {
+            return ArrowTypeTime32(timeType.unit == .second ? .Seconds : .Milliseconds)
         }
         
-        return ArrowType.ArrowDate64
+        return ArrowTypeTime64(timeType.unit == .microsecond ? .Microseconds : .Nanoseconds)
     default:
-        return ArrowType.ArrowUnknown
+        return ArrowType(ArrowType.ArrowUnknown)
     }
 }
 
diff --git a/swift/Arrow/Sources/Arrow/ArrowSchema.swift b/swift/Arrow/Sources/Arrow/ArrowSchema.swift
index fc47ee7307..63841a9ab2 100644
--- a/swift/Arrow/Sources/Arrow/ArrowSchema.swift
+++ b/swift/Arrow/Sources/Arrow/ArrowSchema.swift
@@ -17,11 +17,11 @@
 
 import Foundation
 public class ArrowField {
-    let type: ArrowType.Info
+    let type: ArrowType
     let name: String
     let isNullable: Bool
     
-    init(_ name: String, type: ArrowType.Info, isNullable: Bool) {
+    init(_ name: String, type: ArrowType, isNullable: Bool) {
         self.name = name
         self.type = type
         self.isNullable = isNullable
@@ -59,7 +59,7 @@ public class ArrowSchema {
         }
 
         @discardableResult
-        public func addField(_ name: String, type: ArrowType.Info, isNullable: Bool) -> Builder {
+        public func addField(_ name: String, type: ArrowType, isNullable: Bool) -> Builder {
             fields.append(ArrowField(name, type: type, isNullable: isNullable))
             return self
         }
diff --git a/swift/Arrow/Sources/Arrow/ArrowTable.swift b/swift/Arrow/Sources/Arrow/ArrowTable.swift
index 70cabfaa7b..df8c21b5b8 100644
--- a/swift/Arrow/Sources/Arrow/ArrowTable.swift
+++ b/swift/Arrow/Sources/Arrow/ArrowTable.swift
@@ -20,7 +20,7 @@ import Foundation
 public class ArrowColumn {
     public let field: ArrowField
     fileprivate let dataHolder: ChunkedArrayHolder
-    public var type: ArrowType.Info {get{return self.dataHolder.type}}
+    public var type: ArrowType {get{return self.dataHolder.type}}
     public var length: UInt {get{return self.dataHolder.length}}
     public var nullCount: UInt {get{return self.dataHolder.nullCount}}
 
diff --git a/swift/Arrow/Sources/Arrow/ArrowType.swift b/swift/Arrow/Sources/Arrow/ArrowType.swift
index 4064191918..cf9d7f4dba 100644
--- a/swift/Arrow/Sources/Arrow/ArrowType.swift
+++ b/swift/Arrow/Sources/Arrow/ArrowType.swift
@@ -17,12 +17,15 @@
 
 import Foundation
 
+public typealias Time32 = Int32
+public typealias Time64 = Int64
+
 func FlatBuffersVersion_23_1_4() {
 }
-                                                                                                                
+                                                                                  
 public enum ArrowError: Error {
     case none
-    case unknownType
+    case unknownType(String)
     case runtimeError(String)
     case outOfBounds(index: Int64)
     case arrayHasNoElements
@@ -69,7 +72,34 @@ public enum ArrowTypeId {
     case Unknown
 }
 
+public enum ArrowTime32Unit {
+    case Seconds
+    case Milliseconds
+}
+
+public enum ArrowTime64Unit {
+    case Microseconds
+    case Nanoseconds
+}
+
+public class ArrowTypeTime32: ArrowType {
+    let unit: ArrowTime32Unit
+    public init(_ unit: ArrowTime32Unit) {
+        self.unit = unit
+        super.init(ArrowType.ArrowTime32)
+    }
+}
+
+public class ArrowTypeTime64: ArrowType {
+    let unit: ArrowTime64Unit
+    public init(_ unit: ArrowTime64Unit) {
+        self.unit = unit
+        super.init(ArrowType.ArrowTime64)
+    }
+}
+
 public class ArrowType {
+    public private(set) var info: ArrowType.Info
     public static let ArrowInt8 = Info.PrimitiveInfo(ArrowTypeId.Int8)
     public static let ArrowInt16 = Info.PrimitiveInfo(ArrowTypeId.Int16)
     public static let ArrowInt32 = Info.PrimitiveInfo(ArrowTypeId.Int32)
@@ -85,10 +115,18 @@ public class ArrowType {
     public static let ArrowBool = Info.PrimitiveInfo(ArrowTypeId.Boolean)
     public static let ArrowDate32 = Info.PrimitiveInfo(ArrowTypeId.Date32)
     public static let ArrowDate64 = Info.PrimitiveInfo(ArrowTypeId.Date64)
+    public static let ArrowBinary = Info.VariableInfo(ArrowTypeId.Binary)
+    public static let ArrowTime32 = Info.TimeInfo(ArrowTypeId.Time32)
+    public static let ArrowTime64 = Info.TimeInfo(ArrowTypeId.Time64)
 
+    public init(_ info: ArrowType.Info) {
+        self.info = info
+    }
+    
     public enum Info {
         case PrimitiveInfo(ArrowTypeId)
         case VariableInfo(ArrowTypeId)
+        case TimeInfo(ArrowTypeId)
     }
 
     public static func infoForNumericType<T>(_ t: T.Type) -> ArrowType.Info {
@@ -121,12 +159,14 @@ public class ArrowType {
 extension ArrowType.Info: Equatable {
     public static func==(lhs: ArrowType.Info, rhs: ArrowType.Info) -> Bool {
         switch(lhs, rhs) {
-            case (.PrimitiveInfo(let lhsId), .PrimitiveInfo(let rhsId)):
-                return lhsId == rhsId
-            case (.VariableInfo(let lhsId), .VariableInfo(let rhsId)):
-                return lhsId == rhsId
-            case (.VariableInfo(_), .PrimitiveInfo(_)), (.PrimitiveInfo(_), .VariableInfo(_)):
-                return false
+        case (.PrimitiveInfo(let lhsId), .PrimitiveInfo(let rhsId)):
+            return lhsId == rhsId
+        case (.VariableInfo(let lhsId), .VariableInfo(let rhsId)):
+            return lhsId == rhsId
+        case (.TimeInfo(let lhsId), .TimeInfo(let rhsId)):
+            return lhsId == rhsId
+        default:
+            return false
         }
     }
 }
@@ -135,8 +175,10 @@ func getBytesFor<T>(_ data: T) -> Data? {
     let t = T.self
     if t == String.self {
         let temp = data as! String
-        return temp.data(using: .utf8);
-    }else {
+        return temp.data(using: .utf8)
+    } else if t == Data.self {
+        return data as? Data
+    } else {
         return nil
     }
 }
diff --git a/swift/Arrow/Sources/Arrow/ArrowWriter.swift b/swift/Arrow/Sources/Arrow/ArrowWriter.swift
index c76dd94c13..02e1d432ea 100644
--- a/swift/Arrow/Sources/Arrow/ArrowWriter.swift
+++ b/swift/Arrow/Sources/Arrow/ArrowWriter.swift
@@ -53,9 +53,24 @@ public class ArrowWriter {
         }
     }
 
+    public class Info {
+        public let type: org_apache_arrow_flatbuf_MessageHeader
+        public let schema: ArrowSchema
+        public let batches: [RecordBatch]
+        public init(_ type: org_apache_arrow_flatbuf_MessageHeader, schema: ArrowSchema, batches: [RecordBatch]) {
+            self.type = type
+            self.schema = schema
+            self.batches = batches
+        }
+
+        public convenience init(_ type: org_apache_arrow_flatbuf_MessageHeader, schema: ArrowSchema) {
+            self.init(type, schema: schema, batches: [RecordBatch]())
+        }
+    }
+    
     private func writeField(_ fbb: inout FlatBufferBuilder, field: ArrowField) -> Result<Offset, ArrowError> {
         let nameOffset = fbb.create(string: field.name)
-        let fieldTypeOffsetResult = toFBType(&fbb, infoType: field.type)
+        let fieldTypeOffsetResult = toFBType(&fbb, arrowType: field.type)
         let startOffset = org_apache_arrow_flatbuf_Field.startField(&fbb)
         org_apache_arrow_flatbuf_Field.add(name: nameOffset, &fbb)
         org_apache_arrow_flatbuf_Field.add(nullable: field.isNullable, &fbb)
@@ -205,9 +220,9 @@ public class ArrowWriter {
         return .success(fbb.data)
     }
 
-    private func writeStream(_ writer: inout DataWriter, schema: ArrowSchema, batches: [RecordBatch]) -> Result<Bool, ArrowError> {
+    private func writeStream(_ writer: inout DataWriter, info: ArrowWriter.Info) -> Result<Bool, ArrowError> {
         var fbb: FlatBufferBuilder = FlatBufferBuilder()
-        switch writeSchema(&fbb, schema: schema) {
+        switch writeSchema(&fbb, schema: info.schema) {
         case .success(let schemaOffset):
             fbb.finish(offset: schemaOffset)
             writer.append(fbb.data)
@@ -215,9 +230,9 @@ public class ArrowWriter {
             return .failure(error)
         }
         
-        switch writeRecordBatches(&writer, batches: batches) {
+        switch writeRecordBatches(&writer, batches: info.batches) {
         case .success(let rbBlocks):
-            switch writeFooter(schema: schema, rbBlocks: rbBlocks) {
+            switch writeFooter(schema: info.schema, rbBlocks: rbBlocks) {
             case .success(let footerData):
                 fbb.finish(offset: Offset(offset: fbb.buffer.size))
                 let footerOffset = writer.count
@@ -237,9 +252,9 @@ public class ArrowWriter {
         return .success(true)
     }
 
-    public func toStream(_ schema: ArrowSchema, batches: [RecordBatch]) -> Result<Data, ArrowError> {
+    public func toStream(_ info: ArrowWriter.Info) -> Result<Data, ArrowError> {
         var writer: any DataWriter = InMemDataWriter()
-        switch writeStream(&writer, schema: schema, batches: batches) {
+        switch writeStream(&writer, info: info) {
         case .success(_):
             return .success((writer as! InMemDataWriter).data)
         case .failure(let error):
@@ -247,7 +262,7 @@ public class ArrowWriter {
         }
     }
 
-    public func toFile(_ fileName: URL, schema: ArrowSchema, batches: [RecordBatch]) -> Result<Bool, ArrowError> {
+    public func toFile(_ fileName: URL, info: ArrowWriter.Info) -> Result<Bool, ArrowError> {
         do {
             try Data().write(to: fileName)
         } catch {
@@ -262,7 +277,7 @@ public class ArrowWriter {
 
         var writer: any DataWriter = FileDataWriter(fileHandle)
         writer.append(FILEMARKER.data(using: .utf8)!)
-        switch writeStream(&writer, schema: schema, batches: batches) {
+        switch writeStream(&writer, info: info) {
         case .success(_):
             writer.append(FILEMARKER.data(using: .utf8)!)
         case .failure(let error):
diff --git a/swift/Arrow/Sources/Arrow/ArrowWriterHelper.swift b/swift/Arrow/Sources/Arrow/ArrowWriterHelper.swift
index 75f76be1e2..612df55830 100644
--- a/swift/Arrow/Sources/Arrow/ArrowWriterHelper.swift
+++ b/swift/Arrow/Sources/Arrow/ArrowWriterHelper.swift
@@ -24,7 +24,8 @@ extension Data {
     }
 }
 
-func toFBTypeEnum(_ infoType: ArrowType.Info) -> Result<org_apache_arrow_flatbuf_Type_, ArrowError> {
+func toFBTypeEnum(_ arrowType: ArrowType) -> Result<org_apache_arrow_flatbuf_Type_, ArrowError> {
+    let infoType = arrowType.info
     if infoType == ArrowType.ArrowInt8 || infoType == ArrowType.ArrowInt16 ||
         infoType == ArrowType.ArrowInt64 || infoType == ArrowType.ArrowUInt8 ||
         infoType == ArrowType.ArrowUInt16 || infoType == ArrowType.ArrowUInt32 ||
@@ -34,16 +35,20 @@ func toFBTypeEnum(_ infoType: ArrowType.Info) -> Result<org_apache_arrow_flatbuf
         return .success(org_apache_arrow_flatbuf_Type_.floatingpoint)
     } else if infoType == ArrowType.ArrowString {
         return .success(org_apache_arrow_flatbuf_Type_.utf8)
+    } else if infoType == ArrowType.ArrowBinary {
+        return .success(org_apache_arrow_flatbuf_Type_.binary)
     } else if infoType == ArrowType.ArrowBool {
         return .success(org_apache_arrow_flatbuf_Type_.bool)
     } else if infoType == ArrowType.ArrowDate32 || infoType == ArrowType.ArrowDate64 {
         return .success(org_apache_arrow_flatbuf_Type_.date)
+    } else if infoType == ArrowType.ArrowTime32 || infoType == ArrowType.ArrowTime64 {
+        return .success(org_apache_arrow_flatbuf_Type_.time)
     }
-
-    return .failure(.unknownType)
+    return .failure(.unknownType("Unable to find flatbuf type for Arrow type: \(infoType)"))
 }
 
-func toFBType(_ fbb: inout FlatBufferBuilder, infoType: ArrowType.Info) -> Result<Offset, ArrowError> {
+func toFBType(_ fbb: inout FlatBufferBuilder, arrowType: ArrowType) -> Result<Offset, ArrowError> {
+    let infoType = arrowType.info
     if infoType == ArrowType.ArrowInt8 || infoType == ArrowType.ArrowUInt8 {
         return .success(org_apache_arrow_flatbuf_Int.createInt(&fbb, bitWidth: 8, isSigned: infoType == ArrowType.ArrowInt8))
     } else if infoType == ArrowType.ArrowInt16 || infoType == ArrowType.ArrowUInt16 {
@@ -58,6 +63,8 @@ func toFBType(_ fbb: inout FlatBufferBuilder, infoType: ArrowType.Info) -> Resul
         return .success(org_apache_arrow_flatbuf_FloatingPoint.createFloatingPoint(&fbb, precision: .double))
     } else if infoType == ArrowType.ArrowString {
         return .success(org_apache_arrow_flatbuf_Utf8.endUtf8(&fbb, start: org_apache_arrow_flatbuf_Utf8.startUtf8(&fbb)))
+    } else if infoType == ArrowType.ArrowBinary {
+        return .success(org_apache_arrow_flatbuf_Binary.endBinary(&fbb, start: org_apache_arrow_flatbuf_Binary.startBinary(&fbb)))
     } else if infoType == ArrowType.ArrowBool {
         return .success(org_apache_arrow_flatbuf_Bool.endBool(&fbb, start: org_apache_arrow_flatbuf_Bool.startBool(&fbb)))
     } else if infoType == ArrowType.ArrowDate32 {
@@ -68,9 +75,19 @@ func toFBType(_ fbb: inout FlatBufferBuilder, infoType: ArrowType.Info) -> Resul
         let startOffset = org_apache_arrow_flatbuf_Date.startDate(&fbb)
         org_apache_arrow_flatbuf_Date.add(unit: .millisecond, &fbb)
         return .success(org_apache_arrow_flatbuf_Date.endDate(&fbb, start: startOffset))
+    } else if infoType == ArrowType.ArrowTime32 {
+        let startOffset = org_apache_arrow_flatbuf_Time.startTime(&fbb)
+        let timeType = arrowType as! ArrowTypeTime32
+        org_apache_arrow_flatbuf_Time.add(unit: timeType.unit == .Seconds ? .second : .millisecond, &fbb)
+        return .success(org_apache_arrow_flatbuf_Time.endTime(&fbb, start: startOffset))
+    } else if infoType == ArrowType.ArrowTime64 {
+        let startOffset = org_apache_arrow_flatbuf_Time.startTime(&fbb)
+        let timeType = arrowType as! ArrowTypeTime64
+        org_apache_arrow_flatbuf_Time.add(unit: timeType.unit == .Microseconds ? .microsecond : .nanosecond, &fbb)
+        return .success(org_apache_arrow_flatbuf_Time.endTime(&fbb, start: startOffset))
     }
-    
-    return .failure(.unknownType)
+
+    return .failure(.unknownType("Unable to add flatbuf type for Arrow type: \(infoType)"))
 }
 
 func addPadForAlignment(_ data: inout Data, alignment: Int = 8) {
diff --git a/swift/Arrow/Sources/Arrow/ChunkedArray.swift b/swift/Arrow/Sources/Arrow/ChunkedArray.swift
index c23c953290..edd4d494b1 100644
--- a/swift/Arrow/Sources/Arrow/ChunkedArray.swift
+++ b/swift/Arrow/Sources/Arrow/ChunkedArray.swift
@@ -22,7 +22,7 @@ public protocol AsString {
 }
 
 public class ChunkedArrayHolder {
-    public let type: ArrowType.Info
+    public let type: ArrowType
     public let length: UInt
     public let nullCount: UInt
     public let holder: Any
@@ -89,7 +89,7 @@ public class ChunkedArrayHolder {
 
 public class ChunkedArray<T> : AsString {
     public let arrays: [ArrowArray<T>]
-    public let type: ArrowType.Info
+    public let type: ArrowType
     public let nullCount: UInt
     public let length: UInt
     public var arrayCount: UInt {get{return UInt(self.arrays.count)}}
diff --git a/swift/Arrow/Tests/ArrowTests/ArrayTests.swift b/swift/Arrow/Tests/ArrowTests/ArrayTests.swift
index b20064d4e9..d36073e161 100644
--- a/swift/Arrow/Tests/ArrowTests/ArrayTests.swift
+++ b/swift/Arrow/Tests/ArrowTests/ArrayTests.swift
@@ -125,6 +125,90 @@ final class ArrayTests: XCTestCase {
         XCTAssertEqual(date64Array.length, 3)
         XCTAssertEqual(date64Array[1], date2)
         XCTAssertEqual(date64Array[0]!, date1)
+    }
+    
+    func testBinaryArray() throws {
+        let binaryBuilder = try ArrowArrayBuilders.loadBinaryArrayBuilder();
+        for i in 0..<100 {
+            if i % 10 == 9 {
+                binaryBuilder.append(nil)
+            } else {
+                binaryBuilder.append(("test" + String(i)).data(using:.utf8))
+            }
+        }
         
+        XCTAssertEqual(binaryBuilder.nullCount, 10)
+        XCTAssertEqual(binaryBuilder.length, 100)
+        XCTAssertEqual(binaryBuilder.capacity, 648)
+        let binaryArray = try binaryBuilder.finish()
+        XCTAssertEqual(binaryArray.length, 100)
+        for i in 0..<binaryArray.length {
+            if i % 10 == 9 {
+                XCTAssertEqual(try binaryArray.isNull(i), true)
+            } else {
+                let stringData = String(bytes: binaryArray[i]!, encoding: .utf8)
+                XCTAssertEqual(stringData, "test" + String(i))
+            }
+        }
+    }
+    
+    func testTime32Array() throws {
+        let milliBuilder = try ArrowArrayBuilders.loadTime32ArrayBuilder(.Milliseconds);
+        milliBuilder.append(100)
+        milliBuilder.append(1000000)
+        milliBuilder.append(nil)
+        XCTAssertEqual(milliBuilder.nullCount, 1)
+        XCTAssertEqual(milliBuilder.length, 3)
+        XCTAssertEqual(milliBuilder.capacity, 136)
+        let milliArray = try milliBuilder.finish()
+        let milliType = milliArray.arrowData.type as! ArrowTypeTime32
+        XCTAssertEqual(milliType.unit, .Milliseconds)
+        XCTAssertEqual(milliArray.length, 3)
+        XCTAssertEqual(milliArray[1], 1000000)
+        XCTAssertEqual(milliArray[2], nil)
+
+        let secBuilder = try ArrowArrayBuilders.loadTime32ArrayBuilder(.Seconds);
+        secBuilder.append(200)
+        secBuilder.append(nil)
+        secBuilder.append(2000011)
+        XCTAssertEqual(secBuilder.nullCount, 1)
+        XCTAssertEqual(secBuilder.length, 3)
+        XCTAssertEqual(secBuilder.capacity, 136)
+        let secArray = try secBuilder.finish()
+        let secType = secArray.arrowData.type as! ArrowTypeTime32
+        XCTAssertEqual(secType.unit, .Seconds)
+        XCTAssertEqual(secArray.length, 3)
+        XCTAssertEqual(secArray[1], nil)
+        XCTAssertEqual(secArray[2], 2000011)
+    }
+    
+    func testTime64Array() throws {
+        let nanoBuilder = try ArrowArrayBuilders.loadTime64ArrayBuilder(.Nanoseconds);
+        nanoBuilder.append(10000)
+        nanoBuilder.append(nil)
+        nanoBuilder.append(123456789)
+        XCTAssertEqual(nanoBuilder.nullCount, 1)
+        XCTAssertEqual(nanoBuilder.length, 3)
+        XCTAssertEqual(nanoBuilder.capacity, 264)
+        let nanoArray = try nanoBuilder.finish()
+        let nanoType = nanoArray.arrowData.type as! ArrowTypeTime64
+        XCTAssertEqual(nanoType.unit, .Nanoseconds)
+        XCTAssertEqual(nanoArray.length, 3)
+        XCTAssertEqual(nanoArray[1], nil)
+        XCTAssertEqual(nanoArray[2], 123456789)
+
+        let microBuilder = try ArrowArrayBuilders.loadTime64ArrayBuilder(.Microseconds);
+        microBuilder.append(nil)
+        microBuilder.append(20000)
+        microBuilder.append(987654321)
+        XCTAssertEqual(microBuilder.nullCount, 1)
+        XCTAssertEqual(microBuilder.length, 3)
+        XCTAssertEqual(microBuilder.capacity, 264)
+        let microArray = try microBuilder.finish()
+        let microType = microArray.arrowData.type as! ArrowTypeTime64
+        XCTAssertEqual(microType.unit, .Microseconds)
+        XCTAssertEqual(microArray.length, 3)
+        XCTAssertEqual(microArray[1], 20000)
+        XCTAssertEqual(microArray[2], 987654321)
     }
 }
diff --git a/swift/Arrow/Tests/ArrowTests/IPCTests.swift b/swift/Arrow/Tests/ArrowTests/IPCTests.swift
index 1aa6873dcb..5a7721360d 100644
--- a/swift/Arrow/Tests/ArrowTests/IPCTests.swift
+++ b/swift/Arrow/Tests/ArrowTests/IPCTests.swift
@@ -20,11 +20,11 @@ import FlatBuffers
 @testable import Arrow
 
 @discardableResult
-func checkBoolRecordBatch(_ result: Result<[RecordBatch], ArrowError>) throws -> [RecordBatch] {
+func checkBoolRecordBatch(_ result: Result<ArrowReader.ArrowReaderResult, ArrowError>) throws -> [RecordBatch] {
     let recordBatches: [RecordBatch]
     switch result {
-    case .success(let rbBatches):
-        recordBatches = rbBatches
+    case .success(let result):
+        recordBatches = result.batches
     case .failure(let error):
         throw error
     }
@@ -35,9 +35,9 @@ func checkBoolRecordBatch(_ result: Result<[RecordBatch], ArrowError>) throws ->
         XCTAssertEqual(recordBatch.columns.count, 2)
         XCTAssertEqual(recordBatch.schema.fields.count, 2)
         XCTAssertEqual(recordBatch.schema.fields[0].name, "one")
-        XCTAssertEqual(recordBatch.schema.fields[0].type, ArrowType.ArrowBool)
+        XCTAssertEqual(recordBatch.schema.fields[0].type.info, ArrowType.ArrowBool)
         XCTAssertEqual(recordBatch.schema.fields[1].name, "two")
-        XCTAssertEqual(recordBatch.schema.fields[1].type, ArrowType.ArrowString)
+        XCTAssertEqual(recordBatch.schema.fields[1].type.info, ArrowType.ArrowString)
         for index in 0..<recordBatch.length {
             let column = recordBatch.columns[0]
             let str = column.array as! AsString
@@ -66,21 +66,20 @@ final class IPCFileReaderTests: XCTestCase {
         let result = arrowReader.fromFile(fileURL)
         let recordBatches: [RecordBatch]
         switch result {
-        case .success(let rbBatches):
-            recordBatches = rbBatches
+        case .success(let result):
+            recordBatches = result.batches
         case .failure(let error):
             throw error
         }
-
         XCTAssertEqual(recordBatches.count, 1)
         for recordBatch in recordBatches {
             XCTAssertEqual(recordBatch.length, 5)
             XCTAssertEqual(recordBatch.columns.count, 2)
             XCTAssertEqual(recordBatch.schema.fields.count, 2)
             XCTAssertEqual(recordBatch.schema.fields[0].name, "one")
-            XCTAssertEqual(recordBatch.schema.fields[0].type, ArrowType.ArrowDouble)
+            XCTAssertEqual(recordBatch.schema.fields[0].type.info, ArrowType.ArrowDouble)
             XCTAssertEqual(recordBatch.schema.fields[1].name, "two")
-            XCTAssertEqual(recordBatch.schema.fields[1].type, ArrowType.ArrowString)
+            XCTAssertEqual(recordBatch.schema.fields[1].type.info, ArrowType.ArrowString)
             for index in 0..<recordBatch.length {
                 let column = recordBatch.columns[1]
                 let str = column.array as! AsString
@@ -99,8 +98,7 @@ final class IPCFileReaderTests: XCTestCase {
         let arrowReader = ArrowReader()
         try checkBoolRecordBatch(arrowReader.fromFile(fileURL))
     }
-    
-    
+
     func testFileWriter_bool() throws {
         //read existing file
         let fileURL = currentDirectory().appendingPathComponent("../../testdata_bool.arrow")
@@ -108,33 +106,30 @@ final class IPCFileReaderTests: XCTestCase {
         let fileRBs = try checkBoolRecordBatch(arrowReader.fromFile(fileURL))
         let arrowWriter = ArrowWriter()
         //write data from file to a stream
-        switch arrowWriter.toStream(fileRBs[0].schema, batches: fileRBs) {
+        let writerInfo = ArrowWriter.Info(.recordbatch, schema: fileRBs[0].schema, batches: fileRBs)
+        switch arrowWriter.toStream(writerInfo) {
         case .success(let writeData):
             //read stream back into recordbatches
             try checkBoolRecordBatch(arrowReader.fromStream(writeData))
         case .failure(let error):
             throw error
         }
-
         //write file record batches to another file
         let outputUrl = currentDirectory().appendingPathComponent("../../testfilewriter_bool.arrow")
-        switch arrowWriter.toFile(outputUrl, schema: fileRBs[0].schema, batches: fileRBs) {
+        switch arrowWriter.toFile(outputUrl, info: writerInfo) {
         case .success(_):
             try checkBoolRecordBatch(arrowReader.fromFile(outputUrl))
         case .failure(let error):
             throw error
         }
-        
     }
-
     func makeSchema() -> ArrowSchema {
         let schemaBuilder = ArrowSchema.Builder();
-        return schemaBuilder.addField("col1", type: ArrowType.ArrowUInt8, isNullable: true)
-            .addField("col2", type: ArrowType.ArrowString, isNullable: false)
-            .addField("col3", type: ArrowType.ArrowDate32, isNullable: false)
+        return schemaBuilder.addField("col1", type: ArrowType(ArrowType.ArrowUInt8), isNullable: true)
+            .addField("col2", type: ArrowType(ArrowType.ArrowString), isNullable: false)
+            .addField("col3", type: ArrowType(ArrowType.ArrowDate32), isNullable: false)
             .finish()
     }
-
     func makeRecordBatch() throws -> RecordBatch {
         let uint8Builder: NumberArrayBuilder<UInt8> = try ArrowArrayBuilders.loadNumberArrayBuilder();
         uint8Builder.append(10)
@@ -153,7 +148,6 @@ final class IPCFileReaderTests: XCTestCase {
         date32Builder.append(date2)
         date32Builder.append(date1)
         date32Builder.append(date2)
-
         let intHolder = ArrowArrayHolder(try uint8Builder.finish())
         let stringHolder = ArrowArrayHolder(try stringBuilder.finish())
         let date32Holder = ArrowArrayHolder(try date32Builder.finish())
@@ -170,27 +164,29 @@ final class IPCFileReaderTests: XCTestCase {
         }
     }
     
-    func testInMemoryToFromStream() throws {
+    func testRBInMemoryToFromStream() throws {
         //read existing file
         let schema = makeSchema()
         let recordBatch = try makeRecordBatch()
         let arrowWriter = ArrowWriter()
-        switch arrowWriter.toStream(schema, batches: [recordBatch]) {
+        let writerInfo = ArrowWriter.Info(.recordbatch, schema: schema, batches: [recordBatch])
+        switch arrowWriter.toStream(writerInfo) {
         case .success(let writeData):
             let arrowReader = ArrowReader()
             switch arrowReader.fromStream(writeData) {
-            case .success(let recordBatches):
+            case .success(let result):
+                let recordBatches = result.batches
                 XCTAssertEqual(recordBatches.count, 1)
                 for recordBatch in recordBatches {
                     XCTAssertEqual(recordBatch.length, 4)
                     XCTAssertEqual(recordBatch.columns.count, 3)
                     XCTAssertEqual(recordBatch.schema.fields.count, 3)
                     XCTAssertEqual(recordBatch.schema.fields[0].name, "col1")
-                    XCTAssertEqual(recordBatch.schema.fields[0].type, ArrowType.ArrowUInt8)
+                    XCTAssertEqual(recordBatch.schema.fields[0].type.info, ArrowType.ArrowUInt8)
                     XCTAssertEqual(recordBatch.schema.fields[1].name, "col2")
-                    XCTAssertEqual(recordBatch.schema.fields[1].type, ArrowType.ArrowString)
+                    XCTAssertEqual(recordBatch.schema.fields[1].type.info, ArrowType.ArrowString)
                     XCTAssertEqual(recordBatch.schema.fields[2].name, "col3")
-                    XCTAssertEqual(recordBatch.schema.fields[2].type, ArrowType.ArrowDate32)
+                    XCTAssertEqual(recordBatch.schema.fields[2].type.info, ArrowType.ArrowDate32)
                     let dateVal = "\((recordBatch.columns[2].array as! AsString).asString(0))"
                     XCTAssertEqual(dateVal, "2014-09-10 00:00:00 +0000")
                     let stringVal = "\((recordBatch.columns[1].array as! AsString).asString(1))"
@@ -209,4 +205,143 @@ final class IPCFileReaderTests: XCTestCase {
             throw error
         }
     }
+    
+    func testSchemaInMemoryToFromStream() throws {
+        //read existing file
+        let schema = makeSchema()
+        let arrowWriter = ArrowWriter()
+        let writerInfo = ArrowWriter.Info(.schema, schema: schema)
+        switch arrowWriter.toStream(writerInfo) {
+        case .success(let writeData):
+            let arrowReader = ArrowReader()
+            switch arrowReader.fromStream(writeData) {
+            case .success(let result):
+                XCTAssertNotNil(result.schema)
+                let schema  = result.schema!
+                XCTAssertEqual(schema.fields.count, 3)
+                XCTAssertEqual(schema.fields[0].name, "col1")
+                XCTAssertEqual(schema.fields[0].type.info, ArrowType.ArrowUInt8)
+                XCTAssertEqual(schema.fields[1].name, "col2")
+                XCTAssertEqual(schema.fields[1].type.info, ArrowType.ArrowString)
+                XCTAssertEqual(schema.fields[2].name, "col3")
+                XCTAssertEqual(schema.fields[2].type.info, ArrowType.ArrowDate32)
+            case.failure(let error):
+                throw error
+            }
+        case .failure(let error):
+            throw error
+        }
+    }
+    
+    func makeBinaryDataset() throws -> (ArrowSchema, RecordBatch) {
+        let schemaBuilder = ArrowSchema.Builder();
+        let schema = schemaBuilder.addField("binary", type: ArrowType(ArrowType.ArrowBinary), isNullable: false)
+            .finish()
+        
+        let binaryBuilder = try ArrowArrayBuilders.loadBinaryArrayBuilder();
+        binaryBuilder.append("test10".data(using: .utf8))
+        binaryBuilder.append("test22".data(using: .utf8))
+        binaryBuilder.append("test33".data(using: .utf8))
+        binaryBuilder.append("test44".data(using: .utf8))
+        
+        let binaryHolder = ArrowArrayHolder(try binaryBuilder.finish())
+        let result = RecordBatch.Builder()
+            .addColumn("binary", arrowArray: binaryHolder)
+            .finish()
+        switch result {
+        case .success(let recordBatch):
+            return (schema, recordBatch)
+        case .failure(let error):
+            throw error
+        }
+    }
+    
+    func makeTimeDataset() throws -> (ArrowSchema, RecordBatch) {
+        let schemaBuilder = ArrowSchema.Builder();
+        let schema = schemaBuilder.addField("time64", type: ArrowTypeTime64(.Microseconds), isNullable: false)
+            .addField("time32", type: ArrowTypeTime32(.Milliseconds), isNullable: false)
+            .finish()
+        
+        let time64Builder = try ArrowArrayBuilders.loadTime64ArrayBuilder(.Nanoseconds);
+        time64Builder.append(12345678)
+        time64Builder.append(1)
+        time64Builder.append(nil)
+        time64Builder.append(98765432)
+        let time32Builder = try ArrowArrayBuilders.loadTime32ArrayBuilder(.Milliseconds);
+        time32Builder.append(1)
+        time32Builder.append(2)
+        time32Builder.append(nil)
+        time32Builder.append(3)
+        
+        let time64Holder = ArrowArrayHolder(try time64Builder.finish())
+        let time32Holder = ArrowArrayHolder(try time32Builder.finish())
+        let result = RecordBatch.Builder()
+            .addColumn("time64", arrowArray: time64Holder)
+            .addColumn("time32", arrowArray: time32Holder)
+            .finish()
+        switch result {
+        case .success(let recordBatch):
+            return (schema, recordBatch)
+        case .failure(let error):
+            throw error
+        }
+    }
+    
+    func testBinaryInMemroyToFromStream() throws {
+        let dataset = try makeBinaryDataset();
+        let writerInfo = ArrowWriter.Info(.recordbatch, schema: dataset.0, batches: [dataset.1])
+        let arrowWriter = ArrowWriter()
+        switch arrowWriter.toStream(writerInfo) {
+        case .success(let writeData):
+            let arrowReader = ArrowReader()
+            switch arrowReader.fromStream(writeData) {
+            case .success(let result):
+                XCTAssertNotNil(result.schema)
+                let schema  = result.schema!
+                XCTAssertEqual(schema.fields.count, 1)
+                XCTAssertEqual(schema.fields[0].name, "binary")
+                XCTAssertEqual(schema.fields[0].type.info, ArrowType.ArrowBinary)
+                XCTAssertEqual(result.batches.count, 1)
+                let recordBatch = result.batches[0]
+                XCTAssertEqual(recordBatch.length, 4)
+                let stringVal = "\((recordBatch.columns[0].array as! AsString).asString(1))"
+                XCTAssertEqual(stringVal, "test22")
+            case.failure(let error):
+                throw error
+            }
+        case .failure(let error):
+            throw error
+        }
+    }
+    
+    func testTimeInMemroyToFromStream() throws {
+        let dataset = try makeTimeDataset();
+        let writerInfo = ArrowWriter.Info(.recordbatch, schema: dataset.0, batches: [dataset.1])
+        let arrowWriter = ArrowWriter()
+        switch arrowWriter.toStream(writerInfo) {
+        case .success(let writeData):
+            let arrowReader = ArrowReader()
+            switch arrowReader.fromStream(writeData) {
+            case .success(let result):
+                XCTAssertNotNil(result.schema)
+                let schema  = result.schema!
+                XCTAssertEqual(schema.fields.count, 2)
+                XCTAssertEqual(schema.fields[0].name, "time64")
+                XCTAssertEqual(schema.fields[0].type.info, ArrowType.ArrowTime64)
+                XCTAssertEqual(schema.fields[1].name, "time32")
+                XCTAssertEqual(schema.fields[1].type.info, ArrowType.ArrowTime32)
+                XCTAssertEqual(result.batches.count, 1)
+                let recordBatch = result.batches[0]
+                XCTAssertEqual(recordBatch.length, 4)
+                let stringVal = "\((recordBatch.columns[0].array as! AsString).asString(0))"
+                XCTAssertEqual(stringVal, "12345678")
+                let stringVal2 = "\((recordBatch.columns[1].array as! AsString).asString(3))"
+                XCTAssertEqual(stringVal2, "3")
+            case.failure(let error):
+                throw error
+            }
+        case .failure(let error):
+            throw error
+        }
+    }
 }
diff --git a/swift/Arrow/Tests/ArrowTests/RecordBatchTests.swift b/swift/Arrow/Tests/ArrowTests/RecordBatchTests.swift
index 5da4461765..9a469bfbd8 100644
--- a/swift/Arrow/Tests/ArrowTests/RecordBatchTests.swift
+++ b/swift/Arrow/Tests/ArrowTests/RecordBatchTests.swift
@@ -38,10 +38,10 @@ final class RecordBatchTests: XCTestCase {
             let schema = recordBatch.schema
             XCTAssertEqual(schema.fields.count, 2)
             XCTAssertEqual(schema.fields[0].name, "col1")
-            XCTAssertEqual(schema.fields[0].type, ArrowType.ArrowUInt8)
+            XCTAssertEqual(schema.fields[0].type.info, ArrowType.ArrowUInt8)
             XCTAssertEqual(schema.fields[0].isNullable, false)
             XCTAssertEqual(schema.fields[1].name, "col2")
-            XCTAssertEqual(schema.fields[1].type, ArrowType.ArrowString)
+            XCTAssertEqual(schema.fields[1].type.info, ArrowType.ArrowString)
             XCTAssertEqual(schema.fields[1].isNullable, false)
             XCTAssertEqual(recordBatch.columns.count, 2)
             let col1: ArrowArray<UInt8> = recordBatch.data(for: 0);
diff --git a/swift/Arrow/Tests/ArrowTests/TableTests.swift b/swift/Arrow/Tests/ArrowTests/TableTests.swift
index a3ed87d321..73ca3d3726 100644
--- a/swift/Arrow/Tests/ArrowTests/TableTests.swift
+++ b/swift/Arrow/Tests/ArrowTests/TableTests.swift
@@ -21,15 +21,15 @@ import XCTest
 final class TableTests: XCTestCase {
     func testSchema() throws {
         let schemaBuilder = ArrowSchema.Builder();
-        let schema = schemaBuilder.addField("col1", type: ArrowType.ArrowInt8, isNullable: true)
-            .addField("col2", type: ArrowType.ArrowBool, isNullable: false)
+        let schema = schemaBuilder.addField("col1", type: ArrowType(ArrowType.ArrowInt8), isNullable: true)
+            .addField("col2", type: ArrowType(ArrowType.ArrowBool), isNullable: false)
             .finish()
         XCTAssertEqual(schema.fields.count, 2)
         XCTAssertEqual(schema.fields[0].name, "col1")
-        XCTAssertEqual(schema.fields[0].type, ArrowType.ArrowInt8)
+        XCTAssertEqual(schema.fields[0].type.info, ArrowType.ArrowInt8)
         XCTAssertEqual(schema.fields[0].isNullable, true)
         XCTAssertEqual(schema.fields[1].name, "col2")
-        XCTAssertEqual(schema.fields[1].type, ArrowType.ArrowBool)
+        XCTAssertEqual(schema.fields[1].type.info, ArrowType.ArrowBool)
         XCTAssertEqual(schema.fields[1].isNullable, false)
     }
     
@@ -55,13 +55,13 @@ final class TableTests: XCTestCase {
         let schema = table.schema
         XCTAssertEqual(schema.fields.count, 3)
         XCTAssertEqual(schema.fields[0].name, "col1")
-        XCTAssertEqual(schema.fields[0].type, ArrowType.ArrowUInt8)
+        XCTAssertEqual(schema.fields[0].type.info, ArrowType.ArrowUInt8)
         XCTAssertEqual(schema.fields[0].isNullable, false)
         XCTAssertEqual(schema.fields[1].name, "col2")
-        XCTAssertEqual(schema.fields[1].type, ArrowType.ArrowString)
+        XCTAssertEqual(schema.fields[1].type.info, ArrowType.ArrowString)
         XCTAssertEqual(schema.fields[1].isNullable, false)
         XCTAssertEqual(schema.fields[1].name, "col2")
-        XCTAssertEqual(schema.fields[1].type, ArrowType.ArrowString)
+        XCTAssertEqual(schema.fields[1].type.info, ArrowType.ArrowString)
         XCTAssertEqual(schema.fields[1].isNullable, false)
         XCTAssertEqual(table.columns.count, 3)
         let col1: ChunkedArray<UInt8> = table.columns[0].data();
@@ -107,13 +107,13 @@ final class TableTests: XCTestCase {
         let schema = table.schema
         XCTAssertEqual(schema.fields.count, 3)
         XCTAssertEqual(schema.fields[0].name, "col1")
-        XCTAssertEqual(schema.fields[0].type, ArrowType.ArrowUInt8)
+        XCTAssertEqual(schema.fields[0].type.info, ArrowType.ArrowUInt8)
         XCTAssertEqual(schema.fields[0].isNullable, false)
         XCTAssertEqual(schema.fields[1].name, "col2")
-        XCTAssertEqual(schema.fields[1].type, ArrowType.ArrowString)
+        XCTAssertEqual(schema.fields[1].type.info, ArrowType.ArrowString)
         XCTAssertEqual(schema.fields[1].isNullable, false)
         XCTAssertEqual(schema.fields[1].name, "col2")
-        XCTAssertEqual(schema.fields[1].type, ArrowType.ArrowString)
+        XCTAssertEqual(schema.fields[1].type.info, ArrowType.ArrowString)
         XCTAssertEqual(schema.fields[1].isNullable, false)
         XCTAssertEqual(table.columns.count, 3)
         let col1: ChunkedArray<UInt8> = table.columns[0].data();
@@ -149,10 +149,10 @@ final class TableTests: XCTestCase {
             let schema = table.schema
             XCTAssertEqual(schema.fields.count, 2)
             XCTAssertEqual(schema.fields[0].name, "col1")
-            XCTAssertEqual(schema.fields[0].type, ArrowType.ArrowUInt8)
+            XCTAssertEqual(schema.fields[0].type.info, ArrowType.ArrowUInt8)
             XCTAssertEqual(schema.fields[0].isNullable, false)
             XCTAssertEqual(schema.fields[1].name, "col2")
-            XCTAssertEqual(schema.fields[1].type, ArrowType.ArrowString)
+            XCTAssertEqual(schema.fields[1].type.info, ArrowType.ArrowString)
             XCTAssertEqual(schema.fields[1].isNullable, false)
             XCTAssertEqual(table.columns.count, 2)
             let col1: ChunkedArray<UInt8> = table.columns[0].data();