Prohibit toUnixTimestamp(Date())

Making it implicitly cast to Date() does not looks correct, since before
it returns somewhat unexpected result:

    SELECT toUnixTimestamp(today())

    ┌─toUnixTimestamp(today())─┐
    │                    18591 │
    └──────────────────────────┘
This commit is contained in:
Azat Khuzhin 2020-11-25 00:11:28 +03:00
parent 3ab9ac03df
commit 17f6c82ffa
3 changed files with 11 additions and 3 deletions

View File

@ -91,6 +91,9 @@ inline UInt32 extractToDecimalScale(const ColumnWithTypeAndName & named_column)
return field.get<UInt32>(); return field.get<UInt32>();
} }
/// Function toUnixTimestamp has exactly the same implementation as toDateTime of String type.
struct NameToUnixTimestamp { static constexpr auto name = "toUnixTimestamp"; };
/** Conversion of number types to each other, enums to numbers, dates and datetimes to numbers and back: done by straight assignment. /** Conversion of number types to each other, enums to numbers, dates and datetimes to numbers and back: done by straight assignment.
* (Date is represented internally as number of days from some day; DateTime - as unix timestamp) * (Date is represented internally as number of days from some day; DateTime - as unix timestamp)
@ -111,6 +114,13 @@ struct ConvertImpl
using ColVecFrom = typename FromDataType::ColumnType; using ColVecFrom = typename FromDataType::ColumnType;
using ColVecTo = typename ToDataType::ColumnType; using ColVecTo = typename ToDataType::ColumnType;
if (std::is_same_v<Name, NameToUnixTimestamp>)
{
if (isDate(named_from.type))
throw Exception("Illegal column " + named_from.column->getName() + " of first argument of function " + Name::name,
ErrorCodes::ILLEGAL_COLUMN);
}
if constexpr ((IsDataTypeDecimal<FromDataType> || IsDataTypeDecimal<ToDataType>) if constexpr ((IsDataTypeDecimal<FromDataType> || IsDataTypeDecimal<ToDataType>)
&& !(std::is_same_v<DataTypeDateTime64, FromDataType> || std::is_same_v<DataTypeDateTime64, ToDataType>)) && !(std::is_same_v<DataTypeDateTime64, FromDataType> || std::is_same_v<DataTypeDateTime64, ToDataType>))
{ {
@ -923,9 +933,6 @@ struct ConvertImplGenericFromString
}; };
/// Function toUnixTimestamp has exactly the same implementation as toDateTime of String type.
struct NameToUnixTimestamp { static constexpr auto name = "toUnixTimestamp"; };
template <> template <>
struct ConvertImpl<DataTypeString, DataTypeUInt32, NameToUnixTimestamp> struct ConvertImpl<DataTypeString, DataTypeUInt32, NameToUnixTimestamp>
: ConvertImpl<DataTypeString, DataTypeDateTime, NameToUnixTimestamp> {}; : ConvertImpl<DataTypeString, DataTypeDateTime, NameToUnixTimestamp> {};

View File

@ -0,0 +1 @@
select toUnixTimestamp(today()); -- { serverError 44; }