diff --git a/be/src/vec/functions/function_date_or_datetime_computation.cpp b/be/src/vec/functions/function_date_or_datetime_computation.cpp index 9506835c5d..bbeb3df558 100644 --- a/be/src/vec/functions/function_date_or_datetime_computation.cpp +++ b/be/src/vec/functions/function_date_or_datetime_computation.cpp @@ -124,6 +124,9 @@ using FunctionCurrentTime = FunctionCurrentDateOrDateTime; using FunctionTimeToSec = FunctionCurrentDateOrDateTime; using FunctionSecToTime = FunctionCurrentDateOrDateTime; +using FunctionMicroSecToDateTime = TimestampToDateTime; +using FunctionMilliSecToDateTime = TimestampToDateTime; +using FunctionSecToDateTime = TimestampToDateTime; /// @TEMPORARY: for be_exec_version=2 using FunctionToWeekTwoArgsOld = @@ -179,6 +182,9 @@ void register_function_date_time_computation(SimpleFunctionFactory& factory) { factory.register_function(); factory.register_function(); factory.register_function(); + factory.register_function(); + factory.register_function(); + factory.register_function(); // alias factory.register_alias("days_add", "date_add"); diff --git a/be/src/vec/functions/function_date_or_datetime_computation.h b/be/src/vec/functions/function_date_or_datetime_computation.h index ebf9a0cb49..f77848983c 100644 --- a/be/src/vec/functions/function_date_or_datetime_computation.h +++ b/be/src/vec/functions/function_date_or_datetime_computation.h @@ -1104,6 +1104,55 @@ struct SecToTimeImpl { return Status::OK(); } }; +struct MicroSec { + static constexpr auto name = "from_microsecond"; + static constexpr Int64 ratio = 1000000; +}; +struct MilliSec { + static constexpr auto name = "from_millisecond"; + static constexpr Int64 ratio = 1000; +}; +struct Sec { + static constexpr auto name = "from_second"; + static constexpr Int64 ratio = 1; +}; +template +struct TimestampToDateTime : IFunction { + using ReturnType = DataTypeDateTimeV2; + static constexpr auto name = Impl::name; + static constexpr Int64 ratio_to_micro = (1000 * 1000) / Impl::ratio; + String get_name() const override { return name; } + + size_t get_number_of_arguments() const override { return 1; } + + DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const override { + return make_nullable(std::make_shared()); + } + + static FunctionPtr create() { return std::make_shared>(); } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) override { + const auto& arg_col = block.get_by_position(arguments[0]).column; + const auto& column_data = assert_cast(*arg_col); + auto res_col = ColumnUInt64::create(); + auto null_vector = ColumnVector::create(); + res_col->get_data().resize_fill(input_rows_count, 0); + null_vector->get_data().resize_fill(input_rows_count, false); + NullMap& null_map = null_vector->get_data(); + auto& res_data = res_col->get_data(); + const cctz::time_zone& time_zone = context->state()->timezone_obj(); + for (int i = 0; i < input_rows_count; ++i) { + Int64 value = column_data.get_element(i); + auto& dt = reinterpret_cast&>(res_data[i]); + null_map[i] = !dt.from_unixtime(value / Impl::ratio, time_zone); + dt.set_microsecond((value % Impl::ratio) * ratio_to_micro); + } + block.get_by_position(result).column = + ColumnNullable::create(std::move(res_col), std::move(null_vector)); + return Status::OK(); + } +}; struct UtcTimestampImpl { using ReturnType = DataTypeDateTime; diff --git a/be/src/vec/functions/function_timestamp.cpp b/be/src/vec/functions/function_timestamp.cpp index 1bca282f2e..3510365f46 100644 --- a/be/src/vec/functions/function_timestamp.cpp +++ b/be/src/vec/functions/function_timestamp.cpp @@ -782,6 +782,68 @@ public: } }; +struct MicroSec { + static constexpr auto name = "microsecond_timestamp"; + static constexpr Int64 ratio = 1000000; +}; +struct MilliSec { + static constexpr auto name = "millisecond_timestamp"; + static constexpr Int64 ratio = 1000; +}; +struct Sec { + static constexpr auto name = "second_timestamp"; + static constexpr Int64 ratio = 1; +}; +template +class DateTimeToTimestamp : public IFunction { +public: + using ReturnType = Int64; + static constexpr Int64 ratio_to_micro = (1000 * 1000) / Impl::ratio; + static constexpr auto name = Impl::name; + static FunctionPtr create() { return std::make_shared>(); } + + String get_name() const override { return name; } + + size_t get_number_of_arguments() const override { return 1; } + + DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const override { + return make_nullable(std::make_shared()); + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) override { + const auto& arg_col = block.get_by_position(arguments[0]).column; + const auto& column_data = assert_cast(*arg_col); + auto res_col = ColumnInt64::create(); + auto null_vector = ColumnVector::create(); + res_col->get_data().resize_fill(input_rows_count, 0); + null_vector->get_data().resize_fill(input_rows_count, false); + NullMap& null_map = null_vector->get_data(); + auto& res_data = res_col->get_data(); + const cctz::time_zone& time_zone = context->state()->timezone_obj(); + for (int i = 0; i < input_rows_count; i++) { + if (arg_col->is_null_at(i)) { + null_map[i] = true; + continue; + } + StringRef source = column_data.get_data_at(i); + const DateV2Value& dt = + reinterpret_cast&>(*source.data); + int64_t timestamp {0}; + if (!dt.unix_timestamp(×tamp, time_zone)) { + null_map[i] = true; + } else { + auto microsecond = dt.microsecond(); + timestamp = timestamp * Impl::ratio + microsecond / ratio_to_micro; + res_data[i] = timestamp; + } + } + block.get_by_position(result).column = + ColumnNullable::create(std::move(res_col), std::move(null_vector)); + return Status::OK(); + } +}; + template