Merge pull request #11875 from ClickHouse/fix-fpe-datetime64

Fix strange and wrong code around DateTime64
This commit is contained in:
alexey-milovidov 2020-06-24 12:54:04 +03:00 committed by GitHub
commit c2fba5179b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 249 additions and 126 deletions

View File

@ -1477,7 +1477,8 @@ private:
} }
else else
{ {
out_logs_buf = std::make_unique<WriteBufferFromFile>(server_logs_file, DBMS_DEFAULT_BUFFER_SIZE, O_WRONLY | O_APPEND | O_CREAT); out_logs_buf = std::make_unique<WriteBufferFromFile>(
server_logs_file, DBMS_DEFAULT_BUFFER_SIZE, O_WRONLY | O_APPEND | O_CREAT);
wb = out_logs_buf.get(); wb = out_logs_buf.get();
} }
} }

View File

@ -20,14 +20,14 @@ inline NO_SANITIZE_UNDEFINED uint64_t intExp2(int x)
return 1ULL << x; return 1ULL << x;
} }
inline uint64_t intExp10(int x) constexpr inline uint64_t intExp10(int x)
{ {
if (x < 0) if (x < 0)
return 0; return 0;
if (x > 19) if (x > 19)
return std::numeric_limits<uint64_t>::max(); return std::numeric_limits<uint64_t>::max();
static const uint64_t table[20] = constexpr uint64_t table[20] =
{ {
1ULL, 10ULL, 100ULL, 1ULL, 10ULL, 100ULL,
1000ULL, 10000ULL, 100000ULL, 1000ULL, 10000ULL, 100000ULL,
@ -44,9 +44,10 @@ inline uint64_t intExp10(int x)
namespace common namespace common
{ {
inline int exp10_i32(int x) constexpr inline int exp10_i32(int x)
{
constexpr int values[] =
{ {
static const int values[] = {
1, 1,
10, 10,
100, 100,
@ -61,74 +62,76 @@ inline int exp10_i32(int x)
return values[x]; return values[x];
} }
inline int64_t exp10_i64(int x) constexpr inline int64_t exp10_i64(int x)
{ {
static const int64_t values[] = { constexpr int64_t values[] =
1ll, {
10ll, 1LL,
100ll, 10LL,
1000ll, 100LL,
10000ll, 1000LL,
100000ll, 10000LL,
1000000ll, 100000LL,
10000000ll, 1000000LL,
100000000ll, 10000000LL,
1000000000ll, 100000000LL,
10000000000ll, 1000000000LL,
100000000000ll, 10000000000LL,
1000000000000ll, 100000000000LL,
10000000000000ll, 1000000000000LL,
100000000000000ll, 10000000000000LL,
1000000000000000ll, 100000000000000LL,
10000000000000000ll, 1000000000000000LL,
100000000000000000ll, 10000000000000000LL,
1000000000000000000ll 100000000000000000LL,
1000000000000000000LL
}; };
return values[x]; return values[x];
} }
inline __int128 exp10_i128(int x) constexpr inline __int128 exp10_i128(int x)
{ {
static const __int128 values[] = { constexpr __int128 values[] =
static_cast<__int128>(1ll), {
static_cast<__int128>(10ll), static_cast<__int128>(1LL),
static_cast<__int128>(100ll), static_cast<__int128>(10LL),
static_cast<__int128>(1000ll), static_cast<__int128>(100LL),
static_cast<__int128>(10000ll), static_cast<__int128>(1000LL),
static_cast<__int128>(100000ll), static_cast<__int128>(10000LL),
static_cast<__int128>(1000000ll), static_cast<__int128>(100000LL),
static_cast<__int128>(10000000ll), static_cast<__int128>(1000000LL),
static_cast<__int128>(100000000ll), static_cast<__int128>(10000000LL),
static_cast<__int128>(1000000000ll), static_cast<__int128>(100000000LL),
static_cast<__int128>(10000000000ll), static_cast<__int128>(1000000000LL),
static_cast<__int128>(100000000000ll), static_cast<__int128>(10000000000LL),
static_cast<__int128>(1000000000000ll), static_cast<__int128>(100000000000LL),
static_cast<__int128>(10000000000000ll), static_cast<__int128>(1000000000000LL),
static_cast<__int128>(100000000000000ll), static_cast<__int128>(10000000000000LL),
static_cast<__int128>(1000000000000000ll), static_cast<__int128>(100000000000000LL),
static_cast<__int128>(10000000000000000ll), static_cast<__int128>(1000000000000000LL),
static_cast<__int128>(100000000000000000ll), static_cast<__int128>(10000000000000000LL),
static_cast<__int128>(1000000000000000000ll), static_cast<__int128>(100000000000000000LL),
static_cast<__int128>(1000000000000000000ll) * 10ll, static_cast<__int128>(1000000000000000000LL),
static_cast<__int128>(1000000000000000000ll) * 100ll, static_cast<__int128>(1000000000000000000LL) * 10LL,
static_cast<__int128>(1000000000000000000ll) * 1000ll, static_cast<__int128>(1000000000000000000LL) * 100LL,
static_cast<__int128>(1000000000000000000ll) * 10000ll, static_cast<__int128>(1000000000000000000LL) * 1000LL,
static_cast<__int128>(1000000000000000000ll) * 100000ll, static_cast<__int128>(1000000000000000000LL) * 10000LL,
static_cast<__int128>(1000000000000000000ll) * 1000000ll, static_cast<__int128>(1000000000000000000LL) * 100000LL,
static_cast<__int128>(1000000000000000000ll) * 10000000ll, static_cast<__int128>(1000000000000000000LL) * 1000000LL,
static_cast<__int128>(1000000000000000000ll) * 100000000ll, static_cast<__int128>(1000000000000000000LL) * 10000000LL,
static_cast<__int128>(1000000000000000000ll) * 1000000000ll, static_cast<__int128>(1000000000000000000LL) * 100000000LL,
static_cast<__int128>(1000000000000000000ll) * 10000000000ll, static_cast<__int128>(1000000000000000000LL) * 1000000000LL,
static_cast<__int128>(1000000000000000000ll) * 100000000000ll, static_cast<__int128>(1000000000000000000LL) * 10000000000LL,
static_cast<__int128>(1000000000000000000ll) * 1000000000000ll, static_cast<__int128>(1000000000000000000LL) * 100000000000LL,
static_cast<__int128>(1000000000000000000ll) * 10000000000000ll, static_cast<__int128>(1000000000000000000LL) * 1000000000000LL,
static_cast<__int128>(1000000000000000000ll) * 100000000000000ll, static_cast<__int128>(1000000000000000000LL) * 10000000000000LL,
static_cast<__int128>(1000000000000000000ll) * 1000000000000000ll, static_cast<__int128>(1000000000000000000LL) * 100000000000000LL,
static_cast<__int128>(1000000000000000000ll) * 10000000000000000ll, static_cast<__int128>(1000000000000000000LL) * 1000000000000000LL,
static_cast<__int128>(1000000000000000000ll) * 100000000000000000ll, static_cast<__int128>(1000000000000000000LL) * 10000000000000000LL,
static_cast<__int128>(1000000000000000000ll) * 100000000000000000ll * 10ll, static_cast<__int128>(1000000000000000000LL) * 100000000000000000LL,
static_cast<__int128>(1000000000000000000ll) * 100000000000000000ll * 100ll, static_cast<__int128>(1000000000000000000LL) * 100000000000000000LL * 10LL,
static_cast<__int128>(1000000000000000000ll) * 100000000000000000ll * 1000ll static_cast<__int128>(1000000000000000000LL) * 100000000000000000LL * 100LL,
static_cast<__int128>(1000000000000000000LL) * 100000000000000000LL * 1000LL
}; };
return values[x]; return values[x];
} }
@ -138,7 +141,7 @@ inline __int128 exp10_i128(int x)
/// intExp10 returning the type T. /// intExp10 returning the type T.
template <typename T> template <typename T>
inline T intExp10OfSize(int x) constexpr inline T intExp10OfSize(int x)
{ {
if constexpr (sizeof(T) <= 8) if constexpr (sizeof(T) <= 8)
return intExp10(x); return intExp10(x);

View File

@ -20,19 +20,34 @@
#include <optional> #include <optional>
#include <string> #include <string>
namespace DB 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) DataTypeDateTime64::DataTypeDateTime64(UInt32 scale_, const std::string & time_zone_name)
: DataTypeDecimalBase<DateTime64>(DecimalUtils::maxPrecision<DateTime64>(), scale_), : DataTypeDecimalBase<DateTime64>(DecimalUtils::maxPrecision<DateTime64>(), scale_),
TimezoneMixin(time_zone_name) 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) DataTypeDateTime64::DataTypeDateTime64(UInt32 scale_, const TimezoneMixin & time_zone_info)
: DataTypeDecimalBase<DateTime64>(DecimalUtils::maxPrecision<DateTime64>() - scale_, scale_), : DataTypeDecimalBase<DateTime64>(DecimalUtils::maxPrecision<DateTime64>(), scale_),
TimezoneMixin(time_zone_info) 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 std::string DataTypeDateTime64::doGetName() const
{ {

View File

@ -72,7 +72,7 @@ public:
{ {
if (unlikely(precision < 1 || precision > maxPrecision())) if (unlikely(precision < 1 || precision > maxPrecision()))
throw Exception("Precision " + std::to_string(precision) + " is out of bounds", ErrorCodes::ARGUMENT_OUT_OF_BOUND); throw Exception("Precision " + std::to_string(precision) + " is out of bounds", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
if (unlikely(scale < 0 || static_cast<UInt32>(scale) > maxPrecision())) if (unlikely(scale > maxPrecision()))
throw Exception("Scale " + std::to_string(scale) + " is out of bounds", ErrorCodes::ARGUMENT_OUT_OF_BOUND); throw Exception("Scale " + std::to_string(scale) + " is out of bounds", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
} }

View File

@ -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_date = type_ids.count(TypeIndex::Date);
UInt32 have_datetime = type_ids.count(TypeIndex::DateTime); 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); bool all_date_or_datetime = type_ids.size() == (have_date + have_datetime + have_datetime64);
if (!all_date_or_datetime) 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) if (have_datetime64 == 0)
{
return std::make_shared<DataTypeDateTime>(); return std::make_shared<DataTypeDateTime>();
}
// When DateTime64 involved, make sure that supertype has whole-part precision UInt8 max_scale = 0;
// big enough to hold max whole-value of any type from `types`.
// That would sacrifice scale when comparing DateTime64 of different scales.
UInt32 max_datetime64_whole_precision = 0;
for (const auto & t : types) for (const auto & t : types)
{ {
if (const auto * dt64 = typeid_cast<const DataTypeDateTime64 *>(t.get())) if (const auto * dt64 = typeid_cast<const DataTypeDateTime64 *>(t.get()))
{ {
const auto whole_precision = dt64->getPrecision() - dt64->getScale(); const auto scale = dt64->getScale();
max_datetime64_whole_precision = std::max(whole_precision, max_datetime64_whole_precision); if (scale > max_scale)
max_scale = scale;
} }
} }
UInt32 least_decimal_precision = 0; return std::make_shared<DataTypeDateTime64>(max_scale);
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<DataTypeDateTime64>(scale);
} }
} }

View File

@ -86,7 +86,7 @@ TEST_P(LeastSuperTypeTest, getLeastSupertype)
class MostSubtypeTest : public TypeTest {}; class MostSubtypeTest : public TypeTest {};
TEST_P(MostSubtypeTest, getLeastSupertype) TEST_P(MostSubtypeTest, getMostSubtype)
{ {
if (this->expected_type) if (this->expected_type)
{ {
@ -124,9 +124,7 @@ INSTANTIATE_TEST_SUITE_P(data_type,
{"Date DateTime64(3)", "DateTime64(3)"}, {"Date DateTime64(3)", "DateTime64(3)"},
{"DateTime DateTime64(3)", "DateTime64(3)"}, {"DateTime DateTime64(3)", "DateTime64(3)"},
{"DateTime DateTime64(0)", "DateTime64(0)"}, {"DateTime DateTime64(0)", "DateTime64(0)"},
{"DateTime64(9) DateTime64(3)", "DateTime64(3)"}, {"DateTime64(9) DateTime64(3)", "DateTime64(9)"},
{"DateTime DateTime64(12)", "DateTime64(8)"},
{"Date DateTime64(15)", "DateTime64(13)"},
{"String FixedString(32) FixedString(8)", "String"}, {"String FixedString(32) FixedString(8)", "String"},

View File

@ -275,8 +275,11 @@ ReturnType readIntTextImpl(T & x, ReadBuffer & buf)
switch (*buf.position()) switch (*buf.position())
{ {
case '+': case '+':
{
break; break;
}
case '-': case '-':
{
if constexpr (is_signed_v<T>) if constexpr (is_signed_v<T>)
negative = true; negative = true;
else else
@ -287,6 +290,7 @@ ReturnType readIntTextImpl(T & x, ReadBuffer & buf)
return ReturnType(false); return ReturnType(false);
} }
break; break;
}
case '0': [[fallthrough]]; case '0': [[fallthrough]];
case '1': [[fallthrough]]; case '1': [[fallthrough]];
case '2': [[fallthrough]]; case '2': [[fallthrough]];
@ -297,20 +301,27 @@ ReturnType readIntTextImpl(T & x, ReadBuffer & buf)
case '7': [[fallthrough]]; case '7': [[fallthrough]];
case '8': [[fallthrough]]; case '8': [[fallthrough]];
case '9': case '9':
{
if constexpr (check_overflow == ReadIntTextCheckOverflow::CHECK_OVERFLOW) 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. /// Perform relativelly slow overflow check only when
if (buf.count() - initial_pos >= std::numeric_limits<T>::max_digits10) /// 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<T>::max_digits10)
{ {
if (common::mulOverflow(res, static_cast<decltype(res)>(10), res) T signed_res = res;
|| common::addOverflow(res, static_cast<decltype(res)>(*buf.position() - '0'), res)) if (common::mulOverflow<T>(signed_res, 10, signed_res)
|| common::addOverflow<T>(signed_res, (*buf.position() - '0'), signed_res))
return ReturnType(false); return ReturnType(false);
res = signed_res;
break; break;
} }
} }
res *= 10; res *= 10;
res += *buf.position() - '0'; res += *buf.position() - '0';
break; break;
}
default: default:
goto end; goto end;
} }
@ -318,7 +329,23 @@ ReturnType readIntTextImpl(T & x, ReadBuffer & buf)
} }
end: end:
x = negative ? -res : res; if (!negative)
{
x = res;
}
else
{
if constexpr (check_overflow == ReadIntTextCheckOverflow::CHECK_OVERFLOW)
{
x = res;
if (common::mulOverflow<T>(x, -1, x))
return ReturnType(false);
}
else
{
x = -res;
}
}
return ReturnType(true); return ReturnType(true);
} }
@ -658,35 +685,34 @@ inline ReturnType readDateTimeTextImpl(DateTime64 & datetime64, UInt32 scale, Re
return ReturnType(false); return ReturnType(false);
} }
DB::DecimalUtils::DecimalComponents<DateTime64::NativeType> c{static_cast<DateTime64::NativeType>(whole), 0}; DB::DecimalUtils::DecimalComponents<DateTime64::NativeType> components{static_cast<DateTime64::NativeType>(whole), 0};
if (!buf.eof() && *buf.position() == '.') if (!buf.eof() && *buf.position() == '.')
{ {
buf.ignore(1); // skip separator ++buf.position();
const auto pos_before_fractional = buf.count();
if (!tryReadIntText<ReadIntTextCheckOverflow::CHECK_OVERFLOW>(c.fractional, buf))
{
return ReturnType(false);
}
// Adjust fractional part to the scale, since decimalFromComponents knows nothing /// Read digits, up to 'scale' positions.
// about convention of ommiting trailing zero on fractional part for (size_t i = 0; i < scale; ++i)
// 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<Int32>(buf.count() - pos_before_fractional);
if (const auto adjust_scale = static_cast<Int32>(scale) - fractional_length; adjust_scale > 0)
{ {
c.fractional *= common::exp10_i64(adjust_scale); if (!buf.eof() && isNumericASCII(*buf.position()))
{
components.fractional *= 10;
components.fractional += *buf.position() - '0';
++buf.position();
} }
else if (adjust_scale < 0) else
{ {
c.fractional /= common::exp10_i64(-1 * adjust_scale); /// Adjust to scale.
components.fractional *= 10;
} }
} }
datetime64 = DecimalUtils::decimalFromComponents<DateTime64>(c, scale); /// Ignore digits that are out of precision.
while (!buf.eof() && isNumericASCII(*buf.position()))
++buf.position();
}
datetime64 = DecimalUtils::decimalFromComponents<DateTime64>(components, scale);
return ReturnType(true); return ReturnType(true);
} }

View File

@ -1,2 +1,2 @@
select now64(10); -- { serverError 407 } select now64(10); -- { serverError 69 }
select length(toString(now64(9))); select length(toString(now64(9)));

View File

@ -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} 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) == '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'; SELECT 'in SELECT';
WITH '2020-02-05 14:34:12.333' as S, toDateTime64(S, 3) as DT64 SELECT DT64 = S; WITH '2020-02-05 14:34:12.333' as S, toDateTime64(S, 3) as DT64 SELECT DT64 = S;

View File

@ -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

View File

@ -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 }

View File

@ -0,0 +1 @@
['2000-01-01 01:01:01.123000','2000-01-01 01:01:01.123456']

View File

@ -0,0 +1 @@
SELECT [toDateTime64('2000-01-01 01:01:01.123', 3), toDateTime64('2000-01-01 01:01:01.123456', 6)];