From c51c2c5c18860aaef3b5853f24f8e9cefea167eb Mon Sep 17 00:00:00 2001 From: pingcap-github-bot Date: Tue, 26 May 2020 20:24:16 +0800 Subject: [PATCH] Throw exception if timestamp value is not supported by TiFlash (#725) (#730) * throw error for invalid timestamp value * fix * fmt code Co-authored-by: xufei --- dbms/src/Common/MyTime.cpp | 4 ++++ dbms/src/Functions/FunctionsConversion.h | 9 +++++++++ libs/libcommon/include/common/DateLUTImpl.h | 3 +++ 3 files changed, 16 insertions(+) diff --git a/dbms/src/Common/MyTime.cpp b/dbms/src/Common/MyTime.cpp index a339a646fb0..84362a2b7d0 100644 --- a/dbms/src/Common/MyTime.cpp +++ b/dbms/src/Common/MyTime.cpp @@ -696,6 +696,8 @@ void convertTimeZone(UInt64 from_time, UInt64 & to_time, const DateLUTImpl & tim MyDateTime from_my_time(from_time); time_t epoch = time_zone_from.makeDateTime( from_my_time.year, from_my_time.month, from_my_time.day, from_my_time.hour, from_my_time.minute, from_my_time.second); + if (unlikely(epoch + time_zone_to.getOffsetAtStartEpoch() < 0)) + throw Exception("Unsupported timestamp value , TiFlash only support timestamp after 1970-01-01 00:00:00)"); MyDateTime to_my_time(time_zone_to.toYear(epoch), time_zone_to.toMonth(epoch), time_zone_to.toDayOfMonth(epoch), time_zone_to.toHour(epoch), time_zone_to.toMinute(epoch), time_zone_to.toSecond(epoch), from_my_time.micro_second); to_time = to_my_time.toPackedUInt(); @@ -712,6 +714,8 @@ void convertTimeZoneByOffset(UInt64 from_time, UInt64 & to_time, Int64 offset, c time_t epoch = time_zone.makeDateTime( from_my_time.year, from_my_time.month, from_my_time.day, from_my_time.hour, from_my_time.minute, from_my_time.second); epoch += offset; + if (unlikely(epoch < 0)) + throw Exception("Unsupported timestamp value , TiFlash only support timestamp after 1970-01-01 00:00:00)"); MyDateTime to_my_time(time_zone.toYear(epoch), time_zone.toMonth(epoch), time_zone.toDayOfMonth(epoch), time_zone.toHour(epoch), time_zone.toMinute(epoch), time_zone.toSecond(epoch), from_my_time.micro_second); to_time = to_my_time.toPackedUInt(); diff --git a/dbms/src/Functions/FunctionsConversion.h b/dbms/src/Functions/FunctionsConversion.h index 09bf58bb338..c9346cf8475 100644 --- a/dbms/src/Functions/FunctionsConversion.h +++ b/dbms/src/Functions/FunctionsConversion.h @@ -1387,7 +1387,16 @@ class FunctionFromUnixTime : public IFunction } if (timezone_info.timezone_offset != 0) + { integer_part += timezone_info.timezone_offset; + if (unlikely(integer_part < 0)) + throw Exception("Unsupported timestamp value , TiFlash only support timestamp after 1970-01-01 00:00:00)"); + } + else + { + if (unlikely(integer_part + datelut->getOffsetAtStartEpoch() < 0)) + throw Exception("Unsupported timestamp value , TiFlash only support timestamp after 1970-01-01 00:00:00)"); + } MyDateTime result(datelut->toYear(integer_part), datelut->toMonth(integer_part), datelut->toDayOfMonth(integer_part), datelut->toHour(integer_part), datelut->toMinute(integer_part), datelut->toSecond(integer_part), fsp_part); null_res[i] = 0; diff --git a/libs/libcommon/include/common/DateLUTImpl.h b/libs/libcommon/include/common/DateLUTImpl.h index 456d3ae80f7..c9cc636ae81 100644 --- a/libs/libcommon/include/common/DateLUTImpl.h +++ b/libs/libcommon/include/common/DateLUTImpl.h @@ -111,6 +111,9 @@ class DateLUTImpl public: const std::string & getTimeZone() const { return time_zone; } + time_t getOffsetAtStartEpoch() const { + return offset_at_start_of_epoch; + } /// All functions below are thread-safe; arguments are not checked.