From 96e26232dd34b6c944fd86d528be7f37197c69e0 Mon Sep 17 00:00:00 2001 From: PHILO-HE Date: Wed, 8 Jan 2025 17:56:56 +0800 Subject: [PATCH] Fix casting varchar to timestamp --- .../sparksql/specialforms/SparkCastHooks.cpp | 14 +++++++++++++- .../functions/sparksql/tests/SparkCastExprTest.cpp | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/velox/functions/sparksql/specialforms/SparkCastHooks.cpp b/velox/functions/sparksql/specialforms/SparkCastHooks.cpp index 37649fbf6747..6db8d1a96b77 100644 --- a/velox/functions/sparksql/specialforms/SparkCastHooks.cpp +++ b/velox/functions/sparksql/specialforms/SparkCastHooks.cpp @@ -31,8 +31,20 @@ SparkCastHooks::SparkCastHooks(const velox::core::QueryConfig& config) Expected SparkCastHooks::castStringToTimestamp( const StringView& view) const { - return util::fromTimestampString( + auto conversionResult = util::fromTimestampString( view.data(), view.size(), util::TimestampParseMode::kSparkCast); + if (conversionResult.hasError()) { + return folly::makeUnexpected(conversionResult.error()); + } + auto result = conversionResult.value(); + // If no timezone information is available in the input string, check if we + // should understand it as being at the session timezone, and if so, convert + // to GMT. + const auto sessionTzName = config_.sessionTimezone(); + if (!sessionTzName.empty()) { + result.toGMT(*tz::locateZone(sessionTzName)); + } + return result; } Expected SparkCastHooks::castIntToTimestamp(int64_t seconds) const { diff --git a/velox/functions/sparksql/tests/SparkCastExprTest.cpp b/velox/functions/sparksql/tests/SparkCastExprTest.cpp index ec7fb3034574..fcec9961658f 100644 --- a/velox/functions/sparksql/tests/SparkCastExprTest.cpp +++ b/velox/functions/sparksql/tests/SparkCastExprTest.cpp @@ -261,6 +261,20 @@ TEST_F(SparkCastExprTest, stringToTimestamp) { Timestamp(1426680197, 456000000), }; testCast("timestamp", input, expected); + + setTimezone("Asia/Shanghai"); + testCast( + "timestamp", + { + "1970-01-01 00:00:00", + "1970-01-01 08:00:00", + "1970-01-01 08:00:59", + }, + { + Timestamp(-8 * 3600, 0), + Timestamp(0, 0), + Timestamp(59, 0), + }); } TEST_F(SparkCastExprTest, intToTimestamp) {