diff --git a/velox/expression/PrestoCastHooks.cpp b/velox/expression/PrestoCastHooks.cpp index 29c4d9252265..3c7985774c22 100644 --- a/velox/expression/PrestoCastHooks.cpp +++ b/velox/expression/PrestoCastHooks.cpp @@ -35,7 +35,10 @@ PrestoCastHooks::PrestoCastHooks(const core::QueryConfig& config) Expected PrestoCastHooks::castStringToTimestamp( const StringView& view) const { const auto conversionResult = util::fromTimestampWithTimezoneString( - view.data(), view.size(), util::TimestampParseMode::kPrestoCast); + view.data(), + view.size(), + legacyCast_ ? util::TimestampParseMode::kLegacyCast + : util::TimestampParseMode::kPrestoCast); if (conversionResult.hasError()) { return folly::makeUnexpected(conversionResult.error()); } diff --git a/velox/expression/tests/CastExprTest.cpp b/velox/expression/tests/CastExprTest.cpp index 33d37505f917..5da288190501 100644 --- a/velox/expression/tests/CastExprTest.cpp +++ b/velox/expression/tests/CastExprTest.cpp @@ -614,6 +614,27 @@ TEST_F(CastExprTest, stringToTimestamp) { (evaluateOnce( "cast(c0 as timestamp)", "1970-01-01T00:00")), "Cannot cast VARCHAR '1970-01-01T00:00' to TIMESTAMP. Unable to parse timestamp value"); + + setLegacyCast(true); + input = { + "1970-01-01", + "1970-01-01T00:00 America/Sao_Paulo", + "2000-01-01", + "1970-01-01T00:00:00", + "2000-01-01 12:21:56", + "1970-01-01T00:00:00-02:00", + std::nullopt, + }; + expected = { + Timestamp(0, 0), + Timestamp(10800, 0), + Timestamp(946684800, 0), + Timestamp(0, 0), + Timestamp(946729316, 0), + Timestamp(7200, 0), + std::nullopt, + }; + testCast("timestamp", input, expected); } TEST_F(CastExprTest, timestampToString) { diff --git a/velox/type/TimestampConversion.cpp b/velox/type/TimestampConversion.cpp index 46b2a6960979..0e3a49e8354f 100644 --- a/velox/type/TimestampConversion.cpp +++ b/velox/type/TimestampConversion.cpp @@ -351,6 +351,7 @@ void parseTimeSeparator( pos++; } break; + case TimestampParseMode::kLegacyCast: case TimestampParseMode::kSparkCast: if (buf[pos] == ' ' || buf[pos] == 'T') { pos++; diff --git a/velox/type/TimestampConversion.h b/velox/type/TimestampConversion.h index e5f6b5c4f715..cdc9eb57bf96 100644 --- a/velox/type/TimestampConversion.h +++ b/velox/type/TimestampConversion.h @@ -162,6 +162,9 @@ enum class TimestampParseMode { // Allows leading and trailing spaces. kPrestoCast, + // Same as kPrestoCast, but allows 'T' separator between date and time. + kLegacyCast, + /// A Spark-compatible timestamp string. A mix of the above. Accepts T and /// space as separator between date and time. Allows leading and trailing /// spaces.