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-swift.git
The following commit(s) were added to refs/heads/main by this push:
new f7564cf fix: Serialize `bitWidth` field of `FlatBuffers` Time type
for `time64` (#190)
f7564cf is described below
commit f7564cf732fc3a43ba8933bc24e997a0dba7f5c8
Author: Dongjoon Hyun <[email protected]>
AuthorDate: Wed Aug 5 23:51:55 2026 -0700
fix: Serialize `bitWidth` field of `FlatBuffers` Time type for `time64`
(#190)
## What's Changed
The vendored `ArrowWriterHelper` did not serialize the `bitWidth` field
of the
FlatBuffers `Time` type when writing a `time64` schema. Since the
field's
FlatBuffers default is 32, a `time64` column was encoded as `Time(unit,
32)`,
and servers validating the schema rejected the column with:
```
[UNSUPPORTED_ARROWTYPE] Unsupported arrow type Time(NANOSECOND, 32)
```
This adds `bitWidth: 64` to the `.time64` case in `toFBType`. `time32`
is
unaffected because 32 is the correct default there.
## Testing
Added `TimeBitWidthTests`, which serializes a schema via
`ArrowWriter.toMessage(_:)` and parses the resulting FlatBuffers message
to
assert that `time64` (microseconds/nanoseconds) encodes `bitWidth` 64
and
`time32` (seconds/milliseconds) encodes 32.
The existing round-trip test (`testTimeInMemoryToFromStream`) cannot
catch
this regression because the Swift reader dispatches on `unit` only and
ignores `bitWidth`.
---
Sources/Arrow/ArrowWriterHelper.swift | 1 +
Tests/ArrowTests/TimeBitWidthTests.swift | 47 ++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/Sources/Arrow/ArrowWriterHelper.swift
b/Sources/Arrow/ArrowWriterHelper.swift
index 4a95499..4d7e2fd 100644
--- a/Sources/Arrow/ArrowWriterHelper.swift
+++ b/Sources/Arrow/ArrowWriterHelper.swift
@@ -101,6 +101,7 @@ func toFBType( // swiftlint:disable:this
cyclomatic_complexity function_body_len
let startOffset = org_apache_arrow_flatbuf_Time.startTime(&fbb)
if let timeType = arrowType as? ArrowTypeTime64 {
org_apache_arrow_flatbuf_Time.add(unit: timeType.unit ==
.microseconds ? .microsecond : .nanosecond, &fbb)
+ org_apache_arrow_flatbuf_Time.add(bitWidth: 64, &fbb)
return .success(org_apache_arrow_flatbuf_Time.endTime(&fbb, start:
startOffset))
}
diff --git a/Tests/ArrowTests/TimeBitWidthTests.swift
b/Tests/ArrowTests/TimeBitWidthTests.swift
new file mode 100644
index 0000000..8868f2a
--- /dev/null
+++ b/Tests/ArrowTests/TimeBitWidthTests.swift
@@ -0,0 +1,47 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+import XCTest
+import FlatBuffers
+@testable import Arrow
+
+final class TimeBitWidthTests: XCTestCase {
+ private func timeBitWidth(_ arrowType: ArrowType) throws -> Int32 {
+ let schema = ArrowSchema.Builder()
+ .addField("col", type: arrowType, isNullable: false)
+ .finish()
+ let writer = ArrowWriter()
+ let data: Data
+ switch writer.toMessage(schema) {
+ case .success(let result): data = result
+ case .failure(let error): throw error
+ }
+ var buffer = ByteBuffer(data: data)
+ let message: org_apache_arrow_flatbuf_Message = getRoot(byteBuffer:
&buffer)
+ let fbSchema: org_apache_arrow_flatbuf_Schema = message.header(type:
org_apache_arrow_flatbuf_Schema.self)!
+ let field = fbSchema.fields(at: 0)!
+ let timeType: org_apache_arrow_flatbuf_Time = field.type(type:
org_apache_arrow_flatbuf_Time.self)!
+ return timeType.bitWidth
+ }
+
+ func testTimeBitWidthSerialization() throws {
+ XCTAssertEqual(try timeBitWidth(ArrowTypeTime64(.nanoseconds)), 64)
+ XCTAssertEqual(try timeBitWidth(ArrowTypeTime64(.microseconds)), 64)
+ XCTAssertEqual(try timeBitWidth(ArrowTypeTime32(.milliseconds)), 32)
+ XCTAssertEqual(try timeBitWidth(ArrowTypeTime32(.seconds)), 32)
+ }
+}