mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Add cast type supprt to DateTimeTransformImpl
This commit is contained in:
parent
3936c4dc52
commit
54d526c75c
@ -319,6 +319,49 @@ SELECT
|
||||
## toDateOrNull
|
||||
|
||||
## toDateOrDefault
|
||||
Converts an input value to [Date](/docs/en/sql-reference/data-types/date.md) data type.
|
||||
If unsuccessful, returns the lower border value supported by [Date](/docs/en/sql-reference/data-types/date.md). The default value can be specified as a second argument.
|
||||
Similar to [toDate](#todate).
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
toDateOrDefault(expr [, default_value])
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `expr` — The value. [String](/docs/en/sql-reference/data-types/string.md), [Int](/docs/en/sql-reference/data-types/int-uint.md), [Date](/docs/en/sql-reference/data-types/date.md) or [DateTime](/docs/en/sql-reference/data-types/datetime.md).
|
||||
- `default_value` — The default value. [Date](/docs/en/sql-reference/data-types/date.md)
|
||||
|
||||
If `expr` is a number and looks like a UNIX timestamp (is greater than 65535), it is interpreted as a DateTime, then truncated to Date in the current timezone. If `expr` is a number and it is smaller than 65536, it is interpreted as the number of days since 1970-01-01.
|
||||
|
||||
**Returned value**
|
||||
|
||||
- A calendar date. [Date](/docs/en/sql-reference/data-types/date.md)
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
toDateOrDefault('2021-01-01', '2023-01-01'::Date),
|
||||
toDateOrDefault('xx2021-01-01', '2023-01-01'::Date);
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```response
|
||||
┌─toDateOrDefault('2021-01-01', CAST('2023-01-01', 'Date'))─┬─toDateOrDefault('xx2021-01-01', CAST('2023-01-01', 'Date'))─┐
|
||||
│ 2021-01-01 │ 2023-01-01 │
|
||||
└───────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**See Also**
|
||||
- [toDate](#todate)
|
||||
- [toDate32OrDefault](#todate32ordefault)
|
||||
|
||||
|
||||
## toDateTime
|
||||
|
||||
@ -327,6 +370,48 @@ SELECT
|
||||
## toDateTimeOrNull
|
||||
|
||||
## toDateTimeOrDefault
|
||||
Converts an input value to [DateTime](/docs/en/sql-reference/data-types/datetime.md) data type.
|
||||
If unsuccessful, returns the lower border value supported by [DateTime](/docs/en/sql-reference/data-types/datetime.md). The default value can be specified as a third argument.
|
||||
Similar to [toDateTime](#todatetime).
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
toDateTimeOrDefault(expr, [, time_zone [, default_value]])
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `expr` — The value. [String](/docs/en/sql-reference/data-types/string.md), [Int](/docs/en/sql-reference/data-types/int-uint.md), [Date](/docs/en/sql-reference/data-types/date.md) or [DateTime](/docs/en/sql-reference/data-types/datetime.md).
|
||||
- `time_zone` — Time zone.
|
||||
- `default_value` — The default value. [DateTime](/docs/en/sql-reference/data-types/datetime.md)
|
||||
|
||||
If `expr` is a number, it is interpreted as the number of seconds since the beginning of the Unix Epoch (as Unix timestamp).
|
||||
|
||||
**Returned value**
|
||||
|
||||
- A date time. [DateTime](/docs/en/sql-reference/data-types/datetime.md)
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
toDateTimeOrDefault('2021-01-01', 'UTC', '2023-01-01'::DateTime('UTC')),
|
||||
toDateTimeOrDefault('xx2021-01-01', 'UTC', '2023-01-01'::DateTime('UTC'));
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```response
|
||||
┌─toDateTimeOrDefault('2021-01-01', 'UTC', CAST('2023-01-01', 'DateTime(\'UTC\')'))─┬─toDateTimeOrDefault('xx2021-01-01', 'UTC', CAST('2023-01-01', 'DateTime(\'UTC\')'))─┐
|
||||
│ 2021-01-01 00:00:00 │ 2023-01-01 00:00:00 │
|
||||
└───────────────────────────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**See Also**
|
||||
- [toDateTime](#todatetime)
|
||||
|
||||
## toDate32
|
||||
|
||||
|
@ -21,6 +21,7 @@ namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
extern const int CANNOT_CONVERT_TYPE;
|
||||
}
|
||||
|
||||
/** Transformations.
|
||||
@ -1425,8 +1426,10 @@ struct ToDateTimeComponentsImpl
|
||||
using FactorTransform = ZeroTransform;
|
||||
};
|
||||
|
||||
struct DateTimeAccurateConvertStrategyAdditions {};
|
||||
struct DateTimeAccurateOrNullConvertStrategyAdditions {};
|
||||
|
||||
template <typename FromType, typename ToType, typename Transform, bool is_extended_result = false>
|
||||
template <typename FromType, typename ToType, typename Transform, bool is_extended_result = false, typename Additions = void *>
|
||||
struct Transformer
|
||||
{
|
||||
template <typename FromTypeVector, typename ToTypeVector>
|
||||
@ -1438,6 +1441,33 @@ struct Transformer
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
constexpr bool transformHasExtraCheck = requires(const Transform& t)
|
||||
{
|
||||
t.ExtraCheck(vec_from[i], time_zone);
|
||||
};
|
||||
|
||||
if constexpr (transformHasExtraCheck)
|
||||
{
|
||||
// if constexpr (std::is_same_v<Additions, DateTimeAccurateConvertStrategyAdditions>
|
||||
// || std::is_same_v<Additions, DateTimeAccurateOrNullConvertStrategyAdditions>)
|
||||
{
|
||||
bool checked = transform.ExtraCheck(vec_from[i], time_zone);
|
||||
if (!checked)
|
||||
{
|
||||
if (std::is_same_v<Additions, DateTimeAccurateConvertStrategyAdditions>)
|
||||
{
|
||||
// vec_to[i] = 0;
|
||||
// (*vec_null_map_to)[i] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Value in column {} cannot be safely converted into type {}",
|
||||
TypeName<ValueType>, TypeName<ValueType>);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (is_extended_result)
|
||||
vec_to[i] = static_cast<ValueType>(transform.executeExtendedResult(vec_from[i], time_zone));
|
||||
else
|
||||
@ -1446,14 +1476,14 @@ struct Transformer
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType, typename Transform, bool is_extended_result = false>
|
||||
struct DateTimeTransformImpl
|
||||
{
|
||||
template <typename Additions = void *>
|
||||
static ColumnPtr execute(
|
||||
const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/, const Transform & transform = {})
|
||||
{
|
||||
using Op = Transformer<typename FromDataType::FieldType, typename ToDataType::FieldType, Transform, is_extended_result>;
|
||||
using Op = Transformer<typename FromDataType::FieldType, typename ToDataType::FieldType, Transform, is_extended_result, Additions>;
|
||||
|
||||
const ColumnPtr source_col = arguments[0].column;
|
||||
if (const auto * sources = checkAndGetColumn<typename FromDataType::ColumnType>(source_col.get()))
|
||||
|
@ -400,7 +400,11 @@ template <typename FromType, typename ToType>
|
||||
struct ToDateTransform8Or16Signed
|
||||
{
|
||||
static constexpr auto name = "toDate";
|
||||
|
||||
static NO_SANITIZE_UNDEFINED bool ExtraCheck(const FromType & from, const DateLUTImpl &)
|
||||
{
|
||||
return from >= 0;
|
||||
}
|
||||
|
||||
static NO_SANITIZE_UNDEFINED ToType execute(const FromType & from, const DateLUTImpl &)
|
||||
{
|
||||
if (from < 0)
|
||||
@ -2884,8 +2888,16 @@ private:
|
||||
|
||||
if constexpr (IsDataTypeNumber<LeftDataType> && IsDataTypeDateOrDateTime<RightDataType>)
|
||||
{
|
||||
result_column = ConvertImpl<LeftDataType, RightDataType, FunctionName>::execute(
|
||||
arguments, result_type, input_rows_count);
|
||||
if (wrapper_cast_type == CastType::accurate)
|
||||
{
|
||||
result_column = ConvertImpl<LeftDataType, RightDataType, FunctionName>::template execute<DateTimeAccurateConvertStrategyAdditions>(
|
||||
arguments, result_type, input_rows_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
result_column = ConvertImpl<LeftDataType, RightDataType, FunctionName>::template execute<DateTimeAccurateOrNullConvertStrategyAdditions>(
|
||||
arguments, result_type, input_rows_count);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -6,3 +6,7 @@
|
||||
5
|
||||
1
|
||||
12
|
||||
2023-05-30 14:38:20
|
||||
1970-01-01 00:00:19
|
||||
2023-05-30
|
||||
1970-01-20
|
@ -22,3 +22,13 @@ SELECT accurateCast(-10, 'Decimal32(9)'); -- { serverError 407 }
|
||||
|
||||
SELECT accurateCast('123', 'FixedString(2)'); -- { serverError 131 }
|
||||
SELECT accurateCast('12', 'FixedString(2)');
|
||||
|
||||
SELECT accurateCast(-1, 'DateTime'); -- { serverError 70 }
|
||||
SELECT accurateCast('1xxx', 'DateTime'); -- { serverError 41 }
|
||||
SELECT accurateCast('2023-05-30 14:38:20', 'DateTime');
|
||||
SELECT accurateCast(19, 'DateTime');
|
||||
|
||||
SELECT accurateCast(-1, 'Date'); -- { serverError 70 }
|
||||
SELECT accurateCast('1xxx', 'Date'); -- { serverError 70 }
|
||||
SELECT accurateCast('2023-05-30', 'Date');
|
||||
SELECT accurateCast(19, 'Date');
|
||||
|
Loading…
Reference in New Issue
Block a user