dongjoon-hyun opened a new pull request, #551:
URL: https://github.com/apache/spark-connect-swift/pull/551
### What changes were proposed in this pull request?
This PR aims to support type-safe getters and null-check inspection on `Row`.
Specifically, this PR introduces:
1. **Null checking**:
- `isNullAt(_ i: Int) throws -> Bool`
- `isNullAt(_ name: String) throws -> Bool`
2. **Generic `getAs` accessors**:
- `getAs<T>(_ i: Int, _ type: T.Type = T.self) throws -> T`
- `getAs<T>(_ name: String, _ type: T.Type = T.self) throws -> T`
- Supports both contextual type inference (`let val: Int = try
row.getAs(0)`) and explicit type passing (`try row.getAs(0, Int.self)`).
- Gracefully handles optional types: requesting an optional type (e.g.
`String?.self`) on a `nil` column returns `nil` instead of throwing.
3. **Convenience typed getters (Index and column name overloads)**:
- `getAsBool(_ name: String) throws -> Bool` (alongside existing
`getAsBool(_ i: Int)`)
- `getAsInt(_ i: Int)` / `getAsInt(_ name: String)`: supports type
coercion from any `FixedWidthInteger` (`Int8`, `Int16`, `Int32`, `Int64`,
`Int`), throwing `InvalidType` on integer overflow.
- `getAsInt64(_ i: Int)` / `getAsInt64(_ name: String)`: supports type
coercion from any `FixedWidthInteger`.
- `getAsDouble(_ i: Int)` / `getAsDouble(_ name: String)`: supports
`Double` and `Float` widening.
- `getAsString(_ i: Int)` / `getAsString(_ name: String)`
- `getAsDate(_ i: Int)` / `getAsDate(_ name: String)`: supports `Date`
and `TimestampNanos.date`.
- `getAsTimestampNanos(_ i: Int)` / `getAsTimestampNanos(_ name:
String)`: supports `TimestampNanos` and `Date`.
- `getAsDecimal(_ i: Int)` / `getAsDecimal(_ name: String)`: supports
`Decimal` and `FixedWidthInteger`.
4. **Standardized error handling**:
- Throws `SparkConnectError.InvalidArgument` if column index is out of
bounds.
- Throws `SparkConnectError.UnsupportedOperation` if accessing by column
name on a `Row` without a schema.
- Throws `SparkConnectError.ColumnNotFound` if accessing by an unknown
column name.
- Throws `SparkConnectError.InvalidType` if the column value is `nil`
(for non-optional `T`), type mismatch, or integer overflow occurs.
### Why are the changes needed?
Previously, `Row` only provided untyped `get(_ i: Int) throws -> Sendable`
and a single typed getter `getAsBool(_ i: Int)`. Users had to manually downcast
column values (e.g., `try row.get(i) as? Int` or `try row["name"] as? String`).
Furthermore, query results decoded from Arrow batches in
`DataFrame+Actions.swift` hold sized integer types (`Int8`, `Int16`, `Int32`,
`Int64`). A direct cast such as `as? Int` or `as? Double` would fail at runtime
even if the data represented an integer or floating-point value.
These new APIs provide idiomatic, type-safe field extraction with automatic
type coercion, bringing feature parity with Scala/PySpark `Row`.
### Does this PR introduce _any_ user-facing change?
No behavior change because this PR adds only new public methods (`isNullAt`,
`getAs`, `getAsInt`, `getAsInt64`, `getAsDouble`, `getAsString`, `getAsDate`,
`getAsTimestampNanos`, `getAsDecimal`, and `getAsBool(_ name: String)`) to
`Row`.
### How was this patch tested?
Pass the CIs with the newly added unit test cases.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Gemini 3.8 Flash (High)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]