github-actions[bot] commented on code in PR #39058: URL: https://github.com/apache/doris/pull/39058#discussion_r1707003201
########## be/src/vec/columns/column.h: ########## @@ -22,10 +22,9 @@ #include <fmt/format.h> Review Comment: warning: 'fmt/format.h' file not found [clang-diagnostic-error] ```cpp #include <fmt/format.h> ^ ``` ########## be/src/vec/functions/function_ip.h: ########## @@ -1226,4 +1162,138 @@ class FunctionToIP : public IFunction { } }; +class FunctionIPv4ToIPv6 : public IFunction { +public: + static constexpr auto name = "ipv4_to_ipv6"; + static FunctionPtr create() { return std::make_shared<FunctionIPv4ToIPv6>(); } + + String get_name() const override { return name; } + + size_t get_number_of_arguments() const override { return 1; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + return std::make_shared<DataTypeIPv6>(); + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) const override { + const auto& ipv4_column_with_type_and_name = block.get_by_position(arguments[0]); + const auto& [ipv4_column, ipv4_const] = + unpack_if_const(ipv4_column_with_type_and_name.column); + const auto* ipv4_addr_column = assert_cast<const ColumnIPv4*>(ipv4_column.get()); + const auto& ipv4_column_data = ipv4_addr_column->get_data(); + auto col_res = ColumnIPv6::create(input_rows_count, 0); + auto& col_res_data = col_res->get_data(); + + for (size_t i = 0; i < input_rows_count; ++i) { + auto ipv4_idx = index_check_const(i, ipv4_const); + map_ipv4_to_ipv6(ipv4_column_data[ipv4_idx], + reinterpret_cast<UInt8*>(&col_res_data[i])); + } + + block.replace_by_position(result, std::move(col_res)); + return Status::OK(); + } + +private: + static void map_ipv4_to_ipv6(IPv4 ipv4, UInt8* buf) { Review Comment: warning: pointer parameter 'buf' can be pointer to const [readability-non-const-parameter] ```suggestion static void map_ipv4_to_ipv6(IPv4 ipv4, const UInt8* buf) { ``` ########## be/src/vec/functions/function_ip.h: ########## @@ -1226,4 +1162,138 @@ } }; +class FunctionIPv4ToIPv6 : public IFunction { +public: + static constexpr auto name = "ipv4_to_ipv6"; + static FunctionPtr create() { return std::make_shared<FunctionIPv4ToIPv6>(); } + + String get_name() const override { return name; } + + size_t get_number_of_arguments() const override { return 1; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + return std::make_shared<DataTypeIPv6>(); + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) const override { + const auto& ipv4_column_with_type_and_name = block.get_by_position(arguments[0]); + const auto& [ipv4_column, ipv4_const] = + unpack_if_const(ipv4_column_with_type_and_name.column); + const auto* ipv4_addr_column = assert_cast<const ColumnIPv4*>(ipv4_column.get()); + const auto& ipv4_column_data = ipv4_addr_column->get_data(); + auto col_res = ColumnIPv6::create(input_rows_count, 0); + auto& col_res_data = col_res->get_data(); + + for (size_t i = 0; i < input_rows_count; ++i) { + auto ipv4_idx = index_check_const(i, ipv4_const); + map_ipv4_to_ipv6(ipv4_column_data[ipv4_idx], + reinterpret_cast<UInt8*>(&col_res_data[i])); + } + + block.replace_by_position(result, std::move(col_res)); + return Status::OK(); + } + +private: + static void map_ipv4_to_ipv6(IPv4 ipv4, UInt8* buf) { + unaligned_store<UInt64>(buf, 0x0000FFFF00000000ULL | static_cast<UInt64>(ipv4)); + unaligned_store<UInt64>(buf + 8, 0); + } +}; + +class FunctionCutIPv6 : public IFunction { +public: + static constexpr auto name = "cut_ipv6"; + static FunctionPtr create() { return std::make_shared<FunctionCutIPv6>(); } + + String get_name() const override { return name; } + + size_t get_number_of_arguments() const override { return 3; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + return std::make_shared<DataTypeString>(); + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) const override { + const auto& ipv6_column_with_type_and_name = block.get_by_position(arguments[0]); + const auto& bytes_to_cut_for_ipv6_column_with_type_and_name = + block.get_by_position(arguments[1]); + const auto& bytes_to_cut_for_ipv4_column_with_type_and_name = + block.get_by_position(arguments[2]); + + const auto& [ipv6_column, ipv6_const] = + unpack_if_const(ipv6_column_with_type_and_name.column); + const auto& [bytes_to_cut_for_ipv6_column, bytes_to_cut_for_ipv6_const] = + unpack_if_const(bytes_to_cut_for_ipv6_column_with_type_and_name.column); + const auto& [bytes_to_cut_for_ipv4_column, bytes_to_cut_for_ipv4_const] = + unpack_if_const(bytes_to_cut_for_ipv4_column_with_type_and_name.column); + + const auto* ipv6_addr_column = assert_cast<const ColumnIPv6*>(ipv6_column.get()); + const auto* to_cut_for_ipv6_bytes_column = + assert_cast<const ColumnInt8*>(bytes_to_cut_for_ipv6_column.get()); + const auto* to_cut_for_ipv4_bytes_column = + assert_cast<const ColumnInt8*>(bytes_to_cut_for_ipv4_column.get()); + + const auto& ipv6_addr_column_data = ipv6_addr_column->get_data(); + const auto& to_cut_for_ipv6_bytes_column_data = to_cut_for_ipv6_bytes_column->get_data(); + const auto& to_cut_for_ipv4_bytes_column_data = to_cut_for_ipv4_bytes_column->get_data(); + + auto col_res = ColumnString::create(); + ColumnString::Chars& chars_res = col_res->get_chars(); + ColumnString::Offsets& offsets_res = col_res->get_offsets(); + chars_res.resize(input_rows_count * (IPV6_MAX_TEXT_LENGTH + 1)); // + 1 for ending '\0' + offsets_res.resize(input_rows_count); + auto* begin = reinterpret_cast<char*>(chars_res.data()); + auto* pos = begin; + + for (size_t i = 0; i < input_rows_count; ++i) { + auto ipv6_idx = index_check_const(i, ipv6_const); + auto bytes_to_cut_for_ipv6_idx = index_check_const(i, bytes_to_cut_for_ipv6_const); + auto bytes_to_cut_for_ipv4_idx = index_check_const(i, bytes_to_cut_for_ipv4_const); + + auto* address = const_cast<unsigned char*>( + reinterpret_cast<const unsigned char*>(&ipv6_addr_column_data[ipv6_idx])); + Int8 bytes_to_cut_for_ipv6_count = + to_cut_for_ipv6_bytes_column_data[bytes_to_cut_for_ipv6_idx]; + Int8 bytes_to_cut_for_ipv4_count = + to_cut_for_ipv4_bytes_column_data[bytes_to_cut_for_ipv4_idx]; + + if (bytes_to_cut_for_ipv6_count > IPV6_BINARY_LENGTH) [[unlikely]] { + throw Exception(ErrorCode::INVALID_ARGUMENT, + "Illegal value for argument 2 {} of function {}", + bytes_to_cut_for_ipv6_column_with_type_and_name.type->get_name(), + get_name()); + } + + if (bytes_to_cut_for_ipv4_count > IPV6_BINARY_LENGTH) [[unlikely]] { + throw Exception(ErrorCode::INVALID_ARGUMENT, + "Illegal value for argument 3 {} of function {}", + bytes_to_cut_for_ipv4_column_with_type_and_name.type->get_name(), + get_name()); + } + + UInt8 bytes_to_cut_count = is_ipv4_mapped(address) ? bytes_to_cut_for_ipv4_count + : bytes_to_cut_for_ipv6_count; + cut_address(address, pos, bytes_to_cut_count); + offsets_res[i] = pos - begin; + } + + block.replace_by_position(result, std::move(col_res)); + return Status::OK(); + } + +private: + static bool is_ipv4_mapped(const UInt8* address) { + return (unaligned_load_little_endian<UInt64>(address + 8) == 0) && + ((unaligned_load_little_endian<UInt64>(address) & 0xFFFFFFFF00000000ULL) == + 0x0000FFFF00000000ULL); + } + + static void cut_address(unsigned char* address, char*& dst, UInt8 zeroed_tail_bytes_count) { Review Comment: warning: pointer parameter 'address' can be pointer to const [readability-non-const-parameter] ```suggestion static void cut_address(const unsigned char* address, char*& dst, UInt8 zeroed_tail_bytes_count) { ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org