diff --git a/programs/client/Client.cpp b/programs/client/Client.cpp index 05fc1ba9141..be148ddb3e3 100644 --- a/programs/client/Client.cpp +++ b/programs/client/Client.cpp @@ -1477,7 +1477,8 @@ private: } else { - out_logs_buf = std::make_unique(server_logs_file, DBMS_DEFAULT_BUFFER_SIZE, O_WRONLY | O_APPEND | O_CREAT); + out_logs_buf = std::make_unique( + server_logs_file, DBMS_DEFAULT_BUFFER_SIZE, O_WRONLY | O_APPEND | O_CREAT); wb = out_logs_buf.get(); } } diff --git a/src/Common/intExp.h b/src/Common/intExp.h index a021d9660ff..b38a8afd83b 100644 --- a/src/Common/intExp.h +++ b/src/Common/intExp.h @@ -20,14 +20,14 @@ inline NO_SANITIZE_UNDEFINED uint64_t intExp2(int x) return 1ULL << x; } -inline uint64_t intExp10(int x) +constexpr inline uint64_t intExp10(int x) { if (x < 0) return 0; if (x > 19) return std::numeric_limits::max(); - static const uint64_t table[20] = + constexpr uint64_t table[20] = { 1ULL, 10ULL, 100ULL, 1000ULL, 10000ULL, 100000ULL, @@ -44,9 +44,10 @@ inline uint64_t intExp10(int x) namespace common { -inline int exp10_i32(int x) +constexpr inline int exp10_i32(int x) { - static const int values[] = { + constexpr int values[] = + { 1, 10, 100, @@ -61,74 +62,76 @@ inline int exp10_i32(int x) return values[x]; } -inline int64_t exp10_i64(int x) +constexpr inline int64_t exp10_i64(int x) { - static const int64_t values[] = { - 1ll, - 10ll, - 100ll, - 1000ll, - 10000ll, - 100000ll, - 1000000ll, - 10000000ll, - 100000000ll, - 1000000000ll, - 10000000000ll, - 100000000000ll, - 1000000000000ll, - 10000000000000ll, - 100000000000000ll, - 1000000000000000ll, - 10000000000000000ll, - 100000000000000000ll, - 1000000000000000000ll + constexpr int64_t values[] = + { + 1LL, + 10LL, + 100LL, + 1000LL, + 10000LL, + 100000LL, + 1000000LL, + 10000000LL, + 100000000LL, + 1000000000LL, + 10000000000LL, + 100000000000LL, + 1000000000000LL, + 10000000000000LL, + 100000000000000LL, + 1000000000000000LL, + 10000000000000000LL, + 100000000000000000LL, + 1000000000000000000LL }; return values[x]; } -inline __int128 exp10_i128(int x) +constexpr inline __int128 exp10_i128(int x) { - static const __int128 values[] = { - static_cast<__int128>(1ll), - static_cast<__int128>(10ll), - static_cast<__int128>(100ll), - static_cast<__int128>(1000ll), - static_cast<__int128>(10000ll), - static_cast<__int128>(100000ll), - static_cast<__int128>(1000000ll), - static_cast<__int128>(10000000ll), - static_cast<__int128>(100000000ll), - static_cast<__int128>(1000000000ll), - static_cast<__int128>(10000000000ll), - static_cast<__int128>(100000000000ll), - static_cast<__int128>(1000000000000ll), - static_cast<__int128>(10000000000000ll), - static_cast<__int128>(100000000000000ll), - static_cast<__int128>(1000000000000000ll), - static_cast<__int128>(10000000000000000ll), - static_cast<__int128>(100000000000000000ll), - static_cast<__int128>(1000000000000000000ll), - static_cast<__int128>(1000000000000000000ll) * 10ll, - static_cast<__int128>(1000000000000000000ll) * 100ll, - static_cast<__int128>(1000000000000000000ll) * 1000ll, - static_cast<__int128>(1000000000000000000ll) * 10000ll, - static_cast<__int128>(1000000000000000000ll) * 100000ll, - static_cast<__int128>(1000000000000000000ll) * 1000000ll, - static_cast<__int128>(1000000000000000000ll) * 10000000ll, - static_cast<__int128>(1000000000000000000ll) * 100000000ll, - static_cast<__int128>(1000000000000000000ll) * 1000000000ll, - static_cast<__int128>(1000000000000000000ll) * 10000000000ll, - static_cast<__int128>(1000000000000000000ll) * 100000000000ll, - static_cast<__int128>(1000000000000000000ll) * 1000000000000ll, - static_cast<__int128>(1000000000000000000ll) * 10000000000000ll, - static_cast<__int128>(1000000000000000000ll) * 100000000000000ll, - static_cast<__int128>(1000000000000000000ll) * 1000000000000000ll, - static_cast<__int128>(1000000000000000000ll) * 10000000000000000ll, - static_cast<__int128>(1000000000000000000ll) * 100000000000000000ll, - static_cast<__int128>(1000000000000000000ll) * 100000000000000000ll * 10ll, - static_cast<__int128>(1000000000000000000ll) * 100000000000000000ll * 100ll, - static_cast<__int128>(1000000000000000000ll) * 100000000000000000ll * 1000ll + constexpr __int128 values[] = + { + static_cast<__int128>(1LL), + static_cast<__int128>(10LL), + static_cast<__int128>(100LL), + static_cast<__int128>(1000LL), + static_cast<__int128>(10000LL), + static_cast<__int128>(100000LL), + static_cast<__int128>(1000000LL), + static_cast<__int128>(10000000LL), + static_cast<__int128>(100000000LL), + static_cast<__int128>(1000000000LL), + static_cast<__int128>(10000000000LL), + static_cast<__int128>(100000000000LL), + static_cast<__int128>(1000000000000LL), + static_cast<__int128>(10000000000000LL), + static_cast<__int128>(100000000000000LL), + static_cast<__int128>(1000000000000000LL), + static_cast<__int128>(10000000000000000LL), + static_cast<__int128>(100000000000000000LL), + static_cast<__int128>(1000000000000000000LL), + static_cast<__int128>(1000000000000000000LL) * 10LL, + static_cast<__int128>(1000000000000000000LL) * 100LL, + static_cast<__int128>(1000000000000000000LL) * 1000LL, + static_cast<__int128>(1000000000000000000LL) * 10000LL, + static_cast<__int128>(1000000000000000000LL) * 100000LL, + static_cast<__int128>(1000000000000000000LL) * 1000000LL, + static_cast<__int128>(1000000000000000000LL) * 10000000LL, + static_cast<__int128>(1000000000000000000LL) * 100000000LL, + static_cast<__int128>(1000000000000000000LL) * 1000000000LL, + static_cast<__int128>(1000000000000000000LL) * 10000000000LL, + static_cast<__int128>(1000000000000000000LL) * 100000000000LL, + static_cast<__int128>(1000000000000000000LL) * 1000000000000LL, + static_cast<__int128>(1000000000000000000LL) * 10000000000000LL, + static_cast<__int128>(1000000000000000000LL) * 100000000000000LL, + static_cast<__int128>(1000000000000000000LL) * 1000000000000000LL, + static_cast<__int128>(1000000000000000000LL) * 10000000000000000LL, + static_cast<__int128>(1000000000000000000LL) * 100000000000000000LL, + static_cast<__int128>(1000000000000000000LL) * 100000000000000000LL * 10LL, + static_cast<__int128>(1000000000000000000LL) * 100000000000000000LL * 100LL, + static_cast<__int128>(1000000000000000000LL) * 100000000000000000LL * 1000LL }; return values[x]; } @@ -138,7 +141,7 @@ inline __int128 exp10_i128(int x) /// intExp10 returning the type T. template -inline T intExp10OfSize(int x) +constexpr inline T intExp10OfSize(int x) { if constexpr (sizeof(T) <= 8) return intExp10(x); diff --git a/src/DataTypes/DataTypeDateTime64.cpp b/src/DataTypes/DataTypeDateTime64.cpp index 9b4f16ab408..87da173766d 100644 --- a/src/DataTypes/DataTypeDateTime64.cpp +++ b/src/DataTypes/DataTypeDateTime64.cpp @@ -20,19 +20,34 @@ #include #include + namespace DB { +namespace ErrorCodes +{ + extern const int ARGUMENT_OUT_OF_BOUND; +} + +static constexpr UInt32 max_scale = 9; + DataTypeDateTime64::DataTypeDateTime64(UInt32 scale_, const std::string & time_zone_name) : DataTypeDecimalBase(DecimalUtils::maxPrecision(), scale_), TimezoneMixin(time_zone_name) { + if (scale > max_scale) + throw Exception("Scale " + std::to_string(scale) + " is too large for DateTime64. Maximum is up to nanoseconds (9).", + ErrorCodes::ARGUMENT_OUT_OF_BOUND); } DataTypeDateTime64::DataTypeDateTime64(UInt32 scale_, const TimezoneMixin & time_zone_info) - : DataTypeDecimalBase(DecimalUtils::maxPrecision() - scale_, scale_), + : DataTypeDecimalBase(DecimalUtils::maxPrecision(), scale_), TimezoneMixin(time_zone_info) -{} +{ + if (scale > max_scale) + throw Exception("Scale " + std::to_string(scale) + " is too large for DateTime64. Maximum is up to nanoseconds (9).", + ErrorCodes::ARGUMENT_OUT_OF_BOUND); +} std::string DataTypeDateTime64::doGetName() const { diff --git a/src/DataTypes/DataTypeDecimalBase.h b/src/DataTypes/DataTypeDecimalBase.h index 2cf73467644..edfba272110 100644 --- a/src/DataTypes/DataTypeDecimalBase.h +++ b/src/DataTypes/DataTypeDecimalBase.h @@ -72,7 +72,7 @@ public: { if (unlikely(precision < 1 || precision > maxPrecision())) throw Exception("Precision " + std::to_string(precision) + " is out of bounds", ErrorCodes::ARGUMENT_OUT_OF_BOUND); - if (unlikely(scale < 0 || static_cast(scale) > maxPrecision())) + if (unlikely(scale > maxPrecision())) throw Exception("Scale " + std::to_string(scale) + " is out of bounds", ErrorCodes::ARGUMENT_OUT_OF_BOUND); } diff --git a/src/DataTypes/getLeastSupertype.cpp b/src/DataTypes/getLeastSupertype.cpp index b11f1aa7454..9c3ca679467 100644 --- a/src/DataTypes/getLeastSupertype.cpp +++ b/src/DataTypes/getLeastSupertype.cpp @@ -208,7 +208,7 @@ DataTypePtr getLeastSupertype(const DataTypes & types) } } - /// For Date and DateTime, the common type is DateTime. No other types are compatible. + /// For Date and DateTime/DateTime64, the common type is DateTime/DateTime64. No other types are compatible. { UInt32 have_date = type_ids.count(TypeIndex::Date); UInt32 have_datetime = type_ids.count(TypeIndex::DateTime); @@ -218,40 +218,25 @@ DataTypePtr getLeastSupertype(const DataTypes & types) { bool all_date_or_datetime = type_ids.size() == (have_date + have_datetime + have_datetime64); if (!all_date_or_datetime) - throw Exception(getExceptionMessagePrefix(types) + " because some of them are Date/DateTime and some of them are not", ErrorCodes::NO_COMMON_TYPE); + throw Exception(getExceptionMessagePrefix(types) + " because some of them are Date/DateTime/DateTime64 and some of them are not", + ErrorCodes::NO_COMMON_TYPE); if (have_datetime64 == 0) - { return std::make_shared(); - } - // When DateTime64 involved, make sure that supertype has whole-part precision - // big enough to hold max whole-value of any type from `types`. - // That would sacrifice scale when comparing DateTime64 of different scales. + UInt8 max_scale = 0; - UInt32 max_datetime64_whole_precision = 0; for (const auto & t : types) { if (const auto * dt64 = typeid_cast(t.get())) { - const auto whole_precision = dt64->getPrecision() - dt64->getScale(); - max_datetime64_whole_precision = std::max(whole_precision, max_datetime64_whole_precision); + const auto scale = dt64->getScale(); + if (scale > max_scale) + max_scale = scale; } } - UInt32 least_decimal_precision = 0; - if (have_datetime) - { - least_decimal_precision = leastDecimalPrecisionFor(TypeIndex::UInt32); - } - else if (have_date) - { - least_decimal_precision = leastDecimalPrecisionFor(TypeIndex::UInt16); - } - max_datetime64_whole_precision = std::max(least_decimal_precision, max_datetime64_whole_precision); - - const UInt32 scale = DataTypeDateTime64::maxPrecision() - max_datetime64_whole_precision; - return std::make_shared(scale); + return std::make_shared(max_scale); } } diff --git a/src/DataTypes/tests/gtest_data_type_get_common_type.cpp b/src/DataTypes/tests/gtest_data_type_get_common_type.cpp index bd13de79ef6..8212555e8bc 100644 --- a/src/DataTypes/tests/gtest_data_type_get_common_type.cpp +++ b/src/DataTypes/tests/gtest_data_type_get_common_type.cpp @@ -86,7 +86,7 @@ TEST_P(LeastSuperTypeTest, getLeastSupertype) class MostSubtypeTest : public TypeTest {}; -TEST_P(MostSubtypeTest, getLeastSupertype) +TEST_P(MostSubtypeTest, getMostSubtype) { if (this->expected_type) { @@ -124,9 +124,7 @@ INSTANTIATE_TEST_SUITE_P(data_type, {"Date DateTime64(3)", "DateTime64(3)"}, {"DateTime DateTime64(3)", "DateTime64(3)"}, {"DateTime DateTime64(0)", "DateTime64(0)"}, - {"DateTime64(9) DateTime64(3)", "DateTime64(3)"}, - {"DateTime DateTime64(12)", "DateTime64(8)"}, - {"Date DateTime64(15)", "DateTime64(13)"}, + {"DateTime64(9) DateTime64(3)", "DateTime64(9)"}, {"String FixedString(32) FixedString(8)", "String"}, diff --git a/src/IO/ReadHelpers.h b/src/IO/ReadHelpers.h index 266b5ae1917..00bc6113186 100644 --- a/src/IO/ReadHelpers.h +++ b/src/IO/ReadHelpers.h @@ -275,8 +275,11 @@ ReturnType readIntTextImpl(T & x, ReadBuffer & buf) switch (*buf.position()) { case '+': + { break; + } case '-': + { if constexpr (is_signed_v) negative = true; else @@ -287,6 +290,7 @@ ReturnType readIntTextImpl(T & x, ReadBuffer & buf) return ReturnType(false); } break; + } case '0': [[fallthrough]]; case '1': [[fallthrough]]; case '2': [[fallthrough]]; @@ -297,20 +301,27 @@ ReturnType readIntTextImpl(T & x, ReadBuffer & buf) case '7': [[fallthrough]]; case '8': [[fallthrough]]; case '9': + { if constexpr (check_overflow == ReadIntTextCheckOverflow::CHECK_OVERFLOW) { - // perform relativelly slow overflow check only when number of decimal digits so far is close to the max for given type. - if (buf.count() - initial_pos >= std::numeric_limits::max_digits10) + /// Perform relativelly slow overflow check only when + /// number of decimal digits so far is close to the max for given type. + /// Example: 20 * 10 will overflow Int8. + + if (buf.count() - initial_pos + 1 >= std::numeric_limits::max_digits10) { - if (common::mulOverflow(res, static_cast(10), res) - || common::addOverflow(res, static_cast(*buf.position() - '0'), res)) + T signed_res = res; + if (common::mulOverflow(signed_res, 10, signed_res) + || common::addOverflow(signed_res, (*buf.position() - '0'), signed_res)) return ReturnType(false); + res = signed_res; break; } } res *= 10; res += *buf.position() - '0'; break; + } default: goto end; } @@ -318,7 +329,23 @@ ReturnType readIntTextImpl(T & x, ReadBuffer & buf) } end: - x = negative ? -res : res; + if (!negative) + { + x = res; + } + else + { + if constexpr (check_overflow == ReadIntTextCheckOverflow::CHECK_OVERFLOW) + { + x = res; + if (common::mulOverflow(x, -1, x)) + return ReturnType(false); + } + else + { + x = -res; + } + } return ReturnType(true); } @@ -658,35 +685,34 @@ inline ReturnType readDateTimeTextImpl(DateTime64 & datetime64, UInt32 scale, Re return ReturnType(false); } - DB::DecimalUtils::DecimalComponents c{static_cast(whole), 0}; + DB::DecimalUtils::DecimalComponents components{static_cast(whole), 0}; if (!buf.eof() && *buf.position() == '.') { - buf.ignore(1); // skip separator - const auto pos_before_fractional = buf.count(); - if (!tryReadIntText(c.fractional, buf)) + ++buf.position(); + + /// Read digits, up to 'scale' positions. + for (size_t i = 0; i < scale; ++i) { - return ReturnType(false); + if (!buf.eof() && isNumericASCII(*buf.position())) + { + components.fractional *= 10; + components.fractional += *buf.position() - '0'; + ++buf.position(); + } + else + { + /// Adjust to scale. + components.fractional *= 10; + } } - // Adjust fractional part to the scale, since decimalFromComponents knows nothing - // about convention of ommiting trailing zero on fractional part - // and assumes that fractional part value is less than 10^scale. - - // If scale is 3, but we read '12', promote fractional part to '120'. - // And vice versa: if we read '1234', denote it to '123'. - const auto fractional_length = static_cast(buf.count() - pos_before_fractional); - if (const auto adjust_scale = static_cast(scale) - fractional_length; adjust_scale > 0) - { - c.fractional *= common::exp10_i64(adjust_scale); - } - else if (adjust_scale < 0) - { - c.fractional /= common::exp10_i64(-1 * adjust_scale); - } + /// Ignore digits that are out of precision. + while (!buf.eof() && isNumericASCII(*buf.position())) + ++buf.position(); } - datetime64 = DecimalUtils::decimalFromComponents(c, scale); + datetime64 = DecimalUtils::decimalFromComponents(components, scale); return ReturnType(true); } diff --git a/tests/queries/0_stateless/01259_datetime64_ubsan.sql b/tests/queries/0_stateless/01259_datetime64_ubsan.sql index 3cba78c713f..4bc7a71dac3 100644 --- a/tests/queries/0_stateless/01259_datetime64_ubsan.sql +++ b/tests/queries/0_stateless/01259_datetime64_ubsan.sql @@ -1,2 +1,2 @@ -select now64(10); -- { serverError 407 } +select now64(10); -- { serverError 69 } select length(toString(now64(9))); diff --git a/tests/queries/0_stateless/01268_DateTime64_in_WHERE.sql b/tests/queries/0_stateless/01268_DateTime64_in_WHERE.sql index 4ffcf3be3c9..63d9a11daaa 100644 --- a/tests/queries/0_stateless/01268_DateTime64_in_WHERE.sql +++ b/tests/queries/0_stateless/01268_DateTime64_in_WHERE.sql @@ -6,7 +6,7 @@ WITH '2020-02-05 14:34:12.333' as S, toDateTime64(S, 3) as DT64 SELECT * WHERE D WITH '2020-02-05 14:34:12.333' as S, toDateTime64(S, 3) as DT64 SELECT * WHERE materialize(S) = DT64; -- {serverError 43} SELECT * WHERE toDateTime64(123.345, 3) == 'ABCD'; -- {serverError 53} -- invalid DateTime64 string -SELECT * WHERE toDateTime64(123.345, 3) == '2020-02-05 14:34:12.33333333333333333333333333333333333333333333333333333333'; -- {serverError 53} -- invalid string length +SELECT * WHERE toDateTime64(123.345, 3) == '2020-02-05 14:34:12.33333333333333333333333333333333333333333333333333333333'; SELECT 'in SELECT'; WITH '2020-02-05 14:34:12.333' as S, toDateTime64(S, 3) as DT64 SELECT DT64 = S; diff --git a/tests/queries/0_stateless/01340_datetime64_fpe.reference b/tests/queries/0_stateless/01340_datetime64_fpe.reference new file mode 100644 index 00000000000..0a99fbafde4 --- /dev/null +++ b/tests/queries/0_stateless/01340_datetime64_fpe.reference @@ -0,0 +1,22 @@ +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 +2011-11-11 11:11:11 diff --git a/tests/queries/0_stateless/01340_datetime64_fpe.sql b/tests/queries/0_stateless/01340_datetime64_fpe.sql new file mode 100644 index 00000000000..3e76e3164b1 --- /dev/null +++ b/tests/queries/0_stateless/01340_datetime64_fpe.sql @@ -0,0 +1,71 @@ +WITH toDateTime64('2019-09-16 19:20:12.3456789102019-09-16 19:20:12.345678910', 0) AS dt64 SELECT dt64; -- { serverError 6 } + +SELECT toDateTime64('2011-11-11 11:11:11.1234567890123456789', 0); +SELECT toDateTime64('2011-11-11 11:11:11.-12345678901234567890', 0); -- { serverError 6 } + + +SELECT toDateTime64('2011-11-11 11:11:11.1', 0); +SELECT toDateTime64('2011-11-11 11:11:11.11', 0); +SELECT toDateTime64('2011-11-11 11:11:11.111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.1111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.11111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.1111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.11111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.111111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.1111111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.11111111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.111111111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.1111111111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.11111111111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.111111111111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.1111111111111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.11111111111111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.111111111111111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.1111111111111111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.11111111111111111111', 0); +SELECT toDateTime64('2011-11-11 11:11:11.111111111111111111111', 0); + +SELECT toDateTime64('2011-11-11 11:11:11.-1', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-11', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-1111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-11111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-1111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-11111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-111111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-1111111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-11111111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-111111111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-1111111111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-11111111111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-111111111111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-1111111111111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-11111111111111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-111111111111111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-1111111111111111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-11111111111111111111', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.-111111111111111111111', 0); -- { serverError 6 } + +SELECT toDateTime64('2011-11-11 11:11:11.+1', 0); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.++11', 10); -- { serverError 69 } +SELECT toDateTime64('2011-11-11 11:11:11.+111', 3); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.+++1111', 5); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.+11111', 7); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.+++++111111', 2); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.+1111111', 1); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.++++++11111111', 8); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.+111111111', 9); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.+++++++1111111111', 6); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.+11111111111', 4); -- { serverError 6 } +SELECT toDateTime64('2011-11-11 11:11:11.++++++++111111111111', 11); -- { serverError 69 } +SELECT toDateTime64('2011-11-11 11:11:11.+1111111111111', 15); -- { serverError 69 } +SELECT toDateTime64('2011-11-11 11:11:11.+++++++++11111111111111', 13); -- { serverError 69 } +SELECT toDateTime64('2011-11-11 11:11:11.+111111111111111', 12); -- { serverError 69 } +SELECT toDateTime64('2011-11-11 11:11:11.++++++++++1111111111111111', 16); -- { serverError 69 } +SELECT toDateTime64('2011-11-11 11:11:11.+11111111111111111', 14); -- { serverError 69 } +SELECT toDateTime64('2011-11-11 11:11:11.+++++++++++111111111111111111', 15); -- { serverError 69 } +SELECT toDateTime64('2011-11-11 11:11:11.+1111111111111111111', 17); -- { serverError 69 } +SELECT toDateTime64('2011-11-11 11:11:11.++++++++++++11111111111111111111', 19); -- { serverError 69 } +SELECT toDateTime64('2011-11-11 11:11:11.+111111111111111111111', 18); -- { serverError 69 } diff --git a/tests/queries/0_stateless/01341_datetime64_wrong_supertype.reference b/tests/queries/0_stateless/01341_datetime64_wrong_supertype.reference new file mode 100644 index 00000000000..09076dd68db --- /dev/null +++ b/tests/queries/0_stateless/01341_datetime64_wrong_supertype.reference @@ -0,0 +1 @@ +['2000-01-01 01:01:01.123000','2000-01-01 01:01:01.123456'] diff --git a/tests/queries/0_stateless/01341_datetime64_wrong_supertype.sql b/tests/queries/0_stateless/01341_datetime64_wrong_supertype.sql new file mode 100644 index 00000000000..39acaf93e34 --- /dev/null +++ b/tests/queries/0_stateless/01341_datetime64_wrong_supertype.sql @@ -0,0 +1 @@ +SELECT [toDateTime64('2000-01-01 01:01:01.123', 3), toDateTime64('2000-01-01 01:01:01.123456', 6)];