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

jiayu pushed a commit to branch fix/2608-rasterudt-delta-write
in repository https://gitbox.apache.org/repos/asf/sedona.git

commit cb6c34c21f966bc7e19b631afdb5aaa42e6051bb
Author: Jia Yu <[email protected]>
AuthorDate: Tue Feb 10 00:08:52 2026 -0800

    [GH-2608] Fix RasterUDT JSON schema serialization by stripping $ suffix
    
    RasterUDT is a Scala case object whose getClass.getName returns
    'RasterUDT$' with a trailing $ sign. Spark's UserDefinedType.jsonValue
    uses this class name in the JSON schema. When Delta/Parquet tries to
    reconstruct the UDT via Class.forName(...).getConstructor().newInstance(),
    it fails because the singleton object's constructor is private.
    
    This fix adds a jsonValue override (identical to the existing fix in
    GeometryUDT and GeographyUDT) that strips the trailing $ from the
    class name, allowing correct round-trip serialization.
    
    Closes #2608
    Closes #2347
---
 .../scala/org/apache/spark/sql/sedona_sql/UDT/RasterUDT.scala    | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git 
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/UDT/RasterUDT.scala
 
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/UDT/RasterUDT.scala
index ee05cd1521..a34b372211 100644
--- 
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/UDT/RasterUDT.scala
+++ 
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/UDT/RasterUDT.scala
@@ -21,6 +21,8 @@ package org.apache.spark.sql.sedona_sql.UDT
 import org.apache.sedona.common.raster.serde.Serde
 import org.apache.spark.sql.types.{BinaryType, DataType, UserDefinedType}
 import org.geotools.coverage.grid.GridCoverage2D
+import org.json4s.JsonDSL._
+import org.json4s.JsonAST.JValue
 
 class RasterUDT extends UserDefinedType[GridCoverage2D] {
   override def sqlType: DataType = BinaryType
@@ -41,6 +43,13 @@ class RasterUDT extends UserDefinedType[GridCoverage2D] {
 
   override def userClass: Class[GridCoverage2D] = classOf[GridCoverage2D]
 
+  override private[sql] def jsonValue: JValue = {
+    super.jsonValue mapField {
+      case ("class", _) => "class" -> this.getClass.getName.stripSuffix("$")
+      case other: Any => other
+    }
+  }
+
   override def equals(other: Any): Boolean = other match {
     case _: UserDefinedType[_] => other.isInstanceOf[RasterUDT]
     case _ => false

Reply via email to