diff --git a/velox/functions/sparksql/DateTimeFunctions.h b/velox/functions/sparksql/DateTimeFunctions.h index 603b2b2293f0..7d797138dc3d 100644 --- a/velox/functions/sparksql/DateTimeFunctions.h +++ b/velox/functions/sparksql/DateTimeFunctions.h @@ -181,8 +181,16 @@ struct FromUnixtimeFunction { mysqlDateTime_ = buildJodaDateTimeFormatter( std::string_view(timeFormat.data(), timeFormat.size())); } - Timestamp timestamp = Timestamp::fromMillis(1000 * second); - auto formattedResult = mysqlDateTime_->format(timestamp, sessionTimeZone_); + Timestamp timestamp = Timestamp::fromSecond(second); + std::string formattedResult; + try { + formattedResult = mysqlDateTime_->format(timestamp, sessionTimeZone_); + } catch (const VeloxUserError& e) { + // Suppress exception caused by integer overflow or + // out of [-32767-01-01, 32767-12-31] date range. + formattedResult = + mysqlDateTime_->format(Timestamp(0, 0), sessionTimeZone_); + } auto resultSize = formattedResult.size(); result.resize(resultSize); if (resultSize != 0) { diff --git a/velox/type/Timestamp.h b/velox/type/Timestamp.h index 0dbf889b6236..f37815fcfb96 100644 --- a/velox/type/Timestamp.h +++ b/velox/type/Timestamp.h @@ -122,6 +122,10 @@ struct Timestamp { std::chrono::time_point toTimePoint() const; + static Timestamp fromSecond(int64_t second) { + return Timestamp(second, 0); + } + static Timestamp fromMillis(int64_t millis) { if (millis >= 0 || millis % 1'000 == 0) { return Timestamp(millis / 1'000, (millis % 1'000) * 1'000'000);