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

rui-mo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gluten.git


The following commit(s) were added to refs/heads/main by this push:
     new e9cc742509 [VL] Support Cast from VARCHAR to TIMESTAMP_NTZ (#12656)
e9cc742509 is described below

commit e9cc7425092dfed781ecd0ee3bfdbbfa13d4e412
Author: Mariam AlMesfer <[email protected]>
AuthorDate: Wed Aug 26 19:42:02 2026 +0300

    [VL] Support Cast from VARCHAR to TIMESTAMP_NTZ (#12656)
    
    Co-authored-by: Mariam-Almesfer <[email protected]>
---
 .../functions/DateFunctionsValidateSuite.scala       | 20 ++++++++++++++++++++
 cpp/velox/substrait/SubstraitToVeloxPlanValidator.cc |  4 +++-
 .../extension/columnar/validator/Validators.scala    |  5 ++---
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git 
a/backends-velox/src/test/scala/org/apache/gluten/functions/DateFunctionsValidateSuite.scala
 
b/backends-velox/src/test/scala/org/apache/gluten/functions/DateFunctionsValidateSuite.scala
index 95619f0e0b..b51b3563d2 100644
--- 
a/backends-velox/src/test/scala/org/apache/gluten/functions/DateFunctionsValidateSuite.scala
+++ 
b/backends-velox/src/test/scala/org/apache/gluten/functions/DateFunctionsValidateSuite.scala
@@ -621,6 +621,11 @@ class DateFunctionsValidateSuite extends 
FunctionsValidateSuite {
           checkGlutenPlan[ProjectExecTransformer]
         }
 
+        // cast(timestamp_ntz as string)
+        runQueryAndCompare("select cast(ts as string) from view") {
+          checkGlutenPlan[ProjectExecTransformer]
+        }
+
         withSQLConf("spark.sql.session.timeZone" -> "Asia/Hong_Kong") {
           val dstPath = dir.getAbsolutePath + "/dst_gap"
           spark
@@ -661,6 +666,21 @@ class DateFunctionsValidateSuite extends 
FunctionsValidateSuite {
             checkGlutenPlan[ProjectExecTransformer]
           }
         }
+
+        val strPath = dir.getAbsolutePath + "/str_view"
+        spark
+          .createDataset(inputs)
+          .toDF("str")
+          .coalesce(1)
+          .write
+          .mode("overwrite")
+          .parquet(strPath)
+        spark.read.parquet(strPath).createOrReplaceTempView("str_view")
+
+        // cast(varchar as timestamp_ntz)
+        runQueryAndCompare("select cast(str as timestamp_ntz) from str_view") {
+          checkGlutenPlan[ProjectExecTransformer]
+        }
     }
   }
 }
diff --git a/cpp/velox/substrait/SubstraitToVeloxPlanValidator.cc 
b/cpp/velox/substrait/SubstraitToVeloxPlanValidator.cc
index 6dcce60359..9896b43e54 100644
--- a/cpp/velox/substrait/SubstraitToVeloxPlanValidator.cc
+++ b/cpp/velox/substrait/SubstraitToVeloxPlanValidator.cc
@@ -303,7 +303,9 @@ bool SubstraitToVeloxPlanValidator::isAllowedCast(const 
TypePtr& fromType, const
     return false;
   }
   if (toType->equivalent(*TIMESTAMP_UTC())) {
-    // Only supports from Timestamp to TimestampNTZ.
+    if (fromType->isVarchar()) {
+      return true;
+    }
     return false;
   }
 
diff --git 
a/gluten-substrait/src/main/scala/org/apache/gluten/extension/columnar/validator/Validators.scala
 
b/gluten-substrait/src/main/scala/org/apache/gluten/extension/columnar/validator/Validators.scala
index b7be523c6d..b8e894a415 100644
--- 
a/gluten-substrait/src/main/scala/org/apache/gluten/extension/columnar/validator/Validators.scala
+++ 
b/gluten-substrait/src/main/scala/org/apache/gluten/extension/columnar/validator/Validators.scala
@@ -34,7 +34,7 @@ import 
org.apache.spark.sql.execution.exchange.{BroadcastExchangeExec, ShuffleEx
 import org.apache.spark.sql.execution.joins._
 import org.apache.spark.sql.execution.window.WindowExec
 import org.apache.spark.sql.hive.HiveTableScanExecTransformer
-import org.apache.spark.sql.types.{ArrayType, DataType, MapType, StructType, 
TimestampType}
+import org.apache.spark.sql.types.{ArrayType, DataType, MapType, StructType}
 
 object Validators {
   implicit class ValidatorBuilderImplicits(builder: Validator.Builder) {
@@ -283,8 +283,7 @@ object Validators {
                   case Minute(child, _) => containsNTZ(child.dataType)
                   case Second(child, _) => containsNTZ(child.dataType)
                   case TimestampAdd(_, _, child, _) => 
containsNTZ(child.dataType)
-                  case c: Cast if c.dataType == TimestampType => 
isNTZ(c.child.dataType)
-                  case c: Cast if isNTZ(c.dataType) => c.child.dataType == 
TimestampType
+                  case c: Cast if isNTZ(c.dataType) || isNTZ(c.child.dataType) 
=> true
                   case _ => false
                 }
             }


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

Reply via email to