@@ -67,7 +67,7 @@ namespace
6767 return date_time_type;
6868 }
6969
70- ColumnPtr executeImpl (const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type , size_t ) const override
70+ ColumnPtr executeImpl (const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t ) const override
7171 {
7272 if (arguments.size () != 2 )
7373 throw Exception (ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, " Function {}'s arguments number must be 2." , name);
@@ -77,37 +77,47 @@ namespace
7777 if (!time_zone_const_col)
7878 throw Exception (ErrorCodes::ILLEGAL_COLUMN, " Illegal column {} of 2nd argument of function {}. Excepted const(String)." , arg2.column ->getName (), name);
7979 String time_zone_val = time_zone_const_col->getDataAt (0 ).toString ();
80- auto column = result_type-> createColumn ( );
80+ const DateLUTImpl & utc_time_zone = DateLUT::instance ( " UTC " );
8181 if (WhichDataType (arg1.type ).isDateTime ())
8282 {
8383 const auto * date_time_col = checkAndGetColumn<ColumnDateTime>(arg1.column .get ());
84- for (size_t i = 0 ; i < date_time_col->size (); ++i)
84+ size_t col_size = date_time_col->size ();
85+ using ColVecTo = DataTypeDateTime::ColumnType;
86+ typename ColVecTo::MutablePtr result_column = ColVecTo::create (col_size);
87+ typename ColVecTo::Container & result_data = result_column->getData ();
88+ for (size_t i = 0 ; i < col_size; ++i)
8589 {
8690 UInt32 date_time_val = date_time_col->getElement (i);
87- LocalDateTime date_time (date_time_val, Name::to ? DateLUT::instance ( " UTC " ) : DateLUT::instance (time_zone_val));
88- time_t time_val = date_time.to_time_t (Name::from ? DateLUT::instance ( " UTC " ) : DateLUT::instance (time_zone_val));
89- column-> insert (time_val);
91+ LocalDateTime date_time (date_time_val, Name::to ? utc_time_zone : DateLUT::instance (time_zone_val));
92+ time_t time_val = date_time.to_time_t (Name::from ? utc_time_zone : DateLUT::instance (time_zone_val));
93+ result_data[i] = static_cast <UInt32> (time_val);
9094 }
95+ return result_column;
9196 }
9297 else if (WhichDataType (arg1.type ).isDateTime64 ())
9398 {
9499 const auto * date_time_col = checkAndGetColumn<ColumnDateTime64>(arg1.column .get ());
100+ size_t col_size = date_time_col->size ();
95101 const DataTypeDateTime64 * date_time_type = static_cast <const DataTypeDateTime64 *>(arg1.type .get ());
96- Int64 scale_multiplier = DecimalUtils::scaleMultiplier<Int64>(date_time_type->getScale ());
97- for (size_t i = 0 ; i < date_time_col->size (); ++i)
102+ UInt32 col_scale = date_time_type->getScale ();
103+ Int64 scale_multiplier = DecimalUtils::scaleMultiplier<Int64>(col_scale);
104+ using ColDecimalTo = DataTypeDateTime64::ColumnType;
105+ typename ColDecimalTo::MutablePtr result_column = ColDecimalTo::create (col_size, col_scale);
106+ typename ColDecimalTo::Container & result_data = result_column->getData ();
107+ for (size_t i = 0 ; i < col_size; ++i)
98108 {
99109 DateTime64 date_time_val = date_time_col->getElement (i);
100110 Int64 seconds = date_time_val.value / scale_multiplier;
101111 Int64 micros = date_time_val.value % scale_multiplier;
102- LocalDateTime date_time (seconds, Name::to ? DateLUT::instance ( " UTC " ) : DateLUT::instance (time_zone_val));
103- time_t time_val = date_time.to_time_t (Name::from ? DateLUT::instance ( " UTC " ) : DateLUT::instance (time_zone_val));
112+ LocalDateTime date_time (seconds, Name::to ? utc_time_zone : DateLUT::instance (time_zone_val));
113+ time_t time_val = date_time.to_time_t (Name::from ? utc_time_zone : DateLUT::instance (time_zone_val));
104114 DateTime64 date_time_64 (time_val * scale_multiplier + micros);
105- column-> insert ( date_time_64) ;
115+ result_data[i] = date_time_64;
106116 }
117+ return result_column;
107118 }
108119 else
109120 throw Exception (ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, " Function {}'s 1st argument can only be datetime/datatime64. " , name);
110- return column;
111121 }
112122
113123 };
0 commit comments