@@ -403,7 +403,7 @@ class FunctionToStartOfInterval : public IFunction
403403 type_arg3->getName (), getName ());
404404 if (value_is_date && result_type == ResultType::Date) // / weird why this is && instead of || but too afraid to change it
405405 throw Exception (ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
406- " The timezone argument of function {} with interval type {} is allowed only when the 1st argument has type DateTime or DateTimt64 " ,
406+ " The timezone argument of function {} with interval type {} is allowed only when the 1st argument has type DateTime or DateTime64 " ,
407407 getName (), interval_type->getKind ().toString ());
408408 };
409409
@@ -426,24 +426,28 @@ class FunctionToStartOfInterval : public IFunction
426426 }
427427
428428 auto return_type = std::invoke (
429- [&arguments, &interval_type, &result_type_is_date, &result_type_is_datetime]() -> std::shared_ptr<IDataType>
430- {
431- if (result_type_is_date)
432- return std::make_shared<DataTypeDate>();
433- else if (result_type_is_datetime)
434- return std::make_shared<DataTypeDateTime>(extractTimeZoneNameFromFunctionArguments (arguments, 2 , 0 , false ));
435- else
429+ [&arguments, &interval_type, &result_type]() -> std::shared_ptr<IDataType>
430+ {
431+ switch (result_type)
436432 {
437- auto scale = 0 ;
438-
439- if (interval_type->getKind () == IntervalKind::Nanosecond)
440- scale = 9 ;
441- else if (interval_type->getKind () == IntervalKind::Microsecond)
442- scale = 6 ;
443- else if (interval_type->getKind () == IntervalKind::Millisecond)
444- scale = 3 ;
445-
446- return std::make_shared<DataTypeDateTime64>(scale, extractTimeZoneNameFromFunctionArguments (arguments, 2 , 0 , false ));
433+ case ResultType::Date:
434+ return std::make_shared<DataTypeDate>();
435+ case ResultType::DateTime:
436+ return std::make_shared<DataTypeDateTime>(extractTimeZoneNameFromFunctionArguments (arguments, 2 , 0 , false ));
437+ case ResultType::DateTime64:
438+ {
439+ UInt32 scale = 0 ;
440+ if (interval_type->getKind () == IntervalKind::Nanosecond)
441+ scale = 9 ;
442+ else if (interval_type->getKind () == IntervalKind::Microsecond)
443+ scale = 6 ;
444+ else if (interval_type->getKind () == IntervalKind::Millisecond)
445+ scale = 3 ;
446+
447+ return std::make_shared<DataTypeDateTime64>(scale, extractTimeZoneNameFromFunctionArguments (arguments, 2 , 0 , false ));
448+ }
449+
450+ std::unreachable ();
447451 }
448452 });
449453
@@ -489,13 +493,19 @@ class FunctionToStartOfInterval : public IFunction
489493 if (time_column_vec)
490494 return dispatchForIntervalColumn (assert_cast<const DataTypeDate &>(time_column_type), *time_column_vec, interval_column, result_type, time_zone);
491495 }
492- throw Exception (ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, " Illegal column for 1st argument of function {}, expected a Date, DateTime or DateTime64" , getName ());
496+ else if (isDate32 (time_column_type))
497+ {
498+ const auto * time_column_vec = checkAndGetColumn<ColumnDate32>(time_column_col);
499+ if (time_column_vec)
500+ return dispatchForIntervalColumn (assert_cast<const DataTypeDate32 &>(time_column_type), *time_column_vec, interval_column, result_type, time_zone);
501+ }
502+ throw Exception (ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, " Illegal column for 1st argument of function {}, expected a Date, Date32, DateTime or DateTime64" , getName ());
493503 }
494504
495505 template <typename TimeDataType, typename TimeColumnType>
496506 ColumnPtr dispatchForIntervalColumn (
497507 const TimeDataType & time_data_type, const TimeColumnType & time_column, const ColumnWithTypeAndName & interval_column,
498- const DataTypePtr & result_type, const DateLUTImpl & time_zone, UInt16 scale = 1 ) const
508+ const DataTypePtr & result_type, const DateLUTImpl & time_zone, const UInt16 scale = 1 ) const
499509 {
500510 const auto * interval_type = checkAndGetDataType<DataTypeInterval>(interval_column.type .get ());
501511 if (!interval_type)
@@ -506,7 +516,7 @@ class FunctionToStartOfInterval : public IFunction
506516 throw Exception (ErrorCodes::ILLEGAL_COLUMN, " Illegal column for 2nd argument of function {}, must be a const time interval" , getName ());
507517
508518 const auto num_units = interval_column_const_int64->getValue <Int64>();
509- switch (interval_type->getKind ())
519+ switch (interval_type->getKind ()) // NOLINT(bugprone-switch-missing-default-case)
510520 {
511521 case IntervalKind::Nanosecond:
512522 return execute<TimeDataType, TimeColumnType, DataTypeDateTime64, IntervalKind::Nanosecond>(time_data_type, time_column, num_units, result_type, time_zone, scale);
@@ -548,17 +558,17 @@ class FunctionToStartOfInterval : public IFunction
548558
549559 auto result_col = result_type->createColumn ();
550560 auto [result_null_map_data, result_value_data] = std::invoke (
551- [&result_col]() -> std::pair<NullMap *, typename ToColumnType ::Container &>
561+ [&result_col]() -> std::pair<NullMap *, typename ResultColumnType ::Container &>
552562 {
553563 if constexpr (execution_error_policy == ExecutionErrorPolicy::Null)
554564 {
555565 auto & nullable_column = assert_cast<ColumnNullable &>(*result_col);
556- auto & nested_column = assert_cast<ToColumnType &>(nullable_column.getNestedColumn ());
566+ auto & nested_column = assert_cast<ResultColumnType &>(nullable_column.getNestedColumn ());
557567 return {&nullable_column.getNullMapData (), nested_column.getData ()};
558568 }
559569 else if constexpr (execution_error_policy == ExecutionErrorPolicy::Throw)
560570 {
561- auto & target_column = assert_cast<ToColumnType &>(*result_col);
571+ auto & target_column = assert_cast<ResultColumnType &>(*result_col);
562572 return {nullptr , target_column.getData ()};
563573 }
564574 });
@@ -582,7 +592,7 @@ class FunctionToStartOfInterval : public IFunction
582592 try
583593 {
584594 result_value_data[i]
585- = static_cast <ToFieldType >(Transform<unit>::execute (time_data[i], num_units, time_zone, scale_multiplier, name));
595+ = static_cast <ResultFieldType >(Transform<unit>::execute (time_data[i], num_units, time_zone, scale_multiplier, name));
586596 if constexpr (execution_error_policy == ExecutionErrorPolicy::Null)
587597 (*result_null_map_data)[i] = false ;
588598 }
@@ -596,6 +606,7 @@ class FunctionToStartOfInterval : public IFunction
596606 return result_col;
597607 }
598608};
609+ }
599610
600611REGISTER_FUNCTION (ToStartOfInterval)
601612{
0 commit comments