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 98a8b4a4b4..9eaea0c498 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 @@ -615,6 +615,14 @@ class DateFunctionsValidateSuite extends FunctionsValidateSuite { runQueryAndCompare("select timestampadd(hour, 1, ts) from view") { checkGlutenPlan[ProjectExecTransformer] } + // convert_timezone(timestamp_ntz) runs natively; output stays timestamp_ntz. + runQueryAndCompare("select convert_timezone('America/Los_Angeles', ts) from view") { + checkGlutenPlan[ProjectExecTransformer] + } + runQueryAndCompare( + "select convert_timezone('America/Los_Angeles', 'Asia/Shanghai', ts) from view") { + checkGlutenPlan[ProjectExecTransformer] + } // cast(timestamp_ntz as timestamp) runQueryAndCompare("select cast(ts as timestamp) from view") { diff --git a/ep/build-velox/src/get-velox.sh b/ep/build-velox/src/get-velox.sh index eaace0096f..03dfdb2a86 100755 --- a/ep/build-velox/src/get-velox.sh +++ b/ep/build-velox/src/get-velox.sh @@ -18,8 +18,8 @@ set -exu CURRENT_DIR=$(cd "$(dirname "$BASH_SOURCE")"; pwd) VELOX_REPO=https://github.com/IBM/velox.git -VELOX_BRANCH=dft-2026_09_08 -VELOX_ENHANCED_BRANCH=ibm-2026_09_08 +VELOX_BRANCH=dft-2026_09_10 +VELOX_ENHANCED_BRANCH=ibm-2026_09_10 VELOX_HOME="" RUN_SETUP_SCRIPT=ON ENABLE_ENHANCED_FEATURES=OFF diff --git a/gluten-substrait/src/main/scala/org/apache/gluten/expression/ExpressionMappings.scala b/gluten-substrait/src/main/scala/org/apache/gluten/expression/ExpressionMappings.scala index d58f1b5650..0377bbda50 100644 --- a/gluten-substrait/src/main/scala/org/apache/gluten/expression/ExpressionMappings.scala +++ b/gluten-substrait/src/main/scala/org/apache/gluten/expression/ExpressionMappings.scala @@ -308,6 +308,7 @@ object ExpressionMappings { Sig[KnownNullable](KNOWN_NULLABLE), Sig[TimestampAdd](TIMESTAMP_ADD), Sig[TimestampDiff](TIMESTAMP_DIFF), + Sig[ConvertTimezone](CONVERT_TIMEZONE), Sig[RoundFloor](FLOOR), Sig[RoundCeil](CEIL) ) ++ SparkShimLoader.getSparkShims.scalarExpressionMappings 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 b8e894a415..6c648efaba 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 @@ -25,7 +25,7 @@ import org.apache.gluten.extension.columnar.offload.OffloadSingleNode import org.apache.gluten.sql.shims.SparkShimLoader import org.apache.spark.internal.Logging -import org.apache.spark.sql.catalyst.expressions.{Cast, Hour, Minute, Second, TimestampAdd} +import org.apache.spark.sql.catalyst.expressions.{Cast, ConvertTimezone, Hour, Minute, Second, TimestampAdd} import org.apache.spark.sql.execution._ import org.apache.spark.sql.execution.aggregate.{HashAggregateExec, ObjectHashAggregateExec, SortAggregateExec} import org.apache.spark.sql.execution.datasources.WriteFilesExec @@ -283,6 +283,7 @@ object Validators { case Minute(child, _) => containsNTZ(child.dataType) case Second(child, _) => containsNTZ(child.dataType) case TimestampAdd(_, _, child, _) => containsNTZ(child.dataType) + case ConvertTimezone(_, _, child) => containsNTZ(child.dataType) case c: Cast if isNTZ(c.dataType) || isNTZ(c.child.dataType) => true case _ => false } diff --git a/shims/common/src/main/scala/org/apache/gluten/expression/ExpressionNames.scala b/shims/common/src/main/scala/org/apache/gluten/expression/ExpressionNames.scala index 733adff050..af7a29eb7f 100644 --- a/shims/common/src/main/scala/org/apache/gluten/expression/ExpressionNames.scala +++ b/shims/common/src/main/scala/org/apache/gluten/expression/ExpressionNames.scala @@ -240,6 +240,7 @@ object ExpressionNames { final val MAKE_YM_INTERVAL = "make_ym_interval" final val TO_UTC_TIMESTAMP = "to_utc_timestamp" final val FROM_UTC_TIMESTAMP = "from_utc_timestamp" + final val CONVERT_TIMEZONE = "convert_timezone" final val UNIX_SECONDS = "unix_seconds" final val UNIX_MILLIS = "unix_millis" final val UNIX_MICROS = "unix_micros"