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

MaxGekk pushed a commit to branch branch-4.x
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-4.x by this push:
     new 858da1729be4 [SPARK-54203][SQL] Support TimeType in 
RowToColumnConverter
858da1729be4 is described below

commit 858da1729be4c468395dcba8da55e1a3d7eb35f4
Author: Maxim Gekk <[email protected]>
AuthorDate: Sat Jun 20 09:16:51 2026 +0200

    [SPARK-54203][SQL] Support TimeType in RowToColumnConverter
    
    ### What changes were proposed in this pull request?
    
    Add a `TimeType` branch (via the abstract `AnyTimeType`) to 
`RowToColumnConverter.getConverterForType` in 
`sql/core/.../execution/Columnar.scala`, routing TIME columns through the 
long-backed `LongConverter` path. TIME is stored as nanos-of-day `Long`, and 
the on/off-heap column vectors already reserve long storage for it 
(`OnHeapColumnVector`, `OffHeapColumnVector`), so no column-vector changes are 
required.
    
    ### Why are the changes needed?
    
    Previously `getConverterForType` handled `LongType | TimestampType | 
TimestampNTZType | DayTimeIntervalType` (all long-backed) but had no `TimeType` 
case, so a TIME column fell through to `unsupportedDataTypeError`. This blocked 
row-to-column conversion paths (e.g. `RowToColumnar` transitions, vectorized 
execution) for the TIME data type.
    
    This is a sub-task of 
[SPARK-57550](https://issues.apache.org/jira/browse/SPARK-57550) (Extend 
support for the TIME data type).
    
    ### Does this PR introduce _any_ user-facing change?
    
    No. It enables an existing code path for the TIME data type that previously 
threw an unsupported-type error.
    
    ### How was this patch tested?
    
    Added round-trip and null-handling tests for `TimeType` to 
`RowToColumnConverterSuite`:
    - `TimeType column roundtrip` (precisions 0, 3, 6; values including `0L` 
and end-of-day `86399999999999L`)
    - `TimeType column with nulls`
    
    Ran `build/sbt 'sql/testOnly *RowToColumnConverterSuite'` (all 13 tests 
pass) and scalastyle on the sql module (0 errors).
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Yes, Generated-by: Cursor.
    
    Closes #56613 from MaxGekk/time-RowToColumnConverter.
    
    Authored-by: Maxim Gekk <[email protected]>
    Signed-off-by: Max Gekk <[email protected]>
    (cherry picked from commit a7ad18b858da75f4ae8e5c4691d77d7944e25685)
    Signed-off-by: Max Gekk <[email protected]>
---
 .../org/apache/spark/sql/execution/Columnar.scala  |  3 ++-
 .../sql/execution/RowToColumnConverterSuite.scala  | 24 ++++++++++++++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git 
a/sql/core/src/main/scala/org/apache/spark/sql/execution/Columnar.scala 
b/sql/core/src/main/scala/org/apache/spark/sql/execution/Columnar.scala
index 81fc5d2c1f73..5c98e3685327 100644
--- a/sql/core/src/main/scala/org/apache/spark/sql/execution/Columnar.scala
+++ b/sql/core/src/main/scala/org/apache/spark/sql/execution/Columnar.scala
@@ -265,7 +265,8 @@ private object RowToColumnConverter {
       case ShortType => ShortConverter
       case IntegerType | DateType | _: YearMonthIntervalType => IntConverter
       case FloatType => FloatConverter
-      case LongType | TimestampType | TimestampNTZType | _: 
DayTimeIntervalType => LongConverter
+      case LongType | TimestampType | TimestampNTZType | _: 
DayTimeIntervalType | _: TimeType =>
+        LongConverter
       case DoubleType => DoubleConverter
       case StringType => StringConverter
       case _: GeographyType | _: GeometryType => BinaryViewConverter
diff --git 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/RowToColumnConverterSuite.scala
 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/RowToColumnConverterSuite.scala
index 96d7fb6fbd09..d1d8e89de391 100644
--- 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/RowToColumnConverterSuite.scala
+++ 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/RowToColumnConverterSuite.scala
@@ -184,6 +184,30 @@ class RowToColumnConverterSuite extends SparkFunSuite {
     assert(vectors.head.getTimestampLTZNanos(2) === 
TimestampNanosVal.fromParts(200L, 1.toShort))
   }
 
+  test("TimeType column roundtrip") {
+    Seq(0, 3, 6).foreach { precision =>
+      val schema = StructType(Seq(StructField("t", TimeType(precision))))
+      val values = Seq(0L, 12L * 60 * 60 * 1000 * 1000 * 1000, 86399999999999L)
+      val rows = values.map(v => InternalRow(v))
+      val vectors = convertRows(rows, schema)
+      values.zipWithIndex.foreach { case (v, i) =>
+        assert(vectors.head.getLong(i) === v)
+      }
+    }
+  }
+
+  test("TimeType column with nulls") {
+    val schema = StructType(Seq(StructField("t", TimeType(6), nullable = 
true)))
+    val rows = Seq(
+      InternalRow(0L),
+      InternalRow(null),
+      InternalRow(86399999999999L))
+    val vectors = convertRows(rows, schema)
+    assert(vectors.head.getLong(0) === 0L)
+    assert(vectors.head.isNullAt(1))
+    assert(vectors.head.getLong(2) === 86399999999999L)
+  }
+
   test("multiple columns") {
     val schema = StructType(
       Seq(StructField("s", ShortType), StructField("i", IntegerType), 
StructField("l", LongType)))


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to