From ac0a3a38c7e4a84c86238df8f5898bc4e787bcb2 Mon Sep 17 00:00:00 2001 From: "TONG,Zhigao" Date: Thu, 25 Jul 2024 21:31:47 +0800 Subject: [PATCH 1/2] fix issue 8754 --- dbms/src/Common/MyTime.cpp | 28 ++++++++++++++++++-------- dbms/src/Common/tests/gtest_mytime.cpp | 4 ++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/dbms/src/Common/MyTime.cpp b/dbms/src/Common/MyTime.cpp index ac0249831d0..52485e9d954 100644 --- a/dbms/src/Common/MyTime.cpp +++ b/dbms/src/Common/MyTime.cpp @@ -262,7 +262,7 @@ int getFracIndex(const String & format) int idx = -1; for (int i = end; i >= 0; i--) { - if (isPunctuation(format[i])) + if (format[i] != '+' && format[i] != '-' && isPunctuation(format[i])) { if (format[i] == '.') { @@ -745,7 +745,7 @@ inline bool numberToDateTime(Int64 number, MyDateTime & result, bool allowZeroDa } // returns frac, overflow, matched. eg., "999" fsp=2 will overflow. -std::tuple parseFrac(const String & str, int8_t fsp) +std::tuple parseFrac(const std::string_view str, int8_t fsp) { if (str.empty()) { @@ -761,15 +761,27 @@ std::tuple parseFrac(const String & str, int8_t fsp) } try { - int len = str.length(); - if (fsp >= len) + int end_pos = static_cast(fsp) >= str.size() ? str.size() : (fsp + 1); + UInt32 tmp = 0; + int size = 0; + for (int i = 0; i < end_pos; ++i) { - UInt32 tmp = std::stoul(str); - return {tmp * std::pow(10, 6 - len), false, true}; + if (auto c = str[i]; c >= '0' && c <= '9') + { + tmp = tmp * 10 + c - '0'; + size++; + } + else + { + break; + } + } + + if (fsp >= size) + { + return {tmp * std::pow(10, 6 - size), false, true}; } - // Round when fsp < string length. - UInt32 tmp = std::stoul(str.substr(0, fsp + 1)); tmp = (tmp + 5) / 10; if (tmp >= std::pow(10, fsp)) { diff --git a/dbms/src/Common/tests/gtest_mytime.cpp b/dbms/src/Common/tests/gtest_mytime.cpp index c65a7dc05a0..ccf5badbac9 100644 --- a/dbms/src/Common/tests/gtest_mytime.cpp +++ b/dbms/src/Common/tests/gtest_mytime.cpp @@ -125,6 +125,7 @@ try {"2020-10-10 10.10", "2020-10-10 10:10:00.000000"}, {"2018.01.01", "2018-01-01 00:00:00.000000"}, {"2020--12-10 11:11:11..123456", "2020-12-10 11:11:11.123456"}, + {"2020-01-01 12:00:00.1234xxxx -0600 PST", "2020-01-01 12:00:00.123400"}, }; DataTypeMyDateTime type_with_fraction(6); for (auto & [str, expected] : cases_with_fsp) @@ -184,6 +185,9 @@ try } DataTypeMyDateTime tp(2); checkParseMyDateTime("2010-12-31 23:59:59.99999", "2011-01-01 00:00:00.00", tp); + checkParseMyDateTime("2010-12-31 23:59:59.99xxxxx -0600 PST", "2010-12-31 23:59:59.99", tp); + checkParseMyDateTime("2020-01-01 12:00:00.123456 +0600 PST", "2020-01-01 12:00:00.12", tp); + checkParseMyDateTime("2020-01-01 12:00:00.123456 -0600 PST", "2020-01-01 12:00:00.12", tp); } catch (Exception & e) { From 96550b475c55a77cbf3e252a2edec694b4ec05d2 Mon Sep 17 00:00:00 2001 From: Zhigao Tong Date: Thu, 8 Aug 2024 15:16:31 +0800 Subject: [PATCH 2/2] more tests Signed-off-by: Zhigao Tong --- dbms/src/Common/tests/gtest_mytime.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dbms/src/Common/tests/gtest_mytime.cpp b/dbms/src/Common/tests/gtest_mytime.cpp index ccf5badbac9..5c076739128 100644 --- a/dbms/src/Common/tests/gtest_mytime.cpp +++ b/dbms/src/Common/tests/gtest_mytime.cpp @@ -126,6 +126,7 @@ try {"2018.01.01", "2018-01-01 00:00:00.000000"}, {"2020--12-10 11:11:11..123456", "2020-12-10 11:11:11.123456"}, {"2020-01-01 12:00:00.1234xxxx -0600 PST", "2020-01-01 12:00:00.123400"}, + {"2020-01-01 12:00:00.123456-05:00", "2020-01-01 17:00:00.123456"}, // tidb/issues/49555 }; DataTypeMyDateTime type_with_fraction(6); for (auto & [str, expected] : cases_with_fsp)