#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace DB { namespace ErrorCodes { extern const int ILLEGAL_COLUMN; } template struct WeekTransformer { explicit WeekTransformer(Transform transform_) : transform(std::move(transform_)) {} template void vector(const FromVectorType & vec_from, ToVectorType & vec_to, UInt8 week_mode, const DateLUTImpl & time_zone) const { using ValueType = typename ToVectorType::value_type; size_t size = vec_from.size(); vec_to.resize(size); for (size_t i = 0; i < size; ++i) { if constexpr (is_extended_result) vec_to[i] = static_cast(transform.executeExtendedResult(vec_from[i], week_mode, time_zone)); else vec_to[i] = static_cast(transform.execute(vec_from[i], week_mode, time_zone)); } } private: const Transform transform; }; template struct CustomWeekTransformImpl { template static ColumnPtr execute(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/, Transform transform = {}) { const auto op = WeekTransformer{transform}; static constexpr UInt8 default_week_mode = 0; UInt8 week_mode = default_week_mode; if (arguments.size() > 1) { if (const auto * week_mode_column = checkAndGetColumnConst(arguments[1].column.get())) week_mode = week_mode_column->getValue(); } const DateLUTImpl & time_zone = extractTimeZoneFromFunctionArguments(arguments, 2, 0); const ColumnPtr source_col = arguments[0].column; if constexpr (std::is_same_v) { static const DateLUTImpl & utc_time_zone = DateLUT::instance("UTC"); const auto * sources = checkAndGetColumn(source_col.get()); auto col_to = ToDataType::ColumnType::create(); col_to->getData().resize(sources->size()); for (size_t i = 0; i < sources->size(); ++i) { DateTime64 dt64; ReadBufferFromString buf(sources->getDataAt(i).toView()); parseDateTime64BestEffort(dt64, 0, buf, time_zone, utc_time_zone); col_to->getData()[i] = static_cast(transform.execute(dt64, week_mode, time_zone)); } return col_to; } else if (const auto * sources = checkAndGetColumn(source_col.get())) { auto col_to = ToDataType::ColumnType::create(); op.vector(sources->getData(), col_to->getData(), week_mode, time_zone); return col_to; } else { throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of first argument of function {}", arguments[0].column->getName(), Transform::name); } } }; }