Coverage Report

Created: 2026-09-18 13:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/function_ip.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
// This file is copied from
18
// https://github.com/ClickHouse/ClickHouse/blob/master/src/Functions/FunctionsCodingIP.cpp
19
// and modified by Doris
20
21
#pragma once
22
#include <glog/logging.h>
23
24
#include <cstddef>
25
#include <memory>
26
27
#include "common/cast_set.h"
28
#include "core/assert_cast.h"
29
#include "core/block/column_with_type_and_name.h"
30
#include "core/column/column.h"
31
#include "core/column/column_const.h"
32
#include "core/column/column_nullable.h"
33
#include "core/column/column_string.h"
34
#include "core/column/column_struct.h"
35
#include "core/column/column_vector.h"
36
#include "core/data_type/data_type.h"
37
#include "core/data_type/data_type_ipv4.h"
38
#include "core/data_type/data_type_ipv6.h"
39
#include "core/data_type/data_type_nullable.h"
40
#include "core/data_type/data_type_number.h"
41
#include "core/data_type/data_type_string.h"
42
#include "core/data_type/data_type_struct.h"
43
#include "core/field.h"
44
#include "core/types.h"
45
#include "core/value/ip_address_cidr.h"
46
#include "core/value/ipv4_value.h"
47
#include "exec/common/endian.h"
48
#include "exec/common/format_ip.h"
49
#include "exec/common/ipv6_to_binary.h"
50
#include "exprs/function/function.h"
51
#include "exprs/function/function_helpers.h"
52
#include "storage/index/index_reader_helper.h"
53
#include "storage/index/inverted/inverted_index_iterator.h"
54
55
namespace doris {
56
57
class FunctionIPv4NumToString : public IFunction {
58
private:
59
    template <PrimitiveType ArgPType>
60
32
    Status execute_type(Block& block, const ColumnWithTypeAndName& argument, size_t result) const {
61
32
        using ColumnType = ColumnVector<ArgPType>;
62
32
        const ColumnPtr& column = argument.column;
63
64
32
        const auto* col = assert_cast<const ColumnType*>(column.get());
65
32
        const typename ColumnType::Container& vec_in = col->get_data();
66
32
        auto col_res = ColumnString::create();
67
68
32
        ColumnString::Chars& vec_res = col_res->get_chars();
69
32
        ColumnString::Offsets& offsets_res = col_res->get_offsets();
70
71
32
        vec_res.resize(vec_in.size() *
72
32
                       (IPV4_MAX_TEXT_LENGTH + 1)); /// the longest value is: 255.255.255.255\0
73
32
        offsets_res.resize(vec_in.size());
74
32
        char* begin = reinterpret_cast<char*>(vec_res.data());
75
32
        char* pos = begin;
76
77
32
        auto null_map = ColumnUInt8::create(vec_in.size(), 0);
78
32
        size_t src_size =
79
32
                std::min(sizeof(typename PrimitiveTypeTraits<ArgPType>::CppType), (unsigned long)4);
80
446
        for (size_t i = 0; i < vec_in.size(); ++i) {
81
414
            auto value = vec_in[i];
82
414
            if (value < IPV4_MIN_NUM_VALUE || value > IPV4_MAX_NUM_VALUE) {
83
6
                null_map->get_data()[i] = 1;
84
408
            } else {
85
408
                format_ipv4(reinterpret_cast<const unsigned char*>(&vec_in[i]), src_size, pos);
86
408
            }
87
414
            offsets_res[i] = cast_set<uint32_t>(pos - begin);
88
414
        }
89
90
32
        vec_res.resize(pos - begin);
91
32
        block.replace_by_position(result,
92
32
                                  ColumnNullable::create(std::move(col_res), std::move(null_map)));
93
32
        return Status::OK();
94
32
    }
_ZNK5doris23FunctionIPv4NumToString12execute_typeILNS_13PrimitiveTypeE3EEENS_6StatusERNS_5BlockERKNS_21ColumnWithTypeAndNameEm
Line
Count
Source
60
5
    Status execute_type(Block& block, const ColumnWithTypeAndName& argument, size_t result) const {
61
5
        using ColumnType = ColumnVector<ArgPType>;
62
5
        const ColumnPtr& column = argument.column;
63
64
5
        const auto* col = assert_cast<const ColumnType*>(column.get());
65
5
        const typename ColumnType::Container& vec_in = col->get_data();
66
5
        auto col_res = ColumnString::create();
67
68
5
        ColumnString::Chars& vec_res = col_res->get_chars();
69
5
        ColumnString::Offsets& offsets_res = col_res->get_offsets();
70
71
5
        vec_res.resize(vec_in.size() *
72
5
                       (IPV4_MAX_TEXT_LENGTH + 1)); /// the longest value is: 255.255.255.255\0
73
5
        offsets_res.resize(vec_in.size());
74
5
        char* begin = reinterpret_cast<char*>(vec_res.data());
75
5
        char* pos = begin;
76
77
5
        auto null_map = ColumnUInt8::create(vec_in.size(), 0);
78
5
        size_t src_size =
79
5
                std::min(sizeof(typename PrimitiveTypeTraits<ArgPType>::CppType), (unsigned long)4);
80
10
        for (size_t i = 0; i < vec_in.size(); ++i) {
81
5
            auto value = vec_in[i];
82
5
            if (value < IPV4_MIN_NUM_VALUE || value > IPV4_MAX_NUM_VALUE) {
83
3
                null_map->get_data()[i] = 1;
84
3
            } else {
85
2
                format_ipv4(reinterpret_cast<const unsigned char*>(&vec_in[i]), src_size, pos);
86
2
            }
87
5
            offsets_res[i] = cast_set<uint32_t>(pos - begin);
88
5
        }
89
90
5
        vec_res.resize(pos - begin);
91
5
        block.replace_by_position(result,
92
5
                                  ColumnNullable::create(std::move(col_res), std::move(null_map)));
93
5
        return Status::OK();
94
5
    }
Unexecuted instantiation: _ZNK5doris23FunctionIPv4NumToString12execute_typeILNS_13PrimitiveTypeE4EEENS_6StatusERNS_5BlockERKNS_21ColumnWithTypeAndNameEm
_ZNK5doris23FunctionIPv4NumToString12execute_typeILNS_13PrimitiveTypeE5EEENS_6StatusERNS_5BlockERKNS_21ColumnWithTypeAndNameEm
Line
Count
Source
60
4
    Status execute_type(Block& block, const ColumnWithTypeAndName& argument, size_t result) const {
61
4
        using ColumnType = ColumnVector<ArgPType>;
62
4
        const ColumnPtr& column = argument.column;
63
64
4
        const auto* col = assert_cast<const ColumnType*>(column.get());
65
4
        const typename ColumnType::Container& vec_in = col->get_data();
66
4
        auto col_res = ColumnString::create();
67
68
4
        ColumnString::Chars& vec_res = col_res->get_chars();
69
4
        ColumnString::Offsets& offsets_res = col_res->get_offsets();
70
71
4
        vec_res.resize(vec_in.size() *
72
4
                       (IPV4_MAX_TEXT_LENGTH + 1)); /// the longest value is: 255.255.255.255\0
73
4
        offsets_res.resize(vec_in.size());
74
4
        char* begin = reinterpret_cast<char*>(vec_res.data());
75
4
        char* pos = begin;
76
77
4
        auto null_map = ColumnUInt8::create(vec_in.size(), 0);
78
4
        size_t src_size =
79
4
                std::min(sizeof(typename PrimitiveTypeTraits<ArgPType>::CppType), (unsigned long)4);
80
8
        for (size_t i = 0; i < vec_in.size(); ++i) {
81
4
            auto value = vec_in[i];
82
4
            if (value < IPV4_MIN_NUM_VALUE || value > IPV4_MAX_NUM_VALUE) {
83
0
                null_map->get_data()[i] = 1;
84
4
            } else {
85
4
                format_ipv4(reinterpret_cast<const unsigned char*>(&vec_in[i]), src_size, pos);
86
4
            }
87
4
            offsets_res[i] = cast_set<uint32_t>(pos - begin);
88
4
        }
89
90
4
        vec_res.resize(pos - begin);
91
4
        block.replace_by_position(result,
92
4
                                  ColumnNullable::create(std::move(col_res), std::move(null_map)));
93
4
        return Status::OK();
94
4
    }
_ZNK5doris23FunctionIPv4NumToString12execute_typeILNS_13PrimitiveTypeE6EEENS_6StatusERNS_5BlockERKNS_21ColumnWithTypeAndNameEm
Line
Count
Source
60
23
    Status execute_type(Block& block, const ColumnWithTypeAndName& argument, size_t result) const {
61
23
        using ColumnType = ColumnVector<ArgPType>;
62
23
        const ColumnPtr& column = argument.column;
63
64
23
        const auto* col = assert_cast<const ColumnType*>(column.get());
65
23
        const typename ColumnType::Container& vec_in = col->get_data();
66
23
        auto col_res = ColumnString::create();
67
68
23
        ColumnString::Chars& vec_res = col_res->get_chars();
69
23
        ColumnString::Offsets& offsets_res = col_res->get_offsets();
70
71
23
        vec_res.resize(vec_in.size() *
72
23
                       (IPV4_MAX_TEXT_LENGTH + 1)); /// the longest value is: 255.255.255.255\0
73
23
        offsets_res.resize(vec_in.size());
74
23
        char* begin = reinterpret_cast<char*>(vec_res.data());
75
23
        char* pos = begin;
76
77
23
        auto null_map = ColumnUInt8::create(vec_in.size(), 0);
78
23
        size_t src_size =
79
23
                std::min(sizeof(typename PrimitiveTypeTraits<ArgPType>::CppType), (unsigned long)4);
80
428
        for (size_t i = 0; i < vec_in.size(); ++i) {
81
405
            auto value = vec_in[i];
82
405
            if (value < IPV4_MIN_NUM_VALUE || value > IPV4_MAX_NUM_VALUE) {
83
3
                null_map->get_data()[i] = 1;
84
402
            } else {
85
402
                format_ipv4(reinterpret_cast<const unsigned char*>(&vec_in[i]), src_size, pos);
86
402
            }
87
405
            offsets_res[i] = cast_set<uint32_t>(pos - begin);
88
405
        }
89
90
23
        vec_res.resize(pos - begin);
91
23
        block.replace_by_position(result,
92
23
                                  ColumnNullable::create(std::move(col_res), std::move(null_map)));
93
23
        return Status::OK();
94
23
    }
95
96
public:
97
    static constexpr auto name = "ipv4_num_to_string";
98
31
    static FunctionPtr create() { return std::make_shared<FunctionIPv4NumToString>(); }
99
100
1
    String get_name() const override { return name; }
101
102
24
    size_t get_number_of_arguments() const override { return 1; }
103
104
24
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
105
24
        return make_nullable(std::make_shared<DataTypeString>());
106
24
    }
107
108
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
109
32
                        uint32_t result, size_t input_rows_count) const override {
110
32
        ColumnWithTypeAndName& argument = block.get_by_position(arguments[0]);
111
112
32
        switch (argument.type->get_primitive_type()) {
113
5
        case PrimitiveType::TYPE_TINYINT:
114
5
            return execute_type<TYPE_TINYINT>(block, argument, result);
115
0
            break;
116
0
        case PrimitiveType::TYPE_SMALLINT:
117
0
            return execute_type<TYPE_SMALLINT>(block, argument, result);
118
0
            break;
119
4
        case PrimitiveType::TYPE_INT:
120
4
            return execute_type<TYPE_INT>(block, argument, result);
121
0
            break;
122
23
        case PrimitiveType::TYPE_BIGINT:
123
23
            return execute_type<TYPE_BIGINT>(block, argument, result);
124
0
            break;
125
0
        default:
126
0
            break;
127
32
        }
128
129
0
        return Status::InternalError(
130
0
                "Illegal column {} of argument of function {}, expected Int8 or Int16 or Int32 or "
131
0
                "Int64",
132
0
                argument.name, get_name());
133
32
    }
134
};
135
136
/// Since IPExceptionMode means wider scope, we use more specific name here.
137
enum class IPConvertExceptionMode : uint8_t { Throw, Default, Null };
138
139
3.45k
static inline bool try_parse_ipv4(const char* begin, const char* end, Int64& result_value) {
140
3.45k
    return parse_ipv4_whole(begin, end, reinterpret_cast<unsigned char*>(&result_value));
141
3.45k
}
142
143
template <IPConvertExceptionMode exception_mode, typename ToColumn>
144
120
ColumnPtr convert_to_ipv4(ColumnPtr column, const PaddedPODArray<UInt8>* null_map = nullptr) {
145
120
    const auto* column_string = assert_cast<const ColumnString*>(column.get());
146
147
120
    size_t column_size = column_string->size();
148
149
120
    ColumnUInt8::MutablePtr col_null_map_to;
150
120
    ColumnUInt8::Container* vec_null_map_to = nullptr;
151
152
120
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
153
52
        col_null_map_to = ColumnUInt8::create(column_size, false);
154
52
        vec_null_map_to = &col_null_map_to->get_data();
155
52
    }
156
157
120
    auto col_res = ToColumn::create(column_size, 0);
158
120
    auto& vec_res = col_res->get_data();
159
160
1.68k
    for (size_t i = 0; i < vec_res.size(); ++i) {
161
1.56k
        if (null_map && (*null_map)[i]) {
162
17
            if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
163
1
                throw Exception(
164
1
                        ErrorCode::INVALID_ARGUMENT,
165
1
                        "Null Input, you may consider convert it to a valid default IPv4 value "
166
1
                        "like '0.0.0.0' first");
167
1
            }
168
0
            vec_res[i] = 0;
169
17
            if constexpr (exception_mode == IPConvertExceptionMode::Null) {
170
5
                (*vec_null_map_to)[i] = true;
171
5
            }
172
17
            continue;
173
17
        }
174
1.55k
        const auto src = column_string->get_data_at(i);
175
1.55k
        bool parse_result = try_parse_ipv4(src.begin(), src.end(), vec_res[i]);
176
177
1.55k
        if (!parse_result) {
178
529
            if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
179
7
                throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value");
180
259
            } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
181
259
                vec_res[i] = 0;
182
263
            } else if constexpr (exception_mode == IPConvertExceptionMode::Null) {
183
263
                (*vec_null_map_to)[i] = true;
184
263
                vec_res[i] = 0;
185
263
            }
186
529
        }
187
1.55k
    }
188
189
120
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
190
52
        return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to));
191
52
    }
192
0
    return col_res;
193
120
}
_ZN5doris15convert_to_ipv4ILNS_22IPConvertExceptionModeE0ENS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EES9_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE
Line
Count
Source
144
16
ColumnPtr convert_to_ipv4(ColumnPtr column, const PaddedPODArray<UInt8>* null_map = nullptr) {
145
16
    const auto* column_string = assert_cast<const ColumnString*>(column.get());
146
147
16
    size_t column_size = column_string->size();
148
149
16
    ColumnUInt8::MutablePtr col_null_map_to;
150
16
    ColumnUInt8::Container* vec_null_map_to = nullptr;
151
152
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
153
        col_null_map_to = ColumnUInt8::create(column_size, false);
154
        vec_null_map_to = &col_null_map_to->get_data();
155
    }
156
157
16
    auto col_res = ToColumn::create(column_size, 0);
158
16
    auto& vec_res = col_res->get_data();
159
160
155
    for (size_t i = 0; i < vec_res.size(); ++i) {
161
139
        if (null_map && (*null_map)[i]) {
162
1
            if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
163
1
                throw Exception(
164
1
                        ErrorCode::INVALID_ARGUMENT,
165
1
                        "Null Input, you may consider convert it to a valid default IPv4 value "
166
1
                        "like '0.0.0.0' first");
167
1
            }
168
0
            vec_res[i] = 0;
169
            if constexpr (exception_mode == IPConvertExceptionMode::Null) {
170
                (*vec_null_map_to)[i] = true;
171
            }
172
1
            continue;
173
1
        }
174
138
        const auto src = column_string->get_data_at(i);
175
138
        bool parse_result = try_parse_ipv4(src.begin(), src.end(), vec_res[i]);
176
177
138
        if (!parse_result) {
178
7
            if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
179
7
                throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value");
180
            } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
181
                vec_res[i] = 0;
182
            } else if constexpr (exception_mode == IPConvertExceptionMode::Null) {
183
                (*vec_null_map_to)[i] = true;
184
                vec_res[i] = 0;
185
            }
186
7
        }
187
138
    }
188
189
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
190
        return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to));
191
    }
192
16
    return col_res;
193
16
}
_ZN5doris15convert_to_ipv4ILNS_22IPConvertExceptionModeE1ENS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EES9_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE
Line
Count
Source
144
52
ColumnPtr convert_to_ipv4(ColumnPtr column, const PaddedPODArray<UInt8>* null_map = nullptr) {
145
52
    const auto* column_string = assert_cast<const ColumnString*>(column.get());
146
147
52
    size_t column_size = column_string->size();
148
149
52
    ColumnUInt8::MutablePtr col_null_map_to;
150
52
    ColumnUInt8::Container* vec_null_map_to = nullptr;
151
152
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
153
        col_null_map_to = ColumnUInt8::create(column_size, false);
154
        vec_null_map_to = &col_null_map_to->get_data();
155
    }
156
157
52
    auto col_res = ToColumn::create(column_size, 0);
158
52
    auto& vec_res = col_res->get_data();
159
160
958
    for (size_t i = 0; i < vec_res.size(); ++i) {
161
906
        if (null_map && (*null_map)[i]) {
162
            if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
163
                throw Exception(
164
                        ErrorCode::INVALID_ARGUMENT,
165
                        "Null Input, you may consider convert it to a valid default IPv4 value "
166
                        "like '0.0.0.0' first");
167
            }
168
11
            vec_res[i] = 0;
169
            if constexpr (exception_mode == IPConvertExceptionMode::Null) {
170
                (*vec_null_map_to)[i] = true;
171
            }
172
11
            continue;
173
11
        }
174
895
        const auto src = column_string->get_data_at(i);
175
895
        bool parse_result = try_parse_ipv4(src.begin(), src.end(), vec_res[i]);
176
177
895
        if (!parse_result) {
178
            if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
179
                throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value");
180
259
            } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
181
259
                vec_res[i] = 0;
182
            } else if constexpr (exception_mode == IPConvertExceptionMode::Null) {
183
                (*vec_null_map_to)[i] = true;
184
                vec_res[i] = 0;
185
            }
186
259
        }
187
895
    }
188
189
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
190
        return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to));
191
    }
192
52
    return col_res;
193
52
}
_ZN5doris15convert_to_ipv4ILNS_22IPConvertExceptionModeE2ENS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EES9_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE
Line
Count
Source
144
52
ColumnPtr convert_to_ipv4(ColumnPtr column, const PaddedPODArray<UInt8>* null_map = nullptr) {
145
52
    const auto* column_string = assert_cast<const ColumnString*>(column.get());
146
147
52
    size_t column_size = column_string->size();
148
149
52
    ColumnUInt8::MutablePtr col_null_map_to;
150
52
    ColumnUInt8::Container* vec_null_map_to = nullptr;
151
152
52
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
153
52
        col_null_map_to = ColumnUInt8::create(column_size, false);
154
52
        vec_null_map_to = &col_null_map_to->get_data();
155
52
    }
156
157
52
    auto col_res = ToColumn::create(column_size, 0);
158
52
    auto& vec_res = col_res->get_data();
159
160
576
    for (size_t i = 0; i < vec_res.size(); ++i) {
161
524
        if (null_map && (*null_map)[i]) {
162
            if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
163
                throw Exception(
164
                        ErrorCode::INVALID_ARGUMENT,
165
                        "Null Input, you may consider convert it to a valid default IPv4 value "
166
                        "like '0.0.0.0' first");
167
            }
168
5
            vec_res[i] = 0;
169
5
            if constexpr (exception_mode == IPConvertExceptionMode::Null) {
170
5
                (*vec_null_map_to)[i] = true;
171
5
            }
172
5
            continue;
173
5
        }
174
519
        const auto src = column_string->get_data_at(i);
175
519
        bool parse_result = try_parse_ipv4(src.begin(), src.end(), vec_res[i]);
176
177
519
        if (!parse_result) {
178
            if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
179
                throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value");
180
            } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
181
                vec_res[i] = 0;
182
263
            } else if constexpr (exception_mode == IPConvertExceptionMode::Null) {
183
263
                (*vec_null_map_to)[i] = true;
184
263
                vec_res[i] = 0;
185
263
            }
186
263
        }
187
519
    }
188
189
52
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
190
52
        return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to));
191
52
    }
192
0
    return col_res;
193
52
}
194
195
template <IPConvertExceptionMode exception_mode>
196
class FunctionIPv4StringToNum : public IFunction {
197
public:
198
    static constexpr auto name = exception_mode == IPConvertExceptionMode::Throw
199
                                         ? "ipv4_string_to_num"
200
                                         : (exception_mode == IPConvertExceptionMode::Default
201
                                                    ? "ipv4_string_to_num_or_default"
202
                                                    : "ipv4_string_to_num_or_null");
203
204
72
    static FunctionPtr create() {
205
72
        return std::make_shared<FunctionIPv4StringToNum<exception_mode>>();
206
72
    }
_ZN5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE0EE6createEv
Line
Count
Source
204
16
    static FunctionPtr create() {
205
16
        return std::make_shared<FunctionIPv4StringToNum<exception_mode>>();
206
16
    }
_ZN5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE1EE6createEv
Line
Count
Source
204
26
    static FunctionPtr create() {
205
26
        return std::make_shared<FunctionIPv4StringToNum<exception_mode>>();
206
26
    }
_ZN5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE2EE6createEv
Line
Count
Source
204
30
    static FunctionPtr create() {
205
30
        return std::make_shared<FunctionIPv4StringToNum<exception_mode>>();
206
30
    }
207
208
3
    String get_name() const override { return name; }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE0EE8get_nameB5cxx11Ev
Line
Count
Source
208
1
    String get_name() const override { return name; }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE1EE8get_nameB5cxx11Ev
Line
Count
Source
208
1
    String get_name() const override { return name; }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE2EE8get_nameB5cxx11Ev
Line
Count
Source
208
1
    String get_name() const override { return name; }
209
210
51
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE0EE23get_number_of_argumentsEv
Line
Count
Source
210
9
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE1EE23get_number_of_argumentsEv
Line
Count
Source
210
19
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE2EE23get_number_of_argumentsEv
Line
Count
Source
210
23
    size_t get_number_of_arguments() const override { return 1; }
211
212
51
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
213
51
        auto result_type = std::make_shared<DataTypeInt64>();
214
215
51
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
216
23
            return make_nullable(result_type);
217
23
        }
218
219
0
        return result_type;
220
51
    }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE0EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
212
9
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
213
9
        auto result_type = std::make_shared<DataTypeInt64>();
214
215
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
216
            return make_nullable(result_type);
217
        }
218
219
9
        return result_type;
220
9
    }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE1EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
212
19
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
213
19
        auto result_type = std::make_shared<DataTypeInt64>();
214
215
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
216
            return make_nullable(result_type);
217
        }
218
219
19
        return result_type;
220
19
    }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE2EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
212
23
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
213
23
        auto result_type = std::make_shared<DataTypeInt64>();
214
215
23
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
216
23
            return make_nullable(result_type);
217
23
        }
218
219
0
        return result_type;
220
23
    }
221
222
171
    bool use_default_implementation_for_nulls() const override { return false; }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE0EE36use_default_implementation_for_nullsEv
Line
Count
Source
222
25
    bool use_default_implementation_for_nulls() const override { return false; }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE1EE36use_default_implementation_for_nullsEv
Line
Count
Source
222
71
    bool use_default_implementation_for_nulls() const override { return false; }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE2EE36use_default_implementation_for_nullsEv
Line
Count
Source
222
75
    bool use_default_implementation_for_nulls() const override { return false; }
223
224
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
225
119
                        uint32_t result, size_t input_rows_count) const override {
226
119
        ColumnPtr column =
227
119
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
228
119
        ColumnPtr null_map_column;
229
119
        const NullMap* null_map = nullptr;
230
119
        if (const auto* column_nullable = check_and_get_column<ColumnNullable>(column.get())) {
231
84
            column = column_nullable->get_nested_column_ptr();
232
84
            null_map_column = column_nullable->get_null_map_column_ptr();
233
84
            null_map = &column_nullable->get_null_map_data();
234
84
        }
235
236
119
        auto col_res = convert_to_ipv4<exception_mode, ColumnInt64>(column, null_map);
237
238
119
        if (null_map && exception_mode == IPConvertExceptionMode::Null) {
239
40
            block.replace_by_position(
240
40
                    result, ColumnNullable::create(std::move(col_res), std::move(null_map_column)));
241
79
        } else {
242
79
            block.replace_by_position(result, std::move(col_res));
243
79
        }
244
119
        return Status::OK();
245
119
    }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE0EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
225
16
                        uint32_t result, size_t input_rows_count) const override {
226
16
        ColumnPtr column =
227
16
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
228
16
        ColumnPtr null_map_column;
229
16
        const NullMap* null_map = nullptr;
230
16
        if (const auto* column_nullable = check_and_get_column<ColumnNullable>(column.get())) {
231
10
            column = column_nullable->get_nested_column_ptr();
232
10
            null_map_column = column_nullable->get_null_map_column_ptr();
233
10
            null_map = &column_nullable->get_null_map_data();
234
10
        }
235
236
16
        auto col_res = convert_to_ipv4<exception_mode, ColumnInt64>(column, null_map);
237
238
16
        if (null_map && exception_mode == IPConvertExceptionMode::Null) {
239
0
            block.replace_by_position(
240
0
                    result, ColumnNullable::create(std::move(col_res), std::move(null_map_column)));
241
16
        } else {
242
16
            block.replace_by_position(result, std::move(col_res));
243
16
        }
244
16
        return Status::OK();
245
16
    }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE1EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
225
52
                        uint32_t result, size_t input_rows_count) const override {
226
52
        ColumnPtr column =
227
52
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
228
52
        ColumnPtr null_map_column;
229
52
        const NullMap* null_map = nullptr;
230
52
        if (const auto* column_nullable = check_and_get_column<ColumnNullable>(column.get())) {
231
34
            column = column_nullable->get_nested_column_ptr();
232
34
            null_map_column = column_nullable->get_null_map_column_ptr();
233
34
            null_map = &column_nullable->get_null_map_data();
234
34
        }
235
236
52
        auto col_res = convert_to_ipv4<exception_mode, ColumnInt64>(column, null_map);
237
238
52
        if (null_map && exception_mode == IPConvertExceptionMode::Null) {
239
0
            block.replace_by_position(
240
0
                    result, ColumnNullable::create(std::move(col_res), std::move(null_map_column)));
241
52
        } else {
242
52
            block.replace_by_position(result, std::move(col_res));
243
52
        }
244
52
        return Status::OK();
245
52
    }
_ZNK5doris23FunctionIPv4StringToNumILNS_22IPConvertExceptionModeE2EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
225
51
                        uint32_t result, size_t input_rows_count) const override {
226
51
        ColumnPtr column =
227
51
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
228
51
        ColumnPtr null_map_column;
229
51
        const NullMap* null_map = nullptr;
230
51
        if (const auto* column_nullable = check_and_get_column<ColumnNullable>(column.get())) {
231
40
            column = column_nullable->get_nested_column_ptr();
232
40
            null_map_column = column_nullable->get_null_map_column_ptr();
233
40
            null_map = &column_nullable->get_null_map_data();
234
40
        }
235
236
51
        auto col_res = convert_to_ipv4<exception_mode, ColumnInt64>(column, null_map);
237
238
51
        if (null_map && exception_mode == IPConvertExceptionMode::Null) {
239
40
            block.replace_by_position(
240
40
                    result, ColumnNullable::create(std::move(col_res), std::move(null_map_column)));
241
40
        } else {
242
11
            block.replace_by_position(result, std::move(col_res));
243
11
        }
244
51
        return Status::OK();
245
51
    }
246
};
247
248
template <typename T>
249
void process_ipv6_column(const ColumnPtr& column, size_t input_rows_count,
250
                         ColumnString::Chars& vec_res, ColumnString::Offsets& offsets_res,
251
94
                         ColumnUInt8::MutablePtr& null_map, unsigned char* ipv6_address_data) {
252
94
    auto* begin = reinterpret_cast<char*>(vec_res.data());
253
94
    auto* pos = begin;
254
255
94
    const auto* col = assert_cast<const T*>(column.get());
256
257
979
    for (size_t i = 0; i < input_rows_count; ++i) {
258
885
        bool is_empty = false;
259
260
885
        if constexpr (std::is_same_v<T, ColumnIPv6>) {
261
26
            const auto& vec_in = col->get_data();
262
26
            memcpy(ipv6_address_data, reinterpret_cast<const unsigned char*>(&vec_in[i]),
263
26
                   IPV6_BINARY_LENGTH);
264
859
        } else { // ColumnString
265
859
            const auto str_ref = col->get_data_at(i);
266
859
            const char* value = str_ref.data;
267
859
            size_t value_size = str_ref.size;
268
269
859
            if (value_size > IPV6_BINARY_LENGTH || value == nullptr || value_size == 0) {
270
276
                is_empty = true;
271
583
            } else {
272
583
                memcpy(ipv6_address_data, value, value_size);
273
583
                memset(ipv6_address_data + value_size, 0, IPV6_BINARY_LENGTH - value_size);
274
583
            }
275
859
        }
276
277
885
        if (is_empty) {
278
276
            null_map->get_data()[i] = 1;
279
609
        } else {
280
609
            if constexpr (std::is_same_v<T, ColumnIPv6>) {
281
                // ipv6 is little-endian byte order storage in doris
282
                // so parsing ipv6 in little-endian byte order
283
26
                format_ipv6(ipv6_address_data, pos);
284
583
            } else {
285
                // 16 bytes ipv6 string is big-endian byte order storage in doris
286
                // so transfer to little-endian firstly
287
583
                std::reverse(ipv6_address_data, ipv6_address_data + IPV6_BINARY_LENGTH);
288
583
                format_ipv6(ipv6_address_data, pos);
289
583
            }
290
609
        }
291
885
        offsets_res[i] = cast_set<uint32_t>(pos - begin);
292
885
    }
293
94
}
_ZN5doris19process_ipv6_columnINS_12ColumnVectorILNS_13PrimitiveTypeE37EEEEEvRKNS_3COWINS_7IColumnEE13immutable_ptrIS5_EEmRNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNSB_IjLm4096ESE_Lm16ELm15EEERNS6_11mutable_ptrINS1_ILS2_2EEEEEPh
Line
Count
Source
251
10
                         ColumnUInt8::MutablePtr& null_map, unsigned char* ipv6_address_data) {
252
10
    auto* begin = reinterpret_cast<char*>(vec_res.data());
253
10
    auto* pos = begin;
254
255
10
    const auto* col = assert_cast<const T*>(column.get());
256
257
36
    for (size_t i = 0; i < input_rows_count; ++i) {
258
26
        bool is_empty = false;
259
260
26
        if constexpr (std::is_same_v<T, ColumnIPv6>) {
261
26
            const auto& vec_in = col->get_data();
262
26
            memcpy(ipv6_address_data, reinterpret_cast<const unsigned char*>(&vec_in[i]),
263
26
                   IPV6_BINARY_LENGTH);
264
        } else { // ColumnString
265
            const auto str_ref = col->get_data_at(i);
266
            const char* value = str_ref.data;
267
            size_t value_size = str_ref.size;
268
269
            if (value_size > IPV6_BINARY_LENGTH || value == nullptr || value_size == 0) {
270
                is_empty = true;
271
            } else {
272
                memcpy(ipv6_address_data, value, value_size);
273
                memset(ipv6_address_data + value_size, 0, IPV6_BINARY_LENGTH - value_size);
274
            }
275
        }
276
277
26
        if (is_empty) {
278
0
            null_map->get_data()[i] = 1;
279
26
        } else {
280
26
            if constexpr (std::is_same_v<T, ColumnIPv6>) {
281
                // ipv6 is little-endian byte order storage in doris
282
                // so parsing ipv6 in little-endian byte order
283
26
                format_ipv6(ipv6_address_data, pos);
284
            } else {
285
                // 16 bytes ipv6 string is big-endian byte order storage in doris
286
                // so transfer to little-endian firstly
287
                std::reverse(ipv6_address_data, ipv6_address_data + IPV6_BINARY_LENGTH);
288
                format_ipv6(ipv6_address_data, pos);
289
            }
290
26
        }
291
26
        offsets_res[i] = cast_set<uint32_t>(pos - begin);
292
26
    }
293
10
}
_ZN5doris19process_ipv6_columnINS_9ColumnStrIjEEEEvRKNS_3COWINS_7IColumnEE13immutable_ptrIS4_EEmRNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNSA_IjLm4096ESD_Lm16ELm15EEERNS5_11mutable_ptrINS_12ColumnVectorILNS_13PrimitiveTypeE2EEEEEPh
Line
Count
Source
251
84
                         ColumnUInt8::MutablePtr& null_map, unsigned char* ipv6_address_data) {
252
84
    auto* begin = reinterpret_cast<char*>(vec_res.data());
253
84
    auto* pos = begin;
254
255
84
    const auto* col = assert_cast<const T*>(column.get());
256
257
943
    for (size_t i = 0; i < input_rows_count; ++i) {
258
859
        bool is_empty = false;
259
260
        if constexpr (std::is_same_v<T, ColumnIPv6>) {
261
            const auto& vec_in = col->get_data();
262
            memcpy(ipv6_address_data, reinterpret_cast<const unsigned char*>(&vec_in[i]),
263
                   IPV6_BINARY_LENGTH);
264
859
        } else { // ColumnString
265
859
            const auto str_ref = col->get_data_at(i);
266
859
            const char* value = str_ref.data;
267
859
            size_t value_size = str_ref.size;
268
269
859
            if (value_size > IPV6_BINARY_LENGTH || value == nullptr || value_size == 0) {
270
276
                is_empty = true;
271
583
            } else {
272
583
                memcpy(ipv6_address_data, value, value_size);
273
583
                memset(ipv6_address_data + value_size, 0, IPV6_BINARY_LENGTH - value_size);
274
583
            }
275
859
        }
276
277
859
        if (is_empty) {
278
276
            null_map->get_data()[i] = 1;
279
583
        } else {
280
            if constexpr (std::is_same_v<T, ColumnIPv6>) {
281
                // ipv6 is little-endian byte order storage in doris
282
                // so parsing ipv6 in little-endian byte order
283
                format_ipv6(ipv6_address_data, pos);
284
583
            } else {
285
                // 16 bytes ipv6 string is big-endian byte order storage in doris
286
                // so transfer to little-endian firstly
287
583
                std::reverse(ipv6_address_data, ipv6_address_data + IPV6_BINARY_LENGTH);
288
583
                format_ipv6(ipv6_address_data, pos);
289
583
            }
290
583
        }
291
859
        offsets_res[i] = cast_set<uint32_t>(pos - begin);
292
859
    }
293
84
}
294
295
class FunctionIPv6NumToString : public IFunction {
296
public:
297
    static constexpr auto name = "ipv6_num_to_string";
298
67
    static FunctionPtr create() { return std::make_shared<FunctionIPv6NumToString>(); }
299
300
1
    String get_name() const override { return name; }
301
302
60
    size_t get_number_of_arguments() const override { return 1; }
303
304
60
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
305
60
        return make_nullable(std::make_shared<DataTypeString>());
306
60
    }
307
308
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
309
93
                        uint32_t result, size_t input_rows_count) const override {
310
93
        const ColumnPtr& column = block.get_by_position(arguments[0]).column;
311
312
93
        auto col_res = ColumnString::create();
313
93
        ColumnString::Chars& vec_res = col_res->get_chars();
314
93
        ColumnString::Offsets& offsets_res = col_res->get_offsets();
315
93
        vec_res.resize(input_rows_count * (IPV6_MAX_TEXT_LENGTH + 1));
316
93
        offsets_res.resize(input_rows_count);
317
318
93
        auto null_map = ColumnUInt8::create(input_rows_count, 0);
319
320
93
        unsigned char ipv6_address_data[IPV6_BINARY_LENGTH];
321
322
93
        if (check_and_get_column<ColumnIPv6>(column.get())) {
323
10
            process_ipv6_column<ColumnIPv6>(column, input_rows_count, vec_res, offsets_res,
324
10
                                            null_map, ipv6_address_data);
325
83
        } else { //ColumnString
326
83
            process_ipv6_column<ColumnString>(column, input_rows_count, vec_res, offsets_res,
327
83
                                              null_map, ipv6_address_data);
328
83
        }
329
93
        vec_res.resize(offsets_res[offsets_res.size() - 1]);
330
331
93
        block.replace_by_position(result,
332
93
                                  ColumnNullable::create(std::move(col_res), std::move(null_map)));
333
93
        return Status::OK();
334
93
    }
335
};
336
337
namespace detail {
338
template <IPConvertExceptionMode exception_mode, typename ToColumn = ColumnIPv6,
339
          typename StringColumnType>
340
ColumnPtr convert_to_ipv6(const StringColumnType& string_column,
341
209
                          const PaddedPODArray<UInt8>* null_map = nullptr) {
342
209
    const size_t column_size = string_column.size();
343
344
209
    ColumnUInt8::MutablePtr col_null_map_to;
345
209
    ColumnUInt8::Container* vec_null_map_to = nullptr;
346
347
209
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
348
118
        col_null_map_to = ColumnUInt8::create(column_size, false);
349
118
        vec_null_map_to = &col_null_map_to->get_data();
350
118
    }
351
352
209
    auto column_create = [](size_t column_size) -> typename ToColumn::MutablePtr {
353
209
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
354
196
            auto column_string = ColumnString::create();
355
196
            column_string->get_chars().reserve(column_size * IPV6_BINARY_LENGTH);
356
196
            column_string->get_offsets().reserve(column_size);
357
196
            return column_string;
358
196
        } else {
359
13
            return ColumnIPv6::create();
360
13
        }
361
209
    };
_ZZN5doris6detail15convert_to_ipv6ILNS_22IPConvertExceptionModeE0ENS_9ColumnStrIjEES4_EENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKT1_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEENKUlmE_clEm
Line
Count
Source
352
33
    auto column_create = [](size_t column_size) -> typename ToColumn::MutablePtr {
353
33
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
354
33
            auto column_string = ColumnString::create();
355
33
            column_string->get_chars().reserve(column_size * IPV6_BINARY_LENGTH);
356
33
            column_string->get_offsets().reserve(column_size);
357
33
            return column_string;
358
        } else {
359
            return ColumnIPv6::create();
360
        }
361
33
    };
_ZZN5doris6detail15convert_to_ipv6ILNS_22IPConvertExceptionModeE1ENS_9ColumnStrIjEES4_EENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKT1_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEENKUlmE_clEm
Line
Count
Source
352
45
    auto column_create = [](size_t column_size) -> typename ToColumn::MutablePtr {
353
45
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
354
45
            auto column_string = ColumnString::create();
355
45
            column_string->get_chars().reserve(column_size * IPV6_BINARY_LENGTH);
356
45
            column_string->get_offsets().reserve(column_size);
357
45
            return column_string;
358
        } else {
359
            return ColumnIPv6::create();
360
        }
361
45
    };
_ZZN5doris6detail15convert_to_ipv6ILNS_22IPConvertExceptionModeE2ENS_9ColumnStrIjEES4_EENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKT1_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEENKUlmE_clEm
Line
Count
Source
352
118
    auto column_create = [](size_t column_size) -> typename ToColumn::MutablePtr {
353
118
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
354
118
            auto column_string = ColumnString::create();
355
118
            column_string->get_chars().reserve(column_size * IPV6_BINARY_LENGTH);
356
118
            column_string->get_offsets().reserve(column_size);
357
118
            return column_string;
358
        } else {
359
            return ColumnIPv6::create();
360
        }
361
118
    };
_ZZN5doris6detail15convert_to_ipv6ILNS_22IPConvertExceptionModeE0ENS_12ColumnVectorILNS_13PrimitiveTypeE37EEENS_9ColumnStrIjEEEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EERKT1_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEENKUlmE_clEm
Line
Count
Source
352
13
    auto column_create = [](size_t column_size) -> typename ToColumn::MutablePtr {
353
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
354
            auto column_string = ColumnString::create();
355
            column_string->get_chars().reserve(column_size * IPV6_BINARY_LENGTH);
356
            column_string->get_offsets().reserve(column_size);
357
            return column_string;
358
13
        } else {
359
13
            return ColumnIPv6::create();
360
13
        }
361
13
    };
362
363
210
    auto get_vector = [](auto& col_res, size_t col_size) -> decltype(auto) {
364
210
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
365
197
            auto& vec_res = col_res->get_chars();
366
197
            vec_res.resize(col_size * IPV6_BINARY_LENGTH);
367
197
            return (vec_res);
368
197
        } else {
369
13
            auto& vec_res = col_res->get_data();
370
13
            vec_res.resize(col_size);
371
13
            return (vec_res);
372
13
        }
373
210
    };
_ZZN5doris6detail15convert_to_ipv6ILNS_22IPConvertExceptionModeE0ENS_9ColumnStrIjEES4_EENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKT1_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEENKUlRT_mE_clINS7_11mutable_ptrIS4_EEEEDcSL_m
Line
Count
Source
363
34
    auto get_vector = [](auto& col_res, size_t col_size) -> decltype(auto) {
364
34
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
365
34
            auto& vec_res = col_res->get_chars();
366
34
            vec_res.resize(col_size * IPV6_BINARY_LENGTH);
367
34
            return (vec_res);
368
        } else {
369
            auto& vec_res = col_res->get_data();
370
            vec_res.resize(col_size);
371
            return (vec_res);
372
        }
373
34
    };
_ZZN5doris6detail15convert_to_ipv6ILNS_22IPConvertExceptionModeE1ENS_9ColumnStrIjEES4_EENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKT1_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEENKUlRT_mE_clINS7_11mutable_ptrIS4_EEEEDcSL_m
Line
Count
Source
363
45
    auto get_vector = [](auto& col_res, size_t col_size) -> decltype(auto) {
364
45
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
365
45
            auto& vec_res = col_res->get_chars();
366
45
            vec_res.resize(col_size * IPV6_BINARY_LENGTH);
367
45
            return (vec_res);
368
        } else {
369
            auto& vec_res = col_res->get_data();
370
            vec_res.resize(col_size);
371
            return (vec_res);
372
        }
373
45
    };
_ZZN5doris6detail15convert_to_ipv6ILNS_22IPConvertExceptionModeE2ENS_9ColumnStrIjEES4_EENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKT1_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEENKUlRT_mE_clINS7_11mutable_ptrIS4_EEEEDcSL_m
Line
Count
Source
363
118
    auto get_vector = [](auto& col_res, size_t col_size) -> decltype(auto) {
364
118
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
365
118
            auto& vec_res = col_res->get_chars();
366
118
            vec_res.resize(col_size * IPV6_BINARY_LENGTH);
367
118
            return (vec_res);
368
        } else {
369
            auto& vec_res = col_res->get_data();
370
            vec_res.resize(col_size);
371
            return (vec_res);
372
        }
373
118
    };
_ZZN5doris6detail15convert_to_ipv6ILNS_22IPConvertExceptionModeE0ENS_12ColumnVectorILNS_13PrimitiveTypeE37EEENS_9ColumnStrIjEEEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EERKT1_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEENKUlRT_mE_clINSA_11mutable_ptrIS5_EEEEDcSO_m
Line
Count
Source
363
13
    auto get_vector = [](auto& col_res, size_t col_size) -> decltype(auto) {
364
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
365
            auto& vec_res = col_res->get_chars();
366
            vec_res.resize(col_size * IPV6_BINARY_LENGTH);
367
            return (vec_res);
368
13
        } else {
369
13
            auto& vec_res = col_res->get_data();
370
13
            vec_res.resize(col_size);
371
13
            return (vec_res);
372
13
        }
373
13
    };
374
375
209
    auto col_res = column_create(column_size);
376
209
    auto& vec_res = get_vector(col_res, column_size);
377
378
209
    int offset_inc = 1;
379
209
    ColumnString* column_string = nullptr;
380
209
    if constexpr (std::is_same_v<ToColumn, ColumnString>) {
381
196
        offset_inc = IPV6_BINARY_LENGTH;
382
196
        column_string = col_res.get();
383
196
    }
384
385
2.15k
    for (size_t out_offset = 0, i = 0; i < column_size; out_offset += offset_inc, ++i) {
386
1.95k
        const auto src = string_column.get_data_at(i);
387
1.95k
        const char* src_value = src.begin();
388
1.95k
        const char* src_end = src.end();
389
1.95k
        auto* res_value = reinterpret_cast<unsigned char*>(&vec_res[out_offset]);
390
391
1.95k
        if (null_map && (*null_map)[i]) {
392
45
            if (exception_mode == IPConvertExceptionMode::Throw) {
393
3
                throw Exception(
394
3
                        ErrorCode::INVALID_ARGUMENT,
395
3
                        "Null Input, you may consider convert it to a valid default IPv6 value "
396
3
                        "like '::' first");
397
42
            } else if (exception_mode == IPConvertExceptionMode::Default) {
398
24
                std::fill_n(&vec_res[out_offset], offset_inc, 0);
399
24
            } else {
400
18
                std::fill_n(&vec_res[out_offset], offset_inc, 0);
401
18
                (*vec_null_map_to)[i] = true;
402
18
            }
403
42
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
404
42
                DCHECK(column_string != nullptr);
405
42
                column_string->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
406
42
            }
407
42
            continue;
408
45
        }
409
410
1.91k
        bool parse_result = false;
411
1.91k
        Int64 dummy_result = 0;
412
413
        /// For both cases below: In case of failure, the function parseIPv6 fills vec_res with zero bytes.
414
415
        /// If the source IP address is parsable as an IPv4 address, then transform it into a valid IPv6 address.
416
        /// Keeping it simple by just prefixing `::ffff:` to the IPv4 address to represent it as a valid IPv6 address.
417
1.91k
        size_t string_length = src.size;
418
1.91k
        if (string_length != 0) {
419
1.90k
            if (try_parse_ipv4(src_value, src_end, dummy_result)) {
420
57
                map_ipv4_to_ipv6(static_cast<IPv4>(dummy_result), res_value);
421
57
                parse_result = true;
422
1.84k
            } else {
423
1.84k
                parse_result = parse_ipv6_whole(src_value, src_end, res_value);
424
1.84k
            }
425
1.90k
        }
426
427
1.91k
        if (parse_result && string_length != 0) {
428
1.06k
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
429
                // handling 16 bytes ipv6 string in the big-endian byte order
430
                // is aimed at conforming to human reading habits
431
1.05k
                std::reverse(res_value, res_value + IPV6_BINARY_LENGTH);
432
1.05k
            }
433
1.06k
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
434
1.05k
                auto* column_string_res = static_cast<ColumnString*>(col_res.get());
435
1.05k
                std::copy(res_value, res_value + IPV6_BINARY_LENGTH,
436
1.05k
                          column_string_res->get_chars().begin() + i * IPV6_BINARY_LENGTH);
437
1.05k
                column_string_res->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
438
1.05k
            } else {
439
14
                col_res->insert_data(reinterpret_cast<const char*>(res_value), IPV6_BINARY_LENGTH);
440
14
            }
441
1.06k
        } else {
442
846
            if (exception_mode == IPConvertExceptionMode::Throw) {
443
10
                throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value");
444
10
            }
445
836
            std::fill_n(&vec_res[out_offset], offset_inc, 0);
446
836
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
447
836
                auto* column_string_res = static_cast<ColumnString*>(col_res.get());
448
836
                column_string_res->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
449
836
            }
450
836
            if constexpr (exception_mode == IPConvertExceptionMode::Null) {
451
629
                (*vec_null_map_to)[i] = true;
452
629
            }
453
836
        }
454
1.91k
    }
455
456
196
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
457
118
        return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to));
458
118
    }
459
0
    return col_res;
460
209
}
_ZN5doris6detail15convert_to_ipv6ILNS_22IPConvertExceptionModeE0ENS_9ColumnStrIjEES4_EENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKT1_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE
Line
Count
Source
341
33
                          const PaddedPODArray<UInt8>* null_map = nullptr) {
342
33
    const size_t column_size = string_column.size();
343
344
33
    ColumnUInt8::MutablePtr col_null_map_to;
345
33
    ColumnUInt8::Container* vec_null_map_to = nullptr;
346
347
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
348
        col_null_map_to = ColumnUInt8::create(column_size, false);
349
        vec_null_map_to = &col_null_map_to->get_data();
350
    }
351
352
33
    auto column_create = [](size_t column_size) -> typename ToColumn::MutablePtr {
353
33
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
354
33
            auto column_string = ColumnString::create();
355
33
            column_string->get_chars().reserve(column_size * IPV6_BINARY_LENGTH);
356
33
            column_string->get_offsets().reserve(column_size);
357
33
            return column_string;
358
33
        } else {
359
33
            return ColumnIPv6::create();
360
33
        }
361
33
    };
362
363
33
    auto get_vector = [](auto& col_res, size_t col_size) -> decltype(auto) {
364
33
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
365
33
            auto& vec_res = col_res->get_chars();
366
33
            vec_res.resize(col_size * IPV6_BINARY_LENGTH);
367
33
            return (vec_res);
368
33
        } else {
369
33
            auto& vec_res = col_res->get_data();
370
33
            vec_res.resize(col_size);
371
33
            return (vec_res);
372
33
        }
373
33
    };
374
375
33
    auto col_res = column_create(column_size);
376
33
    auto& vec_res = get_vector(col_res, column_size);
377
378
33
    int offset_inc = 1;
379
33
    ColumnString* column_string = nullptr;
380
33
    if constexpr (std::is_same_v<ToColumn, ColumnString>) {
381
33
        offset_inc = IPV6_BINARY_LENGTH;
382
33
        column_string = col_res.get();
383
33
    }
384
385
167
    for (size_t out_offset = 0, i = 0; i < column_size; out_offset += offset_inc, ++i) {
386
143
        const auto src = string_column.get_data_at(i);
387
143
        const char* src_value = src.begin();
388
143
        const char* src_end = src.end();
389
143
        auto* res_value = reinterpret_cast<unsigned char*>(&vec_res[out_offset]);
390
391
143
        if (null_map && (*null_map)[i]) {
392
3
            if (exception_mode == IPConvertExceptionMode::Throw) {
393
3
                throw Exception(
394
3
                        ErrorCode::INVALID_ARGUMENT,
395
3
                        "Null Input, you may consider convert it to a valid default IPv6 value "
396
3
                        "like '::' first");
397
3
            } else if (exception_mode == IPConvertExceptionMode::Default) {
398
0
                std::fill_n(&vec_res[out_offset], offset_inc, 0);
399
0
            } else {
400
0
                std::fill_n(&vec_res[out_offset], offset_inc, 0);
401
0
                (*vec_null_map_to)[i] = true;
402
0
            }
403
0
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
404
0
                DCHECK(column_string != nullptr);
405
0
                column_string->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
406
0
            }
407
0
            continue;
408
3
        }
409
410
140
        bool parse_result = false;
411
140
        Int64 dummy_result = 0;
412
413
        /// For both cases below: In case of failure, the function parseIPv6 fills vec_res with zero bytes.
414
415
        /// If the source IP address is parsable as an IPv4 address, then transform it into a valid IPv6 address.
416
        /// Keeping it simple by just prefixing `::ffff:` to the IPv4 address to represent it as a valid IPv6 address.
417
140
        size_t string_length = src.size;
418
140
        if (string_length != 0) {
419
140
            if (try_parse_ipv4(src_value, src_end, dummy_result)) {
420
5
                map_ipv4_to_ipv6(static_cast<IPv4>(dummy_result), res_value);
421
5
                parse_result = true;
422
135
            } else {
423
135
                parse_result = parse_ipv6_whole(src_value, src_end, res_value);
424
135
            }
425
140
        }
426
427
140
        if (parse_result && string_length != 0) {
428
134
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
429
                // handling 16 bytes ipv6 string in the big-endian byte order
430
                // is aimed at conforming to human reading habits
431
134
                std::reverse(res_value, res_value + IPV6_BINARY_LENGTH);
432
134
            }
433
134
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
434
134
                auto* column_string_res = static_cast<ColumnString*>(col_res.get());
435
134
                std::copy(res_value, res_value + IPV6_BINARY_LENGTH,
436
134
                          column_string_res->get_chars().begin() + i * IPV6_BINARY_LENGTH);
437
134
                column_string_res->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
438
            } else {
439
                col_res->insert_data(reinterpret_cast<const char*>(res_value), IPV6_BINARY_LENGTH);
440
            }
441
134
        } else {
442
6
            if (exception_mode == IPConvertExceptionMode::Throw) {
443
6
                throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value");
444
6
            }
445
0
            std::fill_n(&vec_res[out_offset], offset_inc, 0);
446
0
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
447
0
                auto* column_string_res = static_cast<ColumnString*>(col_res.get());
448
0
                column_string_res->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
449
0
            }
450
            if constexpr (exception_mode == IPConvertExceptionMode::Null) {
451
                (*vec_null_map_to)[i] = true;
452
            }
453
0
        }
454
140
    }
455
456
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
457
        return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to));
458
    }
459
24
    return col_res;
460
33
}
_ZN5doris6detail15convert_to_ipv6ILNS_22IPConvertExceptionModeE1ENS_9ColumnStrIjEES4_EENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKT1_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE
Line
Count
Source
341
45
                          const PaddedPODArray<UInt8>* null_map = nullptr) {
342
45
    const size_t column_size = string_column.size();
343
344
45
    ColumnUInt8::MutablePtr col_null_map_to;
345
45
    ColumnUInt8::Container* vec_null_map_to = nullptr;
346
347
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
348
        col_null_map_to = ColumnUInt8::create(column_size, false);
349
        vec_null_map_to = &col_null_map_to->get_data();
350
    }
351
352
45
    auto column_create = [](size_t column_size) -> typename ToColumn::MutablePtr {
353
45
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
354
45
            auto column_string = ColumnString::create();
355
45
            column_string->get_chars().reserve(column_size * IPV6_BINARY_LENGTH);
356
45
            column_string->get_offsets().reserve(column_size);
357
45
            return column_string;
358
45
        } else {
359
45
            return ColumnIPv6::create();
360
45
        }
361
45
    };
362
363
45
    auto get_vector = [](auto& col_res, size_t col_size) -> decltype(auto) {
364
45
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
365
45
            auto& vec_res = col_res->get_chars();
366
45
            vec_res.resize(col_size * IPV6_BINARY_LENGTH);
367
45
            return (vec_res);
368
45
        } else {
369
45
            auto& vec_res = col_res->get_data();
370
45
            vec_res.resize(col_size);
371
45
            return (vec_res);
372
45
        }
373
45
    };
374
375
45
    auto col_res = column_create(column_size);
376
45
    auto& vec_res = get_vector(col_res, column_size);
377
378
45
    int offset_inc = 1;
379
45
    ColumnString* column_string = nullptr;
380
45
    if constexpr (std::is_same_v<ToColumn, ColumnString>) {
381
45
        offset_inc = IPV6_BINARY_LENGTH;
382
45
        column_string = col_res.get();
383
45
    }
384
385
855
    for (size_t out_offset = 0, i = 0; i < column_size; out_offset += offset_inc, ++i) {
386
810
        const auto src = string_column.get_data_at(i);
387
810
        const char* src_value = src.begin();
388
810
        const char* src_end = src.end();
389
810
        auto* res_value = reinterpret_cast<unsigned char*>(&vec_res[out_offset]);
390
391
810
        if (null_map && (*null_map)[i]) {
392
24
            if (exception_mode == IPConvertExceptionMode::Throw) {
393
0
                throw Exception(
394
0
                        ErrorCode::INVALID_ARGUMENT,
395
0
                        "Null Input, you may consider convert it to a valid default IPv6 value "
396
0
                        "like '::' first");
397
24
            } else if (exception_mode == IPConvertExceptionMode::Default) {
398
24
                std::fill_n(&vec_res[out_offset], offset_inc, 0);
399
24
            } else {
400
0
                std::fill_n(&vec_res[out_offset], offset_inc, 0);
401
0
                (*vec_null_map_to)[i] = true;
402
0
            }
403
24
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
404
24
                DCHECK(column_string != nullptr);
405
24
                column_string->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
406
24
            }
407
24
            continue;
408
24
        }
409
410
786
        bool parse_result = false;
411
786
        Int64 dummy_result = 0;
412
413
        /// For both cases below: In case of failure, the function parseIPv6 fills vec_res with zero bytes.
414
415
        /// If the source IP address is parsable as an IPv4 address, then transform it into a valid IPv6 address.
416
        /// Keeping it simple by just prefixing `::ffff:` to the IPv4 address to represent it as a valid IPv6 address.
417
786
        size_t string_length = src.size;
418
786
        if (string_length != 0) {
419
786
            if (try_parse_ipv4(src_value, src_end, dummy_result)) {
420
2
                map_ipv4_to_ipv6(static_cast<IPv4>(dummy_result), res_value);
421
2
                parse_result = true;
422
784
            } else {
423
784
                parse_result = parse_ipv6_whole(src_value, src_end, res_value);
424
784
            }
425
786
        }
426
427
786
        if (parse_result && string_length != 0) {
428
579
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
429
                // handling 16 bytes ipv6 string in the big-endian byte order
430
                // is aimed at conforming to human reading habits
431
579
                std::reverse(res_value, res_value + IPV6_BINARY_LENGTH);
432
579
            }
433
579
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
434
579
                auto* column_string_res = static_cast<ColumnString*>(col_res.get());
435
579
                std::copy(res_value, res_value + IPV6_BINARY_LENGTH,
436
579
                          column_string_res->get_chars().begin() + i * IPV6_BINARY_LENGTH);
437
579
                column_string_res->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
438
            } else {
439
                col_res->insert_data(reinterpret_cast<const char*>(res_value), IPV6_BINARY_LENGTH);
440
            }
441
579
        } else {
442
207
            if (exception_mode == IPConvertExceptionMode::Throw) {
443
0
                throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value");
444
0
            }
445
207
            std::fill_n(&vec_res[out_offset], offset_inc, 0);
446
207
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
447
207
                auto* column_string_res = static_cast<ColumnString*>(col_res.get());
448
207
                column_string_res->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
449
207
            }
450
            if constexpr (exception_mode == IPConvertExceptionMode::Null) {
451
                (*vec_null_map_to)[i] = true;
452
            }
453
207
        }
454
786
    }
455
456
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
457
        return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to));
458
    }
459
45
    return col_res;
460
45
}
_ZN5doris6detail15convert_to_ipv6ILNS_22IPConvertExceptionModeE2ENS_9ColumnStrIjEES4_EENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKT1_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE
Line
Count
Source
341
118
                          const PaddedPODArray<UInt8>* null_map = nullptr) {
342
118
    const size_t column_size = string_column.size();
343
344
118
    ColumnUInt8::MutablePtr col_null_map_to;
345
118
    ColumnUInt8::Container* vec_null_map_to = nullptr;
346
347
118
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
348
118
        col_null_map_to = ColumnUInt8::create(column_size, false);
349
118
        vec_null_map_to = &col_null_map_to->get_data();
350
118
    }
351
352
118
    auto column_create = [](size_t column_size) -> typename ToColumn::MutablePtr {
353
118
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
354
118
            auto column_string = ColumnString::create();
355
118
            column_string->get_chars().reserve(column_size * IPV6_BINARY_LENGTH);
356
118
            column_string->get_offsets().reserve(column_size);
357
118
            return column_string;
358
118
        } else {
359
118
            return ColumnIPv6::create();
360
118
        }
361
118
    };
362
363
118
    auto get_vector = [](auto& col_res, size_t col_size) -> decltype(auto) {
364
118
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
365
118
            auto& vec_res = col_res->get_chars();
366
118
            vec_res.resize(col_size * IPV6_BINARY_LENGTH);
367
118
            return (vec_res);
368
118
        } else {
369
118
            auto& vec_res = col_res->get_data();
370
118
            vec_res.resize(col_size);
371
118
            return (vec_res);
372
118
        }
373
118
    };
374
375
118
    auto col_res = column_create(column_size);
376
118
    auto& vec_res = get_vector(col_res, column_size);
377
378
118
    int offset_inc = 1;
379
118
    ColumnString* column_string = nullptr;
380
118
    if constexpr (std::is_same_v<ToColumn, ColumnString>) {
381
118
        offset_inc = IPV6_BINARY_LENGTH;
382
118
        column_string = col_res.get();
383
118
    }
384
385
1.10k
    for (size_t out_offset = 0, i = 0; i < column_size; out_offset += offset_inc, ++i) {
386
985
        const auto src = string_column.get_data_at(i);
387
985
        const char* src_value = src.begin();
388
985
        const char* src_end = src.end();
389
985
        auto* res_value = reinterpret_cast<unsigned char*>(&vec_res[out_offset]);
390
391
985
        if (null_map && (*null_map)[i]) {
392
18
            if (exception_mode == IPConvertExceptionMode::Throw) {
393
0
                throw Exception(
394
0
                        ErrorCode::INVALID_ARGUMENT,
395
0
                        "Null Input, you may consider convert it to a valid default IPv6 value "
396
0
                        "like '::' first");
397
18
            } else if (exception_mode == IPConvertExceptionMode::Default) {
398
0
                std::fill_n(&vec_res[out_offset], offset_inc, 0);
399
18
            } else {
400
18
                std::fill_n(&vec_res[out_offset], offset_inc, 0);
401
18
                (*vec_null_map_to)[i] = true;
402
18
            }
403
18
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
404
18
                DCHECK(column_string != nullptr);
405
18
                column_string->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
406
18
            }
407
18
            continue;
408
18
        }
409
410
967
        bool parse_result = false;
411
967
        Int64 dummy_result = 0;
412
413
        /// For both cases below: In case of failure, the function parseIPv6 fills vec_res with zero bytes.
414
415
        /// If the source IP address is parsable as an IPv4 address, then transform it into a valid IPv6 address.
416
        /// Keeping it simple by just prefixing `::ffff:` to the IPv4 address to represent it as a valid IPv6 address.
417
967
        size_t string_length = src.size;
418
967
        if (string_length != 0) {
419
959
            if (try_parse_ipv4(src_value, src_end, dummy_result)) {
420
50
                map_ipv4_to_ipv6(static_cast<IPv4>(dummy_result), res_value);
421
50
                parse_result = true;
422
909
            } else {
423
909
                parse_result = parse_ipv6_whole(src_value, src_end, res_value);
424
909
            }
425
959
        }
426
427
967
        if (parse_result && string_length != 0) {
428
338
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
429
                // handling 16 bytes ipv6 string in the big-endian byte order
430
                // is aimed at conforming to human reading habits
431
338
                std::reverse(res_value, res_value + IPV6_BINARY_LENGTH);
432
338
            }
433
338
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
434
338
                auto* column_string_res = static_cast<ColumnString*>(col_res.get());
435
338
                std::copy(res_value, res_value + IPV6_BINARY_LENGTH,
436
338
                          column_string_res->get_chars().begin() + i * IPV6_BINARY_LENGTH);
437
338
                column_string_res->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
438
            } else {
439
                col_res->insert_data(reinterpret_cast<const char*>(res_value), IPV6_BINARY_LENGTH);
440
            }
441
629
        } else {
442
629
            if (exception_mode == IPConvertExceptionMode::Throw) {
443
0
                throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value");
444
0
            }
445
629
            std::fill_n(&vec_res[out_offset], offset_inc, 0);
446
629
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
447
629
                auto* column_string_res = static_cast<ColumnString*>(col_res.get());
448
629
                column_string_res->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
449
629
            }
450
629
            if constexpr (exception_mode == IPConvertExceptionMode::Null) {
451
629
                (*vec_null_map_to)[i] = true;
452
629
            }
453
629
        }
454
967
    }
455
456
118
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
457
118
        return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to));
458
118
    }
459
0
    return col_res;
460
118
}
_ZN5doris6detail15convert_to_ipv6ILNS_22IPConvertExceptionModeE0ENS_12ColumnVectorILNS_13PrimitiveTypeE37EEENS_9ColumnStrIjEEEENS_3COWINS_7IColumnEE13immutable_ptrIS9_EERKT1_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE
Line
Count
Source
341
13
                          const PaddedPODArray<UInt8>* null_map = nullptr) {
342
13
    const size_t column_size = string_column.size();
343
344
13
    ColumnUInt8::MutablePtr col_null_map_to;
345
13
    ColumnUInt8::Container* vec_null_map_to = nullptr;
346
347
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
348
        col_null_map_to = ColumnUInt8::create(column_size, false);
349
        vec_null_map_to = &col_null_map_to->get_data();
350
    }
351
352
13
    auto column_create = [](size_t column_size) -> typename ToColumn::MutablePtr {
353
13
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
354
13
            auto column_string = ColumnString::create();
355
13
            column_string->get_chars().reserve(column_size * IPV6_BINARY_LENGTH);
356
13
            column_string->get_offsets().reserve(column_size);
357
13
            return column_string;
358
13
        } else {
359
13
            return ColumnIPv6::create();
360
13
        }
361
13
    };
362
363
13
    auto get_vector = [](auto& col_res, size_t col_size) -> decltype(auto) {
364
13
        if constexpr (std::is_same_v<ToColumn, ColumnString>) {
365
13
            auto& vec_res = col_res->get_chars();
366
13
            vec_res.resize(col_size * IPV6_BINARY_LENGTH);
367
13
            return (vec_res);
368
13
        } else {
369
13
            auto& vec_res = col_res->get_data();
370
13
            vec_res.resize(col_size);
371
13
            return (vec_res);
372
13
        }
373
13
    };
374
375
13
    auto col_res = column_create(column_size);
376
13
    auto& vec_res = get_vector(col_res, column_size);
377
378
13
    int offset_inc = 1;
379
13
    ColumnString* column_string = nullptr;
380
    if constexpr (std::is_same_v<ToColumn, ColumnString>) {
381
        offset_inc = IPV6_BINARY_LENGTH;
382
        column_string = col_res.get();
383
    }
384
385
27
    for (size_t out_offset = 0, i = 0; i < column_size; out_offset += offset_inc, ++i) {
386
18
        const auto src = string_column.get_data_at(i);
387
18
        const char* src_value = src.begin();
388
18
        const char* src_end = src.end();
389
18
        auto* res_value = reinterpret_cast<unsigned char*>(&vec_res[out_offset]);
390
391
18
        if (null_map && (*null_map)[i]) {
392
0
            if (exception_mode == IPConvertExceptionMode::Throw) {
393
0
                throw Exception(
394
0
                        ErrorCode::INVALID_ARGUMENT,
395
0
                        "Null Input, you may consider convert it to a valid default IPv6 value "
396
0
                        "like '::' first");
397
0
            } else if (exception_mode == IPConvertExceptionMode::Default) {
398
0
                std::fill_n(&vec_res[out_offset], offset_inc, 0);
399
0
            } else {
400
0
                std::fill_n(&vec_res[out_offset], offset_inc, 0);
401
0
                (*vec_null_map_to)[i] = true;
402
0
            }
403
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
404
                DCHECK(column_string != nullptr);
405
                column_string->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
406
            }
407
0
            continue;
408
0
        }
409
410
18
        bool parse_result = false;
411
18
        Int64 dummy_result = 0;
412
413
        /// For both cases below: In case of failure, the function parseIPv6 fills vec_res with zero bytes.
414
415
        /// If the source IP address is parsable as an IPv4 address, then transform it into a valid IPv6 address.
416
        /// Keeping it simple by just prefixing `::ffff:` to the IPv4 address to represent it as a valid IPv6 address.
417
18
        size_t string_length = src.size;
418
18
        if (string_length != 0) {
419
16
            if (try_parse_ipv4(src_value, src_end, dummy_result)) {
420
0
                map_ipv4_to_ipv6(static_cast<IPv4>(dummy_result), res_value);
421
0
                parse_result = true;
422
16
            } else {
423
16
                parse_result = parse_ipv6_whole(src_value, src_end, res_value);
424
16
            }
425
16
        }
426
427
18
        if (parse_result && string_length != 0) {
428
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
429
                // handling 16 bytes ipv6 string in the big-endian byte order
430
                // is aimed at conforming to human reading habits
431
                std::reverse(res_value, res_value + IPV6_BINARY_LENGTH);
432
            }
433
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
434
                auto* column_string_res = static_cast<ColumnString*>(col_res.get());
435
                std::copy(res_value, res_value + IPV6_BINARY_LENGTH,
436
                          column_string_res->get_chars().begin() + i * IPV6_BINARY_LENGTH);
437
                column_string_res->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
438
14
            } else {
439
14
                col_res->insert_data(reinterpret_cast<const char*>(res_value), IPV6_BINARY_LENGTH);
440
14
            }
441
14
        } else {
442
4
            if (exception_mode == IPConvertExceptionMode::Throw) {
443
4
                throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value");
444
4
            }
445
0
            std::fill_n(&vec_res[out_offset], offset_inc, 0);
446
            if constexpr (std::is_same_v<ToColumn, ColumnString>) {
447
                auto* column_string_res = static_cast<ColumnString*>(col_res.get());
448
                column_string_res->get_offsets().push_back((i + 1) * IPV6_BINARY_LENGTH);
449
            }
450
            if constexpr (exception_mode == IPConvertExceptionMode::Null) {
451
                (*vec_null_map_to)[i] = true;
452
            }
453
0
        }
454
18
    }
455
456
    if constexpr (exception_mode == IPConvertExceptionMode::Null) {
457
        return ColumnNullable::create(std::move(col_res), std::move(col_null_map_to));
458
    }
459
9
    return col_res;
460
13
}
461
} // namespace detail
462
463
template <IPConvertExceptionMode exception_mode, typename ToColumn = ColumnIPv6>
464
210
ColumnPtr convert_to_ipv6(ColumnPtr column, const PaddedPODArray<UInt8>* null_map = nullptr) {
465
210
    const auto* column_input_string = assert_cast<const ColumnString*>(column.get());
466
210
    auto result = detail::convert_to_ipv6<exception_mode, ToColumn>(*column_input_string, null_map);
467
210
    return result;
468
210
}
_ZN5doris15convert_to_ipv6ILNS_22IPConvertExceptionModeE0ENS_9ColumnStrIjEEEENS_3COWINS_7IColumnEE13immutable_ptrIS5_EES8_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE
Line
Count
Source
464
34
ColumnPtr convert_to_ipv6(ColumnPtr column, const PaddedPODArray<UInt8>* null_map = nullptr) {
465
34
    const auto* column_input_string = assert_cast<const ColumnString*>(column.get());
466
34
    auto result = detail::convert_to_ipv6<exception_mode, ToColumn>(*column_input_string, null_map);
467
34
    return result;
468
34
}
_ZN5doris15convert_to_ipv6ILNS_22IPConvertExceptionModeE1ENS_9ColumnStrIjEEEENS_3COWINS_7IColumnEE13immutable_ptrIS5_EES8_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE
Line
Count
Source
464
45
ColumnPtr convert_to_ipv6(ColumnPtr column, const PaddedPODArray<UInt8>* null_map = nullptr) {
465
45
    const auto* column_input_string = assert_cast<const ColumnString*>(column.get());
466
45
    auto result = detail::convert_to_ipv6<exception_mode, ToColumn>(*column_input_string, null_map);
467
45
    return result;
468
45
}
_ZN5doris15convert_to_ipv6ILNS_22IPConvertExceptionModeE2ENS_9ColumnStrIjEEEENS_3COWINS_7IColumnEE13immutable_ptrIS5_EES8_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE
Line
Count
Source
464
118
ColumnPtr convert_to_ipv6(ColumnPtr column, const PaddedPODArray<UInt8>* null_map = nullptr) {
465
118
    const auto* column_input_string = assert_cast<const ColumnString*>(column.get());
466
118
    auto result = detail::convert_to_ipv6<exception_mode, ToColumn>(*column_input_string, null_map);
467
118
    return result;
468
118
}
_ZN5doris15convert_to_ipv6ILNS_22IPConvertExceptionModeE0ENS_12ColumnVectorILNS_13PrimitiveTypeE37EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EES9_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE
Line
Count
Source
464
13
ColumnPtr convert_to_ipv6(ColumnPtr column, const PaddedPODArray<UInt8>* null_map = nullptr) {
465
13
    const auto* column_input_string = assert_cast<const ColumnString*>(column.get());
466
13
    auto result = detail::convert_to_ipv6<exception_mode, ToColumn>(*column_input_string, null_map);
467
13
    return result;
468
13
}
469
470
template <IPConvertExceptionMode exception_mode>
471
class FunctionIPv6StringToNum : public IFunction {
472
public:
473
    static constexpr auto name = exception_mode == IPConvertExceptionMode::Throw
474
                                         ? "ipv6_string_to_num"
475
                                         : (exception_mode == IPConvertExceptionMode::Default
476
                                                    ? "ipv6_string_to_num_or_default"
477
                                                    : "ipv6_string_to_num_or_null");
478
479
148
    static FunctionPtr create() {
480
148
        return std::make_shared<FunctionIPv6StringToNum<exception_mode>>();
481
148
    }
_ZN5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE0EE6createEv
Line
Count
Source
479
34
    static FunctionPtr create() {
480
34
        return std::make_shared<FunctionIPv6StringToNum<exception_mode>>();
481
34
    }
_ZN5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE1EE6createEv
Line
Count
Source
479
28
    static FunctionPtr create() {
480
28
        return std::make_shared<FunctionIPv6StringToNum<exception_mode>>();
481
28
    }
_ZN5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE2EE6createEv
Line
Count
Source
479
86
    static FunctionPtr create() {
480
86
        return std::make_shared<FunctionIPv6StringToNum<exception_mode>>();
481
86
    }
482
483
3
    String get_name() const override { return name; }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE0EE8get_nameB5cxx11Ev
Line
Count
Source
483
1
    String get_name() const override { return name; }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE1EE8get_nameB5cxx11Ev
Line
Count
Source
483
1
    String get_name() const override { return name; }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE2EE8get_nameB5cxx11Ev
Line
Count
Source
483
1
    String get_name() const override { return name; }
484
485
127
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE0EE23get_number_of_argumentsEv
Line
Count
Source
485
27
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE1EE23get_number_of_argumentsEv
Line
Count
Source
485
21
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE2EE23get_number_of_argumentsEv
Line
Count
Source
485
79
    size_t get_number_of_arguments() const override { return 1; }
486
487
324
    bool use_default_implementation_for_nulls() const override { return false; }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE0EE36use_default_implementation_for_nullsEv
Line
Count
Source
487
61
    bool use_default_implementation_for_nulls() const override { return false; }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE1EE36use_default_implementation_for_nullsEv
Line
Count
Source
487
66
    bool use_default_implementation_for_nulls() const override { return false; }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE2EE36use_default_implementation_for_nullsEv
Line
Count
Source
487
197
    bool use_default_implementation_for_nulls() const override { return false; }
488
489
127
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
490
127
        auto result_type = std::make_shared<DataTypeString>();
491
492
127
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
493
79
            return make_nullable(result_type);
494
79
        }
495
496
0
        return result_type;
497
127
    }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE0EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
489
27
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
490
27
        auto result_type = std::make_shared<DataTypeString>();
491
492
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
493
            return make_nullable(result_type);
494
        }
495
496
27
        return result_type;
497
27
    }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE1EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
489
21
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
490
21
        auto result_type = std::make_shared<DataTypeString>();
491
492
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
493
            return make_nullable(result_type);
494
        }
495
496
21
        return result_type;
497
21
    }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE2EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
489
79
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
490
79
        auto result_type = std::make_shared<DataTypeString>();
491
492
79
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
493
79
            return make_nullable(result_type);
494
79
        }
495
496
0
        return result_type;
497
79
    }
498
499
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
500
196
                        uint32_t result, size_t input_rows_count) const override {
501
196
        ColumnPtr column =
502
196
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
503
196
        ColumnPtr null_map_column;
504
196
        const NullMap* null_map = nullptr;
505
506
196
        if (const auto* column_nullable = check_and_get_column<ColumnNullable>(column.get())) {
507
95
            column = column_nullable->get_nested_column_ptr();
508
95
            null_map_column = column_nullable->get_null_map_column_ptr();
509
95
            null_map = &column_nullable->get_null_map_data();
510
95
        }
511
512
196
        auto col_res = convert_to_ipv6<exception_mode, ColumnString>(column, null_map);
513
514
196
        if (null_map && exception_mode == IPConvertExceptionMode::Null) {
515
60
            block.replace_by_position(
516
60
                    result, ColumnNullable::create(std::move(col_res), std::move(null_map_column)));
517
136
        } else {
518
136
            block.replace_by_position(result, std::move(col_res));
519
136
        }
520
196
        return Status::OK();
521
196
    }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE0EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
500
33
                        uint32_t result, size_t input_rows_count) const override {
501
33
        ColumnPtr column =
502
33
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
503
33
        ColumnPtr null_map_column;
504
33
        const NullMap* null_map = nullptr;
505
506
33
        if (const auto* column_nullable = check_and_get_column<ColumnNullable>(column.get())) {
507
12
            column = column_nullable->get_nested_column_ptr();
508
12
            null_map_column = column_nullable->get_null_map_column_ptr();
509
12
            null_map = &column_nullable->get_null_map_data();
510
12
        }
511
512
33
        auto col_res = convert_to_ipv6<exception_mode, ColumnString>(column, null_map);
513
514
33
        if (null_map && exception_mode == IPConvertExceptionMode::Null) {
515
0
            block.replace_by_position(
516
0
                    result, ColumnNullable::create(std::move(col_res), std::move(null_map_column)));
517
33
        } else {
518
33
            block.replace_by_position(result, std::move(col_res));
519
33
        }
520
33
        return Status::OK();
521
33
    }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE1EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
500
45
                        uint32_t result, size_t input_rows_count) const override {
501
45
        ColumnPtr column =
502
45
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
503
45
        ColumnPtr null_map_column;
504
45
        const NullMap* null_map = nullptr;
505
506
45
        if (const auto* column_nullable = check_and_get_column<ColumnNullable>(column.get())) {
507
23
            column = column_nullable->get_nested_column_ptr();
508
23
            null_map_column = column_nullable->get_null_map_column_ptr();
509
23
            null_map = &column_nullable->get_null_map_data();
510
23
        }
511
512
45
        auto col_res = convert_to_ipv6<exception_mode, ColumnString>(column, null_map);
513
514
45
        if (null_map && exception_mode == IPConvertExceptionMode::Null) {
515
0
            block.replace_by_position(
516
0
                    result, ColumnNullable::create(std::move(col_res), std::move(null_map_column)));
517
45
        } else {
518
45
            block.replace_by_position(result, std::move(col_res));
519
45
        }
520
45
        return Status::OK();
521
45
    }
_ZNK5doris23FunctionIPv6StringToNumILNS_22IPConvertExceptionModeE2EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
500
118
                        uint32_t result, size_t input_rows_count) const override {
501
118
        ColumnPtr column =
502
118
                block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
503
118
        ColumnPtr null_map_column;
504
118
        const NullMap* null_map = nullptr;
505
506
118
        if (const auto* column_nullable = check_and_get_column<ColumnNullable>(column.get())) {
507
60
            column = column_nullable->get_nested_column_ptr();
508
60
            null_map_column = column_nullable->get_null_map_column_ptr();
509
60
            null_map = &column_nullable->get_null_map_data();
510
60
        }
511
512
118
        auto col_res = convert_to_ipv6<exception_mode, ColumnString>(column, null_map);
513
514
118
        if (null_map && exception_mode == IPConvertExceptionMode::Null) {
515
60
            block.replace_by_position(
516
60
                    result, ColumnNullable::create(std::move(col_res), std::move(null_map_column)));
517
60
        } else {
518
58
            block.replace_by_position(result, std::move(col_res));
519
58
        }
520
118
        return Status::OK();
521
118
    }
522
};
523
524
template <typename Type>
525
class FunctionIsIPString : public IFunction {
526
    static_assert(std::is_same_v<Type, IPv4> || std::is_same_v<Type, IPv6>);
527
528
public:
529
    static constexpr auto name = std::is_same_v<Type, IPv4> ? "is_ipv4_string" : "is_ipv6_string";
530
54
    static FunctionPtr create() { return std::make_shared<FunctionIsIPString<Type>>(); }
_ZN5doris18FunctionIsIPStringIjE6createEv
Line
Count
Source
530
26
    static FunctionPtr create() { return std::make_shared<FunctionIsIPString<Type>>(); }
_ZN5doris18FunctionIsIPStringIoE6createEv
Line
Count
Source
530
28
    static FunctionPtr create() { return std::make_shared<FunctionIsIPString<Type>>(); }
531
532
2
    String get_name() const override { return name; }
_ZNK5doris18FunctionIsIPStringIjE8get_nameB5cxx11Ev
Line
Count
Source
532
1
    String get_name() const override { return name; }
_ZNK5doris18FunctionIsIPStringIoE8get_nameB5cxx11Ev
Line
Count
Source
532
1
    String get_name() const override { return name; }
533
534
40
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris18FunctionIsIPStringIjE23get_number_of_argumentsEv
Line
Count
Source
534
19
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris18FunctionIsIPStringIoE23get_number_of_argumentsEv
Line
Count
Source
534
21
    size_t get_number_of_arguments() const override { return 1; }
535
536
40
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
537
40
        return std::make_shared<DataTypeUInt8>();
538
40
    }
_ZNK5doris18FunctionIsIPStringIjE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS6_EE
Line
Count
Source
536
19
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
537
19
        return std::make_shared<DataTypeUInt8>();
538
19
    }
_ZNK5doris18FunctionIsIPStringIoE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS6_EE
Line
Count
Source
536
21
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
537
21
        return std::make_shared<DataTypeUInt8>();
538
21
    }
539
540
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
541
95
                        uint32_t result, size_t input_rows_count) const override {
542
95
        const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]);
543
95
        const ColumnPtr& addr_column = addr_column_with_type_and_name.column;
544
95
        const auto* str_addr_column = assert_cast<const ColumnString*>(addr_column.get());
545
95
        auto col_res = ColumnUInt8::create(input_rows_count, 0);
546
95
        auto& col_res_data = col_res->get_data();
547
548
1.72k
        for (size_t i = 0; i < input_rows_count; ++i) {
549
1.63k
            if constexpr (std::is_same_v<Type, IPv4>) {
550
816
                StringRef ipv4_str = str_addr_column->get_data_at(i);
551
816
                if (IPv4Value::is_valid_string(ipv4_str.data, ipv4_str.size)) {
552
206
                    col_res_data[i] = 1;
553
206
                }
554
818
            } else {
555
818
                StringRef ipv6_str = str_addr_column->get_data_at(i);
556
818
                if (IPv6Value::is_valid_string(ipv6_str.data, ipv6_str.size)) {
557
210
                    col_res_data[i] = 1;
558
210
                }
559
818
            }
560
1.63k
        }
561
562
95
        block.replace_by_position(result, std::move(col_res));
563
95
        return Status::OK();
564
95
    }
_ZNK5doris18FunctionIsIPStringIjE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
541
46
                        uint32_t result, size_t input_rows_count) const override {
542
46
        const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]);
543
46
        const ColumnPtr& addr_column = addr_column_with_type_and_name.column;
544
46
        const auto* str_addr_column = assert_cast<const ColumnString*>(addr_column.get());
545
46
        auto col_res = ColumnUInt8::create(input_rows_count, 0);
546
46
        auto& col_res_data = col_res->get_data();
547
548
862
        for (size_t i = 0; i < input_rows_count; ++i) {
549
816
            if constexpr (std::is_same_v<Type, IPv4>) {
550
816
                StringRef ipv4_str = str_addr_column->get_data_at(i);
551
816
                if (IPv4Value::is_valid_string(ipv4_str.data, ipv4_str.size)) {
552
206
                    col_res_data[i] = 1;
553
206
                }
554
            } else {
555
                StringRef ipv6_str = str_addr_column->get_data_at(i);
556
                if (IPv6Value::is_valid_string(ipv6_str.data, ipv6_str.size)) {
557
                    col_res_data[i] = 1;
558
                }
559
            }
560
816
        }
561
562
46
        block.replace_by_position(result, std::move(col_res));
563
46
        return Status::OK();
564
46
    }
_ZNK5doris18FunctionIsIPStringIoE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
541
49
                        uint32_t result, size_t input_rows_count) const override {
542
49
        const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]);
543
49
        const ColumnPtr& addr_column = addr_column_with_type_and_name.column;
544
49
        const auto* str_addr_column = assert_cast<const ColumnString*>(addr_column.get());
545
49
        auto col_res = ColumnUInt8::create(input_rows_count, 0);
546
49
        auto& col_res_data = col_res->get_data();
547
548
867
        for (size_t i = 0; i < input_rows_count; ++i) {
549
            if constexpr (std::is_same_v<Type, IPv4>) {
550
                StringRef ipv4_str = str_addr_column->get_data_at(i);
551
                if (IPv4Value::is_valid_string(ipv4_str.data, ipv4_str.size)) {
552
                    col_res_data[i] = 1;
553
                }
554
818
            } else {
555
818
                StringRef ipv6_str = str_addr_column->get_data_at(i);
556
818
                if (IPv6Value::is_valid_string(ipv6_str.data, ipv6_str.size)) {
557
210
                    col_res_data[i] = 1;
558
210
                }
559
818
            }
560
818
        }
561
562
49
        block.replace_by_position(result, std::move(col_res));
563
49
        return Status::OK();
564
49
    }
565
};
566
567
class FunctionIsIPAddressInRange : public IFunction {
568
public:
569
    static constexpr auto name = "is_ip_address_in_range";
570
73
    static FunctionPtr create() { return std::make_shared<FunctionIsIPAddressInRange>(); }
571
572
1
    String get_name() const override { return name; }
573
574
66
    size_t get_number_of_arguments() const override { return 2; }
575
576
66
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
577
66
        return std::make_shared<DataTypeUInt8>();
578
66
    }
579
580
    template <PrimitiveType PT, typename ColumnType>
581
    void execute_impl_with_ip(size_t input_rows_count, bool addr_const, bool cidr_const,
582
                              const ColumnString* str_cidr_column, const ColumnPtr addr_column,
583
17
                              ColumnUInt8* col_res) const {
584
17
        auto& col_res_data = col_res->get_data();
585
17
        const auto& ip_data = assert_cast<const ColumnType*>(addr_column.get())->get_data();
586
418
        for (size_t i = 0; i < input_rows_count; ++i) {
587
401
            auto addr_idx = index_check_const(i, addr_const);
588
401
            auto cidr_idx = index_check_const(i, cidr_const);
589
401
            auto cidr_data = str_cidr_column->get_data_at(cidr_idx);
590
            // cidr_data maybe NULL, But the input column is nested column, so check here avoid throw exception
591
401
            if (cidr_data.data == nullptr || cidr_data.size == 0) {
592
0
                col_res_data[i] = 0;
593
0
                continue;
594
0
            }
595
401
            const auto cidr = parse_ip_with_cidr(cidr_data.to_string_view());
596
401
            if constexpr (PT == PrimitiveType::TYPE_IPV4) {
597
202
                if (cidr._address.is_v4()) {
598
3
                    col_res_data[i] = match_ipv4_subnet(ip_data[addr_idx], cidr._address.as_v4(),
599
3
                                                        cidr._prefix)
600
3
                                              ? 1
601
3
                                              : 0;
602
199
                } else {
603
199
                    col_res_data[i] = 0;
604
199
                }
605
202
            } else if constexpr (PT == PrimitiveType::TYPE_IPV6) {
606
199
                if (cidr._address.is_v6()) {
607
199
                    col_res_data[i] = match_ipv6_subnet((uint8_t*)(&ip_data[addr_idx]),
608
199
                                                        cidr._address.as_v6(), cidr._prefix)
609
199
                                              ? 1
610
199
                                              : 0;
611
199
                } else {
612
0
                    col_res_data[i] = 0;
613
0
                }
614
199
            }
615
401
        }
616
17
    }
_ZNK5doris26FunctionIsIPAddressInRange20execute_impl_with_ipILNS_13PrimitiveTypeE36ENS_12ColumnVectorILS2_36EEEEEvmbbPKNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISA_EEPNS3_ILS2_2EEE
Line
Count
Source
583
9
                              ColumnUInt8* col_res) const {
584
9
        auto& col_res_data = col_res->get_data();
585
9
        const auto& ip_data = assert_cast<const ColumnType*>(addr_column.get())->get_data();
586
211
        for (size_t i = 0; i < input_rows_count; ++i) {
587
202
            auto addr_idx = index_check_const(i, addr_const);
588
202
            auto cidr_idx = index_check_const(i, cidr_const);
589
202
            auto cidr_data = str_cidr_column->get_data_at(cidr_idx);
590
            // cidr_data maybe NULL, But the input column is nested column, so check here avoid throw exception
591
202
            if (cidr_data.data == nullptr || cidr_data.size == 0) {
592
0
                col_res_data[i] = 0;
593
0
                continue;
594
0
            }
595
202
            const auto cidr = parse_ip_with_cidr(cidr_data.to_string_view());
596
202
            if constexpr (PT == PrimitiveType::TYPE_IPV4) {
597
202
                if (cidr._address.is_v4()) {
598
3
                    col_res_data[i] = match_ipv4_subnet(ip_data[addr_idx], cidr._address.as_v4(),
599
3
                                                        cidr._prefix)
600
3
                                              ? 1
601
3
                                              : 0;
602
199
                } else {
603
199
                    col_res_data[i] = 0;
604
199
                }
605
            } else if constexpr (PT == PrimitiveType::TYPE_IPV6) {
606
                if (cidr._address.is_v6()) {
607
                    col_res_data[i] = match_ipv6_subnet((uint8_t*)(&ip_data[addr_idx]),
608
                                                        cidr._address.as_v6(), cidr._prefix)
609
                                              ? 1
610
                                              : 0;
611
                } else {
612
                    col_res_data[i] = 0;
613
                }
614
            }
615
202
        }
616
9
    }
_ZNK5doris26FunctionIsIPAddressInRange20execute_impl_with_ipILNS_13PrimitiveTypeE37ENS_12ColumnVectorILS2_37EEEEEvmbbPKNS_9ColumnStrIjEENS_3COWINS_7IColumnEE13immutable_ptrISA_EEPNS3_ILS2_2EEE
Line
Count
Source
583
8
                              ColumnUInt8* col_res) const {
584
8
        auto& col_res_data = col_res->get_data();
585
8
        const auto& ip_data = assert_cast<const ColumnType*>(addr_column.get())->get_data();
586
207
        for (size_t i = 0; i < input_rows_count; ++i) {
587
199
            auto addr_idx = index_check_const(i, addr_const);
588
199
            auto cidr_idx = index_check_const(i, cidr_const);
589
199
            auto cidr_data = str_cidr_column->get_data_at(cidr_idx);
590
            // cidr_data maybe NULL, But the input column is nested column, so check here avoid throw exception
591
199
            if (cidr_data.data == nullptr || cidr_data.size == 0) {
592
0
                col_res_data[i] = 0;
593
0
                continue;
594
0
            }
595
199
            const auto cidr = parse_ip_with_cidr(cidr_data.to_string_view());
596
            if constexpr (PT == PrimitiveType::TYPE_IPV4) {
597
                if (cidr._address.is_v4()) {
598
                    col_res_data[i] = match_ipv4_subnet(ip_data[addr_idx], cidr._address.as_v4(),
599
                                                        cidr._prefix)
600
                                              ? 1
601
                                              : 0;
602
                } else {
603
                    col_res_data[i] = 0;
604
                }
605
199
            } else if constexpr (PT == PrimitiveType::TYPE_IPV6) {
606
199
                if (cidr._address.is_v6()) {
607
199
                    col_res_data[i] = match_ipv6_subnet((uint8_t*)(&ip_data[addr_idx]),
608
199
                                                        cidr._address.as_v6(), cidr._prefix)
609
199
                                              ? 1
610
199
                                              : 0;
611
199
                } else {
612
0
                    col_res_data[i] = 0;
613
0
                }
614
199
            }
615
199
        }
616
8
    }
617
618
    Status evaluate_inverted_index(
619
            const ColumnsWithTypeAndName& arguments,
620
            const std::vector<IndexFieldNameAndTypePair>& data_type_with_names,
621
            std::vector<segment_v2::IndexIterator*> iterators, uint32_t num_rows,
622
            const InvertedIndexAnalyzerCtx* /*analyzer_ctx*/,
623
2
            segment_v2::InvertedIndexResultBitmap& bitmap_result) const override {
624
2
        DCHECK(arguments.size() == 1);
625
2
        DCHECK(data_type_with_names.size() == 1);
626
2
        DCHECK(iterators.size() == 1);
627
2
        auto* iter = iterators[0];
628
2
        auto data_type_with_name = data_type_with_names[0];
629
2
        if (iter == nullptr) {
630
0
            return Status::OK();
631
0
        }
632
633
2
        if (!segment_v2::IndexReaderHelper::has_bkd_index(iter)) {
634
            // Not support only bkd index
635
0
            return Status::Error<ErrorCode::INVERTED_INDEX_EVALUATE_SKIPPED>(
636
0
                    "Inverted index evaluate skipped, ip range reader can only support by bkd "
637
0
                    "reader");
638
0
        }
639
        // Get the is_ip_address_in_range from the arguments: cidr
640
2
        const auto& cidr_column_with_type_and_name = arguments[0];
641
        // in is_ip_address_in_range param is const Field
642
2
        ColumnPtr arg_column = cidr_column_with_type_and_name.column;
643
2
        DataTypePtr arg_type = cidr_column_with_type_and_name.type;
644
2
        if ((is_column_nullable(*arg_column) && !is_column_const(*remove_nullable(arg_column))) ||
645
2
            (!is_column_nullable(*arg_column) && !is_column_const(*arg_column))) {
646
            // if not we should skip inverted index and evaluate in expression
647
0
            return Status::Error<ErrorCode::INVERTED_INDEX_EVALUATE_SKIPPED>(
648
0
                    "Inverted index evaluate skipped, is_ip_address_in_range only support const "
649
0
                    "value");
650
0
        }
651
        // check param type is string
652
2
        if (!is_string_type(arg_type->get_primitive_type())) {
653
0
            return Status::Error<ErrorCode::INVERTED_INDEX_EVALUATE_SKIPPED>(
654
0
                    "Inverted index evaluate skipped, is_ip_address_in_range only support string "
655
0
                    "type");
656
0
        }
657
        // min && max ip address
658
2
        Field min_ip, max_ip;
659
2
        IPAddressCIDR cidr = parse_ip_with_cidr(arg_column->get_data_at(0));
660
2
        if (data_type_with_name.second->get_primitive_type() == TYPE_IPV4 &&
661
2
            cidr._address.is_v4()) {
662
1
            auto range = apply_cidr_mask(cidr._address.as_v4(), cidr._prefix);
663
1
            min_ip = Field::create_field<TYPE_IPV4>(range.first);
664
1
            max_ip = Field::create_field<TYPE_IPV4>(range.second);
665
1
        } else if (data_type_with_name.second->get_primitive_type() == TYPE_IPV6 &&
666
1
                   cidr._address.is_v6()) {
667
1
            auto cidr_range_ipv6_col = ColumnIPv6::create(2, 0);
668
1
            auto& cidr_range_ipv6_data = cidr_range_ipv6_col->get_data();
669
1
            apply_cidr_mask(reinterpret_cast<const char*>(cidr._address.as_v6()),
670
1
                            reinterpret_cast<char*>(&cidr_range_ipv6_data[0]),
671
1
                            reinterpret_cast<char*>(&cidr_range_ipv6_data[1]), cidr._prefix);
672
1
            min_ip = Field::create_field<TYPE_IPV6>(cidr_range_ipv6_data[0]);
673
1
            max_ip = Field::create_field<TYPE_IPV6>(cidr_range_ipv6_data[1]);
674
1
        } else {
675
            // if here param is invalid for current column to calcute min_ip|max_ip we just return
676
0
            return Status::Error<ErrorCode::INVERTED_INDEX_EVALUATE_SKIPPED>(
677
0
                    "Inverted index evaluate skipped, data type " + arg_type->get_name() +
678
0
                    " can not support this cidr " + arg_column->get_data_at(0).to_string());
679
0
        }
680
        // apply for inverted index
681
2
        std::shared_ptr<roaring::Roaring> null_bitmap = std::make_shared<roaring::Roaring>();
682
2
        bool has_null = DORIS_TRY(iter->has_null());
683
2
        segment_v2::InvertedIndexQueryCacheHandle null_bitmap_cache_handle;
684
685
        // >= min ip
686
2
        segment_v2::InvertedIndexParam min_param;
687
2
        min_param.column_name = data_type_with_name.first;
688
2
        min_param.column_type = data_type_with_name.second;
689
2
        min_param.query_type = segment_v2::InvertedIndexQueryType::GREATER_EQUAL_QUERY;
690
2
        min_param.query_value = min_ip;
691
2
        min_param.num_rows = num_rows;
692
2
        min_param.roaring = std::make_shared<roaring::Roaring>();
693
2
        if (has_null) {
694
            // Fetch the NULL bitmap together with the first range query to reuse its index reader.
695
0
            min_param.null_bitmap_cache_handle = &null_bitmap_cache_handle;
696
0
        }
697
2
        RETURN_IF_ERROR(iter->read_from_index(&min_param));
698
2
        if (has_null) {
699
0
            null_bitmap = null_bitmap_cache_handle.get_bitmap();
700
0
        }
701
702
        // <= max ip
703
2
        segment_v2::InvertedIndexParam max_param;
704
2
        max_param.column_name = data_type_with_name.first;
705
2
        max_param.column_type = data_type_with_name.second;
706
2
        max_param.query_type = segment_v2::InvertedIndexQueryType::LESS_EQUAL_QUERY;
707
2
        max_param.query_value = max_ip;
708
2
        max_param.num_rows = num_rows;
709
2
        max_param.roaring = std::make_shared<roaring::Roaring>();
710
2
        RETURN_IF_ERROR(iter->read_from_index(&max_param));
711
712
2
        auto result_roaring = std::make_shared<roaring::Roaring>();
713
2
        *result_roaring = *min_param.roaring & *max_param.roaring;
714
715
2
        DBUG_EXECUTE_IF("ip.inverted_index_filtered", {
716
2
            auto req_id = DebugPoints::instance()->get_debug_param_or_default<int32_t>(
717
2
                    "ip.inverted_index_filtered", "req_id", 0);
718
2
            LOG(INFO) << "execute inverted index req_id: " << req_id
719
2
                      << " min: " << min_param.roaring->cardinality()
720
2
                      << " max: " << max_param.roaring->cardinality()
721
2
                      << " result: " << result_roaring->cardinality();
722
2
        });
723
2
        segment_v2::InvertedIndexResultBitmap result(result_roaring, null_bitmap);
724
2
        bitmap_result = result;
725
2
        bitmap_result.mask_out_null();
726
2
        return Status::OK();
727
2
    }
728
729
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
730
88
                        uint32_t result, size_t input_rows_count) const override {
731
88
        DBUG_EXECUTE_IF("ip.inverted_index_filtered", {
732
88
            auto req_id = DebugPoints::instance()->get_debug_param_or_default<int32_t>(
733
88
                    "ip.inverted_index_filtered", "req_id", 0);
734
88
            return Status::Error<ErrorCode::INTERNAL_ERROR>(
735
88
                    "{} has already execute inverted index req_id {} , should not execute expr "
736
88
                    "with rows: {}",
737
88
                    get_name(), req_id, input_rows_count);
738
88
        });
739
88
        const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]);
740
88
        const auto& cidr_column_with_type_and_name = block.get_by_position(arguments[1]);
741
88
        const auto& [addr_column, addr_const] =
742
88
                unpack_if_const(addr_column_with_type_and_name.column);
743
88
        const auto& [cidr_column, cidr_const] =
744
88
                unpack_if_const(cidr_column_with_type_and_name.column);
745
746
88
        auto col_res = ColumnUInt8::create(input_rows_count, 0);
747
88
        auto& col_res_data = col_res->get_data();
748
749
88
        if (addr_column_with_type_and_name.type->get_primitive_type() == TYPE_IPV4) {
750
9
            execute_impl_with_ip<PrimitiveType::TYPE_IPV4, ColumnIPv4>(
751
9
                    input_rows_count, addr_const, cidr_const,
752
9
                    assert_cast<const ColumnString*>(cidr_column.get()), addr_column,
753
9
                    col_res.get());
754
79
        } else if (addr_column_with_type_and_name.type->get_primitive_type() == TYPE_IPV6) {
755
8
            execute_impl_with_ip<PrimitiveType::TYPE_IPV6, ColumnIPv6>(
756
8
                    input_rows_count, addr_const, cidr_const,
757
8
                    assert_cast<const ColumnString*>(cidr_column.get()), addr_column,
758
8
                    col_res.get());
759
71
        } else {
760
71
            const auto* str_addr_column = assert_cast<const ColumnString*>(addr_column.get());
761
71
            const auto* str_cidr_column = assert_cast<const ColumnString*>(cidr_column.get());
762
763
234
            for (size_t i = 0; i < input_rows_count; ++i) {
764
163
                auto addr_idx = index_check_const(i, addr_const);
765
163
                auto cidr_idx = index_check_const(i, cidr_const);
766
163
                auto addr_data = str_addr_column->get_data_at(addr_idx);
767
163
                auto cidr_data = str_cidr_column->get_data_at(cidr_idx);
768
                // cidr_data maybe NULL, But the input column is nested column, so check here avoid throw exception
769
163
                if (cidr_data.data == nullptr || cidr_data.size == 0) {
770
1
                    col_res_data[i] = 0;
771
1
                    continue;
772
1
                }
773
162
                const auto addr = IPAddressVariant(addr_data.to_string_view());
774
162
                const auto cidr = parse_ip_with_cidr(cidr_data.to_string_view());
775
162
                col_res_data[i] = is_address_in_range(addr, cidr) ? 1 : 0;
776
162
            }
777
71
        }
778
779
88
        block.replace_by_position(result, std::move(col_res));
780
88
        return Status::OK();
781
88
    }
782
};
783
784
class FunctionIPv4CIDRToRange : public IFunction {
785
public:
786
    static constexpr auto name = "ipv4_cidr_to_range";
787
19
    static FunctionPtr create() { return std::make_shared<FunctionIPv4CIDRToRange>(); }
788
789
1
    String get_name() const override { return name; }
790
791
12
    size_t get_number_of_arguments() const override { return 2; }
792
793
12
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
794
12
        DataTypePtr element = std::make_shared<DataTypeIPv4>();
795
12
        return std::make_shared<DataTypeStruct>(DataTypes {element, element},
796
12
                                                Strings {"min", "max"});
797
12
    }
798
799
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
800
33
                        uint32_t result, size_t input_rows_count) const override {
801
33
        ColumnWithTypeAndName& ip_column = block.get_by_position(arguments[0]);
802
33
        ColumnWithTypeAndName& cidr_column = block.get_by_position(arguments[1]);
803
804
33
        const auto& [ip_column_ptr, ip_col_const] = unpack_if_const(ip_column.column);
805
33
        const auto& [cidr_column_ptr, cidr_col_const] = unpack_if_const(cidr_column.column);
806
807
33
        const auto* col_ip_column = assert_cast<const ColumnIPv4*>(ip_column_ptr.get());
808
33
        const auto* col_cidr_column = assert_cast<const ColumnInt16*>(cidr_column_ptr.get());
809
810
33
        const typename ColumnIPv4::Container& vec_ip_input = col_ip_column->get_data();
811
33
        const ColumnInt16::Container& vec_cidr_input = col_cidr_column->get_data();
812
33
        auto col_lower_range_output = ColumnIPv4::create(input_rows_count, 0);
813
33
        auto col_upper_range_output = ColumnIPv4::create(input_rows_count, 0);
814
815
33
        ColumnIPv4::Container& vec_lower_range_output = col_lower_range_output->get_data();
816
33
        ColumnIPv4::Container& vec_upper_range_output = col_upper_range_output->get_data();
817
818
33
        static constexpr UInt8 max_cidr_mask = IPV4_BINARY_LENGTH * 8;
819
820
33
        if (ip_col_const) {
821
4
            auto ip = vec_ip_input[0];
822
11
            for (size_t i = 0; i < input_rows_count; ++i) {
823
7
                auto cidr = vec_cidr_input[i];
824
7
                if (cidr < 0 || cidr > max_cidr_mask) {
825
0
                    throw Exception(ErrorCode::INVALID_ARGUMENT, "Illegal cidr value '{}'",
826
0
                                    std::to_string(cidr));
827
0
                }
828
7
                auto range = apply_cidr_mask(ip, cast_set<UInt8>(cidr));
829
7
                vec_lower_range_output[i] = range.first;
830
7
                vec_upper_range_output[i] = range.second;
831
7
            }
832
29
        } else if (cidr_col_const) {
833
20
            auto cidr = vec_cidr_input[0];
834
20
            if (cidr < 0 || cidr > max_cidr_mask) {
835
0
                throw Exception(ErrorCode::INVALID_ARGUMENT, "Illegal cidr value '{}'",
836
0
                                std::to_string(cidr));
837
0
            }
838
425
            for (size_t i = 0; i < input_rows_count; ++i) {
839
405
                auto ip = vec_ip_input[i];
840
405
                auto range = apply_cidr_mask(ip, cast_set<UInt8>(cidr));
841
405
                vec_lower_range_output[i] = range.first;
842
405
                vec_upper_range_output[i] = range.second;
843
405
            }
844
20
        } else {
845
21
            for (size_t i = 0; i < input_rows_count; ++i) {
846
12
                auto ip = vec_ip_input[i];
847
12
                auto cidr = vec_cidr_input[i];
848
12
                if (cidr < 0 || cidr > max_cidr_mask) {
849
0
                    throw Exception(ErrorCode::INVALID_ARGUMENT, "Illegal cidr value '{}'",
850
0
                                    std::to_string(cidr));
851
0
                }
852
12
                auto range = apply_cidr_mask(ip, cast_set<UInt8>(cidr));
853
12
                vec_lower_range_output[i] = range.first;
854
12
                vec_upper_range_output[i] = range.second;
855
12
            }
856
9
        }
857
858
33
        block.replace_by_position(
859
33
                result, ColumnStruct::create(Columns {std::move(col_lower_range_output),
860
33
                                                      std::move(col_upper_range_output)}));
861
33
        return Status::OK();
862
33
    }
863
};
864
865
/**
866
 * this function accepts two arguments: an IPv6 address and a CIDR mask
867
 *  IPv6 address can be either ipv6 type or string type as ipv6 string address
868
 *  FE: PropagateNullable is used to handle nullable columns
869
 */
870
class FunctionIPv6CIDRToRange : public IFunction {
871
public:
872
    static constexpr auto name = "ipv6_cidr_to_range";
873
28
    static FunctionPtr create() { return std::make_shared<FunctionIPv6CIDRToRange>(); }
874
875
1
    String get_name() const override { return name; }
876
877
21
    size_t get_number_of_arguments() const override { return 2; }
878
879
21
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
880
21
        DataTypePtr element = std::make_shared<DataTypeIPv6>();
881
21
        return std::make_shared<DataTypeStruct>(DataTypes {element, element},
882
21
                                                Strings {"min", "max"});
883
21
    }
884
885
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
886
42
                        uint32_t result, size_t input_rows_count) const override {
887
42
        const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]);
888
42
        const auto& cidr_column_with_type_and_name = block.get_by_position(arguments[1]);
889
42
        const auto& [addr_column, add_col_const] =
890
42
                unpack_if_const(addr_column_with_type_and_name.column);
891
42
        const auto& [cidr_column, col_const] =
892
42
                unpack_if_const(cidr_column_with_type_and_name.column);
893
894
42
        const auto* cidr_col = assert_cast<const ColumnInt16*>(cidr_column.get());
895
42
        ColumnPtr col_res = nullptr;
896
897
42
        if (addr_column_with_type_and_name.type->get_primitive_type() == TYPE_IPV6) {
898
29
            const auto* ipv6_addr_column = assert_cast<const ColumnIPv6*>(addr_column.get());
899
29
            col_res = execute_impl(*ipv6_addr_column, *cidr_col, input_rows_count, add_col_const,
900
29
                                   col_const);
901
29
        } else if (is_string_type(addr_column_with_type_and_name.type->get_primitive_type())) {
902
13
            ColumnPtr col_ipv6 =
903
13
                    convert_to_ipv6<IPConvertExceptionMode::Throw>(addr_column, nullptr);
904
13
            const auto* ipv6_addr_column = assert_cast<const ColumnIPv6*>(col_ipv6.get());
905
13
            col_res = execute_impl(*ipv6_addr_column, *cidr_col, input_rows_count, add_col_const,
906
13
                                   col_const);
907
13
        } else {
908
0
            return Status::RuntimeError(
909
0
                    "Illegal column {} of argument of function {}, Expected IPv6 or String",
910
0
                    addr_column->get_name(), get_name());
911
0
        }
912
913
42
        block.replace_by_position(result, std::move(col_res));
914
42
        return Status::OK();
915
42
    }
916
917
    static ColumnPtr execute_impl(const ColumnIPv6& from_column, const ColumnInt16& cidr_column,
918
                                  size_t input_rows_count, bool is_addr_const = false,
919
38
                                  bool is_cidr_const = false) {
920
38
        auto col_res_lower_range = ColumnIPv6::create(input_rows_count, 0);
921
38
        auto col_res_upper_range = ColumnIPv6::create(input_rows_count, 0);
922
38
        auto& vec_res_lower_range = col_res_lower_range->get_data();
923
38
        auto& vec_res_upper_range = col_res_upper_range->get_data();
924
925
38
        static constexpr UInt8 max_cidr_mask = IPV6_BINARY_LENGTH * 8;
926
927
38
        if (is_addr_const) {
928
9
            for (size_t i = 0; i < input_rows_count; ++i) {
929
6
                auto cidr = cidr_column.get_int(i);
930
6
                if (cidr < 0 || cidr > max_cidr_mask) {
931
0
                    throw Exception(ErrorCode::INVALID_ARGUMENT, "Illegal cidr value '{}'",
932
0
                                    std::to_string(cidr));
933
0
                }
934
6
                apply_cidr_mask(from_column.get_data_at(0).data,
935
6
                                reinterpret_cast<char*>(&vec_res_lower_range[i]),
936
6
                                reinterpret_cast<char*>(&vec_res_upper_range[i]),
937
6
                                cast_set<UInt8>(cidr));
938
6
            }
939
35
        } else if (is_cidr_const) {
940
20
            auto cidr = cidr_column.get_int(0);
941
20
            if (cidr < 0 || cidr > max_cidr_mask) {
942
0
                throw Exception(ErrorCode::INVALID_ARGUMENT, "Illegal cidr value '{}'",
943
0
                                std::to_string(cidr));
944
0
            }
945
427
            for (size_t i = 0; i < input_rows_count; ++i) {
946
407
                apply_cidr_mask(from_column.get_data_at(i).data,
947
407
                                reinterpret_cast<char*>(&vec_res_lower_range[i]),
948
407
                                reinterpret_cast<char*>(&vec_res_upper_range[i]),
949
407
                                cast_set<UInt8>(cidr));
950
407
            }
951
20
        } else {
952
40
            for (size_t i = 0; i < input_rows_count; ++i) {
953
25
                auto cidr = cidr_column.get_int(i);
954
25
                if (cidr < 0 || cidr > max_cidr_mask) {
955
0
                    throw Exception(ErrorCode::INVALID_ARGUMENT, "Illegal cidr value '{}'",
956
0
                                    std::to_string(cidr));
957
0
                }
958
25
                apply_cidr_mask(from_column.get_data_at(i).data,
959
25
                                reinterpret_cast<char*>(&vec_res_lower_range[i]),
960
25
                                reinterpret_cast<char*>(&vec_res_upper_range[i]),
961
25
                                cast_set<UInt8>(cidr));
962
25
            }
963
15
        }
964
38
        return ColumnStruct::create(
965
38
                Columns {std::move(col_res_lower_range), std::move(col_res_upper_range)});
966
38
    }
967
};
968
969
class FunctionIsIPv4Compat : public IFunction {
970
public:
971
    static constexpr auto name = "is_ipv4_compat";
972
32
    static FunctionPtr create() { return std::make_shared<FunctionIsIPv4Compat>(); }
973
974
1
    String get_name() const override { return name; }
975
976
25
    size_t get_number_of_arguments() const override { return 1; }
977
978
25
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
979
25
        return std::make_shared<DataTypeUInt8>();
980
25
    }
981
982
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
983
25
                        uint32_t result, size_t input_rows_count) const override {
984
25
        const ColumnPtr& column = block.get_by_position(arguments[0]).column;
985
25
        const auto* col_in = assert_cast<const ColumnString*>(column.get());
986
987
25
        size_t col_size = col_in->size();
988
25
        auto col_res = ColumnUInt8::create(col_size, 0);
989
25
        auto& col_res_data = col_res->get_data();
990
991
244
        for (size_t i = 0; i < col_size; ++i) {
992
219
            const auto address = col_in->get_data_at(i);
993
219
            if (is_ipv4_compat(address)) {
994
8
                col_res_data[i] = 1;
995
8
            }
996
219
        }
997
998
25
        block.replace_by_position(result, std::move(col_res));
999
25
        return Status::OK();
1000
25
    }
1001
1002
private:
1003
219
    static bool is_ipv4_compat(const StringRef& address) {
1004
219
        return address.size == IPV6_BINARY_LENGTH && (LittleEndian::Load64(address.data) == 0) &&
1005
219
               (LittleEndian::Load32(address.data + 8) == 0) &&
1006
219
               (LittleEndian::Load32(address.data + 12) != 0);
1007
219
    }
1008
};
1009
1010
class FunctionIsIPv4Mapped : public IFunction {
1011
public:
1012
    static constexpr auto name = "is_ipv4_mapped";
1013
32
    static FunctionPtr create() { return std::make_shared<FunctionIsIPv4Mapped>(); }
1014
1015
1
    String get_name() const override { return name; }
1016
1017
25
    size_t get_number_of_arguments() const override { return 1; }
1018
1019
25
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1020
25
        return std::make_shared<DataTypeUInt8>();
1021
25
    }
1022
1023
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
1024
21
                        uint32_t result, size_t input_rows_count) const override {
1025
21
        const ColumnPtr& column = block.get_by_position(arguments[0]).column;
1026
21
        const auto* col_in = assert_cast<const ColumnString*>(column.get());
1027
1028
21
        size_t col_size = col_in->size();
1029
21
        auto col_res = ColumnUInt8::create(col_size, 0);
1030
21
        auto& col_res_data = col_res->get_data();
1031
1032
236
        for (size_t i = 0; i < col_size; ++i) {
1033
215
            const auto address = col_in->get_data_at(i);
1034
215
            if (is_ipv4_mapped(address)) {
1035
6
                col_res_data[i] = 1;
1036
6
            }
1037
215
        }
1038
1039
21
        block.replace_by_position(result, std::move(col_res));
1040
21
        return Status::OK();
1041
21
    }
1042
1043
private:
1044
215
    static bool is_ipv4_mapped(const StringRef& address) {
1045
215
        return address.size == IPV6_BINARY_LENGTH && (LittleEndian::Load64(address.data) == 0) &&
1046
215
               ((LittleEndian::Load64(address.data + 8) & 0x00000000FFFFFFFFULL) ==
1047
10
                0x00000000FFFF0000ULL);
1048
215
    }
1049
};
1050
1051
template <IPConvertExceptionMode exception_mode, PrimitiveType PType>
1052
0
inline constexpr auto to_ip_func_name() {
1053
0
    if constexpr (PType == TYPE_IPV4) {
1054
0
        return exception_mode == IPConvertExceptionMode::Throw
1055
0
                       ? "to_ipv4"
1056
0
                       : (exception_mode == IPConvertExceptionMode::Default ? "to_ipv4_or_default"
1057
0
                                                                            : "to_ipv4_or_null");
1058
0
    } else {
1059
0
        return exception_mode == IPConvertExceptionMode::Throw
1060
0
                       ? "to_ipv6"
1061
0
                       : (exception_mode == IPConvertExceptionMode::Default ? "to_ipv6_or_default"
1062
0
                                                                            : "to_ipv6_or_null");
1063
0
    }
1064
0
}
Unexecuted instantiation: _ZN5doris15to_ip_func_nameILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE36EEEDav
Unexecuted instantiation: _ZN5doris15to_ip_func_nameILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE36EEEDav
Unexecuted instantiation: _ZN5doris15to_ip_func_nameILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE36EEEDav
Unexecuted instantiation: _ZN5doris15to_ip_func_nameILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE37EEEDav
Unexecuted instantiation: _ZN5doris15to_ip_func_nameILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE37EEEDav
Unexecuted instantiation: _ZN5doris15to_ip_func_nameILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE37EEEDav
1065
1066
template <IPConvertExceptionMode exception_mode, PrimitiveType PType>
1067
class FunctionToIP : public IFunction {
1068
    static_assert(is_ip(PType));
1069
1070
public:
1071
    static constexpr auto name = to_ip_func_name<exception_mode, PType>();
1072
1073
107
    static FunctionPtr create() { return std::make_shared<FunctionToIP<exception_mode, PType>>(); }
_ZN5doris12FunctionToIPILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE36EE6createEv
Line
Count
Source
1073
20
    static FunctionPtr create() { return std::make_shared<FunctionToIP<exception_mode, PType>>(); }
_ZN5doris12FunctionToIPILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE36EE6createEv
Line
Count
Source
1073
16
    static FunctionPtr create() { return std::make_shared<FunctionToIP<exception_mode, PType>>(); }
_ZN5doris12FunctionToIPILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE36EE6createEv
Line
Count
Source
1073
18
    static FunctionPtr create() { return std::make_shared<FunctionToIP<exception_mode, PType>>(); }
_ZN5doris12FunctionToIPILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE37EE6createEv
Line
Count
Source
1073
20
    static FunctionPtr create() { return std::make_shared<FunctionToIP<exception_mode, PType>>(); }
_ZN5doris12FunctionToIPILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE37EE6createEv
Line
Count
Source
1073
16
    static FunctionPtr create() { return std::make_shared<FunctionToIP<exception_mode, PType>>(); }
_ZN5doris12FunctionToIPILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE37EE6createEv
Line
Count
Source
1073
17
    static FunctionPtr create() { return std::make_shared<FunctionToIP<exception_mode, PType>>(); }
1074
1075
8
    String get_name() const override { return name; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE36EE8get_nameB5cxx11Ev
Line
Count
Source
1075
2
    String get_name() const override { return name; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE36EE8get_nameB5cxx11Ev
Line
Count
Source
1075
1
    String get_name() const override { return name; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE36EE8get_nameB5cxx11Ev
Line
Count
Source
1075
1
    String get_name() const override { return name; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE37EE8get_nameB5cxx11Ev
Line
Count
Source
1075
2
    String get_name() const override { return name; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE37EE8get_nameB5cxx11Ev
Line
Count
Source
1075
1
    String get_name() const override { return name; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE37EE8get_nameB5cxx11Ev
Line
Count
Source
1075
1
    String get_name() const override { return name; }
1076
1077
65
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE36EE23get_number_of_argumentsEv
Line
Count
Source
1077
13
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE36EE23get_number_of_argumentsEv
Line
Count
Source
1077
9
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE36EE23get_number_of_argumentsEv
Line
Count
Source
1077
11
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE37EE23get_number_of_argumentsEv
Line
Count
Source
1077
13
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE37EE23get_number_of_argumentsEv
Line
Count
Source
1077
9
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE37EE23get_number_of_argumentsEv
Line
Count
Source
1077
10
    size_t get_number_of_arguments() const override { return 1; }
1078
1079
65
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1080
65
        DataTypePtr result_type;
1081
1082
65
        if constexpr (PType == TYPE_IPV4) {
1083
33
            result_type = std::make_shared<DataTypeIPv4>();
1084
33
        } else {
1085
32
            result_type = std::make_shared<DataTypeIPv6>();
1086
32
        }
1087
1088
65
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1089
21
            return make_nullable(result_type);
1090
44
        } else {
1091
44
            return result_type;
1092
44
        }
1093
65
    }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE36EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS8_EE
Line
Count
Source
1079
13
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1080
13
        DataTypePtr result_type;
1081
1082
13
        if constexpr (PType == TYPE_IPV4) {
1083
13
            result_type = std::make_shared<DataTypeIPv4>();
1084
        } else {
1085
            result_type = std::make_shared<DataTypeIPv6>();
1086
        }
1087
1088
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1089
            return make_nullable(result_type);
1090
13
        } else {
1091
13
            return result_type;
1092
13
        }
1093
13
    }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE36EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS8_EE
Line
Count
Source
1079
9
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1080
9
        DataTypePtr result_type;
1081
1082
9
        if constexpr (PType == TYPE_IPV4) {
1083
9
            result_type = std::make_shared<DataTypeIPv4>();
1084
        } else {
1085
            result_type = std::make_shared<DataTypeIPv6>();
1086
        }
1087
1088
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1089
            return make_nullable(result_type);
1090
9
        } else {
1091
9
            return result_type;
1092
9
        }
1093
9
    }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE36EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS8_EE
Line
Count
Source
1079
11
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1080
11
        DataTypePtr result_type;
1081
1082
11
        if constexpr (PType == TYPE_IPV4) {
1083
11
            result_type = std::make_shared<DataTypeIPv4>();
1084
        } else {
1085
            result_type = std::make_shared<DataTypeIPv6>();
1086
        }
1087
1088
11
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1089
11
            return make_nullable(result_type);
1090
        } else {
1091
            return result_type;
1092
        }
1093
11
    }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE37EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS8_EE
Line
Count
Source
1079
13
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1080
13
        DataTypePtr result_type;
1081
1082
        if constexpr (PType == TYPE_IPV4) {
1083
            result_type = std::make_shared<DataTypeIPv4>();
1084
13
        } else {
1085
13
            result_type = std::make_shared<DataTypeIPv6>();
1086
13
        }
1087
1088
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1089
            return make_nullable(result_type);
1090
13
        } else {
1091
13
            return result_type;
1092
13
        }
1093
13
    }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE37EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS8_EE
Line
Count
Source
1079
9
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1080
9
        DataTypePtr result_type;
1081
1082
        if constexpr (PType == TYPE_IPV4) {
1083
            result_type = std::make_shared<DataTypeIPv4>();
1084
9
        } else {
1085
9
            result_type = std::make_shared<DataTypeIPv6>();
1086
9
        }
1087
1088
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1089
            return make_nullable(result_type);
1090
9
        } else {
1091
9
            return result_type;
1092
9
        }
1093
9
    }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE37EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS8_EE
Line
Count
Source
1079
10
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1080
10
        DataTypePtr result_type;
1081
1082
        if constexpr (PType == TYPE_IPV4) {
1083
            result_type = std::make_shared<DataTypeIPv4>();
1084
10
        } else {
1085
10
            result_type = std::make_shared<DataTypeIPv6>();
1086
10
        }
1087
1088
10
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1089
10
            return make_nullable(result_type);
1090
        } else {
1091
            return result_type;
1092
        }
1093
10
    }
1094
1095
260
    bool use_default_implementation_for_nulls() const override { return false; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE36EE36use_default_implementation_for_nullsEv
Line
Count
Source
1095
34
    bool use_default_implementation_for_nulls() const override { return false; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE36EE36use_default_implementation_for_nullsEv
Line
Count
Source
1095
45
    bool use_default_implementation_for_nulls() const override { return false; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE36EE36use_default_implementation_for_nullsEv
Line
Count
Source
1095
55
    bool use_default_implementation_for_nulls() const override { return false; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE37EE36use_default_implementation_for_nullsEv
Line
Count
Source
1095
31
    bool use_default_implementation_for_nulls() const override { return false; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE37EE36use_default_implementation_for_nullsEv
Line
Count
Source
1095
45
    bool use_default_implementation_for_nulls() const override { return false; }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE37EE36use_default_implementation_for_nullsEv
Line
Count
Source
1095
50
    bool use_default_implementation_for_nulls() const override { return false; }
1096
1097
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
1098
195
                        uint32_t result, size_t input_rows_count) const override {
1099
195
        const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]);
1100
195
        const ColumnPtr& addr_column = addr_column_with_type_and_name.column;
1101
195
        const ColumnString* str_addr_column = nullptr;
1102
195
        const NullMap* addr_null_map = nullptr;
1103
1104
195
        if (addr_column_with_type_and_name.type->is_nullable()) {
1105
141
            const auto* addr_column_nullable =
1106
141
                    assert_cast<const ColumnNullable*>(addr_column.get());
1107
141
            str_addr_column = assert_cast<const ColumnString*>(
1108
141
                    addr_column_nullable->get_nested_column_ptr().get());
1109
141
            addr_null_map = &addr_column_nullable->get_null_map_data();
1110
141
        } else {
1111
54
            str_addr_column = assert_cast<const ColumnString*>(addr_column.get());
1112
54
        }
1113
1114
195
        auto col_res = ColumnVector<PType>::create(input_rows_count, 0);
1115
195
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
1116
195
        auto& col_res_data = col_res->get_data();
1117
195
        auto& res_null_map_data = res_null_map->get_data();
1118
1119
3.71k
        for (size_t i = 0; i < input_rows_count; ++i) {
1120
3.47k
            if (addr_null_map && (*addr_null_map)[i]) {
1121
53
                if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1122
2
                    throw Exception(ErrorCode::INVALID_ARGUMENT,
1123
2
                                    "The arguments of function {} must be String, not NULL",
1124
2
                                    get_name());
1125
24
                } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1126
24
                    col_res_data[i] = 0; // '0.0.0.0' or '::'
1127
24
                    continue;
1128
27
                } else {
1129
27
                    res_null_map_data[i] = 1;
1130
27
                    continue;
1131
27
                }
1132
53
            }
1133
1134
1.74k
            if constexpr (PType == TYPE_IPV4) {
1135
1.74k
                StringRef ipv4_str = str_addr_column->get_data_at(i);
1136
1.74k
                IPv4 ipv4_val = 0;
1137
1.74k
                if (IPv4Value::from_string(ipv4_val, ipv4_str.data, ipv4_str.size)) {
1138
530
                    col_res_data[i] = ipv4_val;
1139
1.21k
                } else {
1140
1.21k
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1141
5
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value '{}'",
1142
5
                                        ipv4_str.to_string_view());
1143
602
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1144
602
                        col_res_data[i] = 0; // '0.0.0.0'
1145
604
                    } else {
1146
604
                        res_null_map_data[i] = 1;
1147
604
                    }
1148
1.21k
                }
1149
1.74k
            } else {
1150
1.73k
                StringRef ipv6_str = str_addr_column->get_data_at(i);
1151
1.73k
                IPv6 ipv6_val = 0;
1152
1.73k
                if (IPv6Value::from_string(ipv6_val, ipv6_str.data, ipv6_str.size)) {
1153
513
                    col_res_data[i] = ipv6_val;
1154
1.21k
                } else {
1155
1.21k
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1156
4
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value '{}'",
1157
4
                                        ipv6_str.to_string_view());
1158
607
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1159
607
                        col_res_data[i] = 0; // '::'
1160
608
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1161
608
                        res_null_map_data[i] = 1;
1162
608
                    }
1163
1.21k
                }
1164
1.73k
            }
1165
3.47k
        }
1166
1167
207
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1168
111
            block.replace_by_position(
1169
111
                    result, ColumnNullable::create(std::move(col_res), std::move(res_null_map)));
1170
135
        } else {
1171
135
            block.replace_by_position(result, std::move(col_res));
1172
135
        }
1173
1174
207
        return Status::OK();
1175
195
    }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE36EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
1098
21
                        uint32_t result, size_t input_rows_count) const override {
1099
21
        const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]);
1100
21
        const ColumnPtr& addr_column = addr_column_with_type_and_name.column;
1101
21
        const ColumnString* str_addr_column = nullptr;
1102
21
        const NullMap* addr_null_map = nullptr;
1103
1104
21
        if (addr_column_with_type_and_name.type->is_nullable()) {
1105
12
            const auto* addr_column_nullable =
1106
12
                    assert_cast<const ColumnNullable*>(addr_column.get());
1107
12
            str_addr_column = assert_cast<const ColumnString*>(
1108
12
                    addr_column_nullable->get_nested_column_ptr().get());
1109
12
            addr_null_map = &addr_column_nullable->get_null_map_data();
1110
12
        } else {
1111
9
            str_addr_column = assert_cast<const ColumnString*>(addr_column.get());
1112
9
        }
1113
1114
21
        auto col_res = ColumnVector<PType>::create(input_rows_count, 0);
1115
21
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
1116
21
        auto& col_res_data = col_res->get_data();
1117
21
        auto& res_null_map_data = res_null_map->get_data();
1118
1119
142
        for (size_t i = 0; i < input_rows_count; ++i) {
1120
121
            if (addr_null_map && (*addr_null_map)[i]) {
1121
1
                if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1122
1
                    throw Exception(ErrorCode::INVALID_ARGUMENT,
1123
1
                                    "The arguments of function {} must be String, not NULL",
1124
1
                                    get_name());
1125
                } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1126
                    col_res_data[i] = 0; // '0.0.0.0' or '::'
1127
                    continue;
1128
                } else {
1129
                    res_null_map_data[i] = 1;
1130
                    continue;
1131
                }
1132
1
            }
1133
1134
121
            if constexpr (PType == TYPE_IPV4) {
1135
121
                StringRef ipv4_str = str_addr_column->get_data_at(i);
1136
121
                IPv4 ipv4_val = 0;
1137
121
                if (IPv4Value::from_string(ipv4_val, ipv4_str.data, ipv4_str.size)) {
1138
116
                    col_res_data[i] = ipv4_val;
1139
116
                } else {
1140
5
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1141
5
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value '{}'",
1142
5
                                        ipv4_str.to_string_view());
1143
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1144
                        col_res_data[i] = 0; // '0.0.0.0'
1145
                    } else {
1146
                        res_null_map_data[i] = 1;
1147
                    }
1148
5
                }
1149
            } else {
1150
                StringRef ipv6_str = str_addr_column->get_data_at(i);
1151
                IPv6 ipv6_val = 0;
1152
                if (IPv6Value::from_string(ipv6_val, ipv6_str.data, ipv6_str.size)) {
1153
                    col_res_data[i] = ipv6_val;
1154
                } else {
1155
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1156
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value '{}'",
1157
                                        ipv6_str.to_string_view());
1158
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1159
                        col_res_data[i] = 0; // '::'
1160
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1161
                        res_null_map_data[i] = 1;
1162
                    }
1163
                }
1164
            }
1165
121
        }
1166
1167
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1168
            block.replace_by_position(
1169
                    result, ColumnNullable::create(std::move(col_res), std::move(res_null_map)));
1170
21
        } else {
1171
21
            block.replace_by_position(result, std::move(col_res));
1172
21
        }
1173
1174
21
        return Status::OK();
1175
21
    }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE36EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
1098
36
                        uint32_t result, size_t input_rows_count) const override {
1099
36
        const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]);
1100
36
        const ColumnPtr& addr_column = addr_column_with_type_and_name.column;
1101
36
        const ColumnString* str_addr_column = nullptr;
1102
36
        const NullMap* addr_null_map = nullptr;
1103
1104
36
        if (addr_column_with_type_and_name.type->is_nullable()) {
1105
28
            const auto* addr_column_nullable =
1106
28
                    assert_cast<const ColumnNullable*>(addr_column.get());
1107
28
            str_addr_column = assert_cast<const ColumnString*>(
1108
28
                    addr_column_nullable->get_nested_column_ptr().get());
1109
28
            addr_null_map = &addr_column_nullable->get_null_map_data();
1110
28
        } else {
1111
8
            str_addr_column = assert_cast<const ColumnString*>(addr_column.get());
1112
8
        }
1113
1114
36
        auto col_res = ColumnVector<PType>::create(input_rows_count, 0);
1115
36
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
1116
36
        auto& col_res_data = col_res->get_data();
1117
36
        auto& res_null_map_data = res_null_map->get_data();
1118
1119
850
        for (size_t i = 0; i < input_rows_count; ++i) {
1120
802
            if (addr_null_map && (*addr_null_map)[i]) {
1121
                if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1122
                    throw Exception(ErrorCode::INVALID_ARGUMENT,
1123
                                    "The arguments of function {} must be String, not NULL",
1124
                                    get_name());
1125
12
                } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1126
12
                    col_res_data[i] = 0; // '0.0.0.0' or '::'
1127
12
                    continue;
1128
                } else {
1129
                    res_null_map_data[i] = 1;
1130
                    continue;
1131
                }
1132
12
            }
1133
1134
802
            if constexpr (PType == TYPE_IPV4) {
1135
802
                StringRef ipv4_str = str_addr_column->get_data_at(i);
1136
802
                IPv4 ipv4_val = 0;
1137
802
                if (IPv4Value::from_string(ipv4_val, ipv4_str.data, ipv4_str.size)) {
1138
200
                    col_res_data[i] = ipv4_val;
1139
602
                } else {
1140
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1141
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value '{}'",
1142
                                        ipv4_str.to_string_view());
1143
602
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1144
602
                        col_res_data[i] = 0; // '0.0.0.0'
1145
                    } else {
1146
                        res_null_map_data[i] = 1;
1147
                    }
1148
602
                }
1149
            } else {
1150
                StringRef ipv6_str = str_addr_column->get_data_at(i);
1151
                IPv6 ipv6_val = 0;
1152
                if (IPv6Value::from_string(ipv6_val, ipv6_str.data, ipv6_str.size)) {
1153
                    col_res_data[i] = ipv6_val;
1154
                } else {
1155
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1156
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value '{}'",
1157
                                        ipv6_str.to_string_view());
1158
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1159
                        col_res_data[i] = 0; // '::'
1160
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1161
                        res_null_map_data[i] = 1;
1162
                    }
1163
                }
1164
            }
1165
802
        }
1166
1167
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1168
            block.replace_by_position(
1169
                    result, ColumnNullable::create(std::move(col_res), std::move(res_null_map)));
1170
48
        } else {
1171
48
            block.replace_by_position(result, std::move(col_res));
1172
48
        }
1173
1174
48
        return Status::OK();
1175
36
    }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE36EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
1098
44
                        uint32_t result, size_t input_rows_count) const override {
1099
44
        const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]);
1100
44
        const ColumnPtr& addr_column = addr_column_with_type_and_name.column;
1101
44
        const ColumnString* str_addr_column = nullptr;
1102
44
        const NullMap* addr_null_map = nullptr;
1103
1104
44
        if (addr_column_with_type_and_name.type->is_nullable()) {
1105
36
            const auto* addr_column_nullable =
1106
36
                    assert_cast<const ColumnNullable*>(addr_column.get());
1107
36
            str_addr_column = assert_cast<const ColumnString*>(
1108
36
                    addr_column_nullable->get_nested_column_ptr().get());
1109
36
            addr_null_map = &addr_column_nullable->get_null_map_data();
1110
36
        } else {
1111
8
            str_addr_column = assert_cast<const ColumnString*>(addr_column.get());
1112
8
        }
1113
1114
44
        auto col_res = ColumnVector<PType>::create(input_rows_count, 0);
1115
44
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
1116
44
        auto& col_res_data = col_res->get_data();
1117
44
        auto& res_null_map_data = res_null_map->get_data();
1118
1119
876
        for (size_t i = 0; i < input_rows_count; ++i) {
1120
818
            if (addr_null_map && (*addr_null_map)[i]) {
1121
                if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1122
                    throw Exception(ErrorCode::INVALID_ARGUMENT,
1123
                                    "The arguments of function {} must be String, not NULL",
1124
                                    get_name());
1125
                } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1126
                    col_res_data[i] = 0; // '0.0.0.0' or '::'
1127
                    continue;
1128
14
                } else {
1129
14
                    res_null_map_data[i] = 1;
1130
14
                    continue;
1131
14
                }
1132
14
            }
1133
1134
818
            if constexpr (PType == TYPE_IPV4) {
1135
818
                StringRef ipv4_str = str_addr_column->get_data_at(i);
1136
818
                IPv4 ipv4_val = 0;
1137
818
                if (IPv4Value::from_string(ipv4_val, ipv4_str.data, ipv4_str.size)) {
1138
214
                    col_res_data[i] = ipv4_val;
1139
604
                } else {
1140
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1141
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value '{}'",
1142
                                        ipv4_str.to_string_view());
1143
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1144
                        col_res_data[i] = 0; // '0.0.0.0'
1145
604
                    } else {
1146
604
                        res_null_map_data[i] = 1;
1147
604
                    }
1148
604
                }
1149
            } else {
1150
                StringRef ipv6_str = str_addr_column->get_data_at(i);
1151
                IPv6 ipv6_val = 0;
1152
                if (IPv6Value::from_string(ipv6_val, ipv6_str.data, ipv6_str.size)) {
1153
                    col_res_data[i] = ipv6_val;
1154
                } else {
1155
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1156
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value '{}'",
1157
                                        ipv6_str.to_string_view());
1158
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1159
                        col_res_data[i] = 0; // '::'
1160
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1161
                        res_null_map_data[i] = 1;
1162
                    }
1163
                }
1164
            }
1165
818
        }
1166
1167
58
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1168
58
            block.replace_by_position(
1169
58
                    result, ColumnNullable::create(std::move(col_res), std::move(res_null_map)));
1170
        } else {
1171
            block.replace_by_position(result, std::move(col_res));
1172
        }
1173
1174
58
        return Status::OK();
1175
44
    }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE0ELNS_13PrimitiveTypeE37EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
1098
18
                        uint32_t result, size_t input_rows_count) const override {
1099
18
        const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]);
1100
18
        const ColumnPtr& addr_column = addr_column_with_type_and_name.column;
1101
18
        const ColumnString* str_addr_column = nullptr;
1102
18
        const NullMap* addr_null_map = nullptr;
1103
1104
18
        if (addr_column_with_type_and_name.type->is_nullable()) {
1105
5
            const auto* addr_column_nullable =
1106
5
                    assert_cast<const ColumnNullable*>(addr_column.get());
1107
5
            str_addr_column = assert_cast<const ColumnString*>(
1108
5
                    addr_column_nullable->get_nested_column_ptr().get());
1109
5
            addr_null_map = &addr_column_nullable->get_null_map_data();
1110
13
        } else {
1111
13
            str_addr_column = assert_cast<const ColumnString*>(addr_column.get());
1112
13
        }
1113
1114
18
        auto col_res = ColumnVector<PType>::create(input_rows_count, 0);
1115
18
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
1116
18
        auto& col_res_data = col_res->get_data();
1117
18
        auto& res_null_map_data = res_null_map->get_data();
1118
1119
137
        for (size_t i = 0; i < input_rows_count; ++i) {
1120
119
            if (addr_null_map && (*addr_null_map)[i]) {
1121
1
                if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1122
1
                    throw Exception(ErrorCode::INVALID_ARGUMENT,
1123
1
                                    "The arguments of function {} must be String, not NULL",
1124
1
                                    get_name());
1125
                } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1126
                    col_res_data[i] = 0; // '0.0.0.0' or '::'
1127
                    continue;
1128
                } else {
1129
                    res_null_map_data[i] = 1;
1130
                    continue;
1131
                }
1132
1
            }
1133
1134
            if constexpr (PType == TYPE_IPV4) {
1135
                StringRef ipv4_str = str_addr_column->get_data_at(i);
1136
                IPv4 ipv4_val = 0;
1137
                if (IPv4Value::from_string(ipv4_val, ipv4_str.data, ipv4_str.size)) {
1138
                    col_res_data[i] = ipv4_val;
1139
                } else {
1140
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1141
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value '{}'",
1142
                                        ipv4_str.to_string_view());
1143
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1144
                        col_res_data[i] = 0; // '0.0.0.0'
1145
                    } else {
1146
                        res_null_map_data[i] = 1;
1147
                    }
1148
                }
1149
119
            } else {
1150
119
                StringRef ipv6_str = str_addr_column->get_data_at(i);
1151
119
                IPv6 ipv6_val = 0;
1152
119
                if (IPv6Value::from_string(ipv6_val, ipv6_str.data, ipv6_str.size)) {
1153
115
                    col_res_data[i] = ipv6_val;
1154
115
                } else {
1155
4
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1156
4
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value '{}'",
1157
4
                                        ipv6_str.to_string_view());
1158
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1159
                        col_res_data[i] = 0; // '::'
1160
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1161
                        res_null_map_data[i] = 1;
1162
                    }
1163
4
                }
1164
119
            }
1165
119
        }
1166
1167
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1168
            block.replace_by_position(
1169
                    result, ColumnNullable::create(std::move(col_res), std::move(res_null_map)));
1170
18
        } else {
1171
18
            block.replace_by_position(result, std::move(col_res));
1172
18
        }
1173
1174
18
        return Status::OK();
1175
18
    }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE1ELNS_13PrimitiveTypeE37EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
1098
36
                        uint32_t result, size_t input_rows_count) const override {
1099
36
        const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]);
1100
36
        const ColumnPtr& addr_column = addr_column_with_type_and_name.column;
1101
36
        const ColumnString* str_addr_column = nullptr;
1102
36
        const NullMap* addr_null_map = nullptr;
1103
1104
36
        if (addr_column_with_type_and_name.type->is_nullable()) {
1105
28
            const auto* addr_column_nullable =
1106
28
                    assert_cast<const ColumnNullable*>(addr_column.get());
1107
28
            str_addr_column = assert_cast<const ColumnString*>(
1108
28
                    addr_column_nullable->get_nested_column_ptr().get());
1109
28
            addr_null_map = &addr_column_nullable->get_null_map_data();
1110
28
        } else {
1111
8
            str_addr_column = assert_cast<const ColumnString*>(addr_column.get());
1112
8
        }
1113
1114
36
        auto col_res = ColumnVector<PType>::create(input_rows_count, 0);
1115
36
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
1116
36
        auto& col_res_data = col_res->get_data();
1117
36
        auto& res_null_map_data = res_null_map->get_data();
1118
1119
850
        for (size_t i = 0; i < input_rows_count; ++i) {
1120
802
            if (addr_null_map && (*addr_null_map)[i]) {
1121
                if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1122
                    throw Exception(ErrorCode::INVALID_ARGUMENT,
1123
                                    "The arguments of function {} must be String, not NULL",
1124
                                    get_name());
1125
12
                } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1126
12
                    col_res_data[i] = 0; // '0.0.0.0' or '::'
1127
12
                    continue;
1128
                } else {
1129
                    res_null_map_data[i] = 1;
1130
                    continue;
1131
                }
1132
12
            }
1133
1134
            if constexpr (PType == TYPE_IPV4) {
1135
                StringRef ipv4_str = str_addr_column->get_data_at(i);
1136
                IPv4 ipv4_val = 0;
1137
                if (IPv4Value::from_string(ipv4_val, ipv4_str.data, ipv4_str.size)) {
1138
                    col_res_data[i] = ipv4_val;
1139
                } else {
1140
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1141
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value '{}'",
1142
                                        ipv4_str.to_string_view());
1143
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1144
                        col_res_data[i] = 0; // '0.0.0.0'
1145
                    } else {
1146
                        res_null_map_data[i] = 1;
1147
                    }
1148
                }
1149
802
            } else {
1150
802
                StringRef ipv6_str = str_addr_column->get_data_at(i);
1151
802
                IPv6 ipv6_val = 0;
1152
802
                if (IPv6Value::from_string(ipv6_val, ipv6_str.data, ipv6_str.size)) {
1153
195
                    col_res_data[i] = ipv6_val;
1154
607
                } else {
1155
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1156
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value '{}'",
1157
                                        ipv6_str.to_string_view());
1158
607
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1159
607
                        col_res_data[i] = 0; // '::'
1160
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1161
                        res_null_map_data[i] = 1;
1162
                    }
1163
607
                }
1164
802
            }
1165
802
        }
1166
1167
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1168
            block.replace_by_position(
1169
                    result, ColumnNullable::create(std::move(col_res), std::move(res_null_map)));
1170
48
        } else {
1171
48
            block.replace_by_position(result, std::move(col_res));
1172
48
        }
1173
1174
48
        return Status::OK();
1175
36
    }
_ZNK5doris12FunctionToIPILNS_22IPConvertExceptionModeE2ELNS_13PrimitiveTypeE37EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
1098
40
                        uint32_t result, size_t input_rows_count) const override {
1099
40
        const auto& addr_column_with_type_and_name = block.get_by_position(arguments[0]);
1100
40
        const ColumnPtr& addr_column = addr_column_with_type_and_name.column;
1101
40
        const ColumnString* str_addr_column = nullptr;
1102
40
        const NullMap* addr_null_map = nullptr;
1103
1104
40
        if (addr_column_with_type_and_name.type->is_nullable()) {
1105
32
            const auto* addr_column_nullable =
1106
32
                    assert_cast<const ColumnNullable*>(addr_column.get());
1107
32
            str_addr_column = assert_cast<const ColumnString*>(
1108
32
                    addr_column_nullable->get_nested_column_ptr().get());
1109
32
            addr_null_map = &addr_column_nullable->get_null_map_data();
1110
32
        } else {
1111
8
            str_addr_column = assert_cast<const ColumnString*>(addr_column.get());
1112
8
        }
1113
1114
40
        auto col_res = ColumnVector<PType>::create(input_rows_count, 0);
1115
40
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
1116
40
        auto& col_res_data = col_res->get_data();
1117
40
        auto& res_null_map_data = res_null_map->get_data();
1118
1119
864
        for (size_t i = 0; i < input_rows_count; ++i) {
1120
811
            if (addr_null_map && (*addr_null_map)[i]) {
1121
                if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1122
                    throw Exception(ErrorCode::INVALID_ARGUMENT,
1123
                                    "The arguments of function {} must be String, not NULL",
1124
                                    get_name());
1125
                } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1126
                    col_res_data[i] = 0; // '0.0.0.0' or '::'
1127
                    continue;
1128
13
                } else {
1129
13
                    res_null_map_data[i] = 1;
1130
13
                    continue;
1131
13
                }
1132
13
            }
1133
1134
            if constexpr (PType == TYPE_IPV4) {
1135
                StringRef ipv4_str = str_addr_column->get_data_at(i);
1136
                IPv4 ipv4_val = 0;
1137
                if (IPv4Value::from_string(ipv4_val, ipv4_str.data, ipv4_str.size)) {
1138
                    col_res_data[i] = ipv4_val;
1139
                } else {
1140
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1141
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv4 value '{}'",
1142
                                        ipv4_str.to_string_view());
1143
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1144
                        col_res_data[i] = 0; // '0.0.0.0'
1145
                    } else {
1146
                        res_null_map_data[i] = 1;
1147
                    }
1148
                }
1149
811
            } else {
1150
811
                StringRef ipv6_str = str_addr_column->get_data_at(i);
1151
811
                IPv6 ipv6_val = 0;
1152
811
                if (IPv6Value::from_string(ipv6_val, ipv6_str.data, ipv6_str.size)) {
1153
203
                    col_res_data[i] = ipv6_val;
1154
608
                } else {
1155
                    if constexpr (exception_mode == IPConvertExceptionMode::Throw) {
1156
                        throw Exception(ErrorCode::INVALID_ARGUMENT, "Invalid IPv6 value '{}'",
1157
                                        ipv6_str.to_string_view());
1158
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Default) {
1159
                        col_res_data[i] = 0; // '::'
1160
608
                    } else if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1161
608
                        res_null_map_data[i] = 1;
1162
608
                    }
1163
608
                }
1164
811
            }
1165
811
        }
1166
1167
53
        if constexpr (exception_mode == IPConvertExceptionMode::Null) {
1168
53
            block.replace_by_position(
1169
53
                    result, ColumnNullable::create(std::move(col_res), std::move(res_null_map)));
1170
        } else {
1171
            block.replace_by_position(result, std::move(col_res));
1172
        }
1173
1174
53
        return Status::OK();
1175
40
    }
1176
};
1177
1178
class FunctionIPv4ToIPv6 : public IFunction {
1179
public:
1180
    static constexpr auto name = "ipv4_to_ipv6";
1181
14
    static FunctionPtr create() { return std::make_shared<FunctionIPv4ToIPv6>(); }
1182
1183
1
    String get_name() const override { return name; }
1184
1185
7
    size_t get_number_of_arguments() const override { return 1; }
1186
1187
7
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1188
7
        return std::make_shared<DataTypeIPv6>();
1189
7
    }
1190
1191
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
1192
14
                        uint32_t result, size_t input_rows_count) const override {
1193
14
        const auto& ipv4_column_with_type_and_name = block.get_by_position(arguments[0]);
1194
14
        const auto& [ipv4_column, ipv4_const] =
1195
14
                unpack_if_const(ipv4_column_with_type_and_name.column);
1196
14
        const auto* ipv4_addr_column = assert_cast<const ColumnIPv4*>(ipv4_column.get());
1197
14
        const auto& ipv4_column_data = ipv4_addr_column->get_data();
1198
14
        auto col_res = ColumnIPv6::create(input_rows_count, 0);
1199
14
        auto& col_res_data = col_res->get_data();
1200
1201
48
        for (size_t i = 0; i < input_rows_count; ++i) {
1202
34
            auto ipv4_idx = index_check_const(i, ipv4_const);
1203
34
            map_ipv4_to_ipv6(ipv4_column_data[ipv4_idx],
1204
34
                             reinterpret_cast<UInt8*>(&col_res_data[i]));
1205
34
        }
1206
1207
14
        block.replace_by_position(result, std::move(col_res));
1208
14
        return Status::OK();
1209
14
    }
1210
};
1211
1212
class FunctionCutIPv6 : public IFunction {
1213
public:
1214
    static constexpr auto name = "cut_ipv6";
1215
11
    static FunctionPtr create() { return std::make_shared<FunctionCutIPv6>(); }
1216
1217
1
    String get_name() const override { return name; }
1218
1219
4
    size_t get_number_of_arguments() const override { return 3; }
1220
1221
4
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1222
4
        return std::make_shared<DataTypeString>();
1223
4
    }
1224
1225
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
1226
9
                        uint32_t result, size_t input_rows_count) const override {
1227
9
        const auto& ipv6_column_with_type_and_name = block.get_by_position(arguments[0]);
1228
9
        const auto& bytes_to_cut_for_ipv6_column_with_type_and_name =
1229
9
                block.get_by_position(arguments[1]);
1230
9
        const auto& bytes_to_cut_for_ipv4_column_with_type_and_name =
1231
9
                block.get_by_position(arguments[2]);
1232
1233
9
        const auto& [ipv6_column, ipv6_const] =
1234
9
                unpack_if_const(ipv6_column_with_type_and_name.column);
1235
9
        const auto& [bytes_to_cut_for_ipv6_column, bytes_to_cut_for_ipv6_const] =
1236
9
                unpack_if_const(bytes_to_cut_for_ipv6_column_with_type_and_name.column);
1237
9
        const auto& [bytes_to_cut_for_ipv4_column, bytes_to_cut_for_ipv4_const] =
1238
9
                unpack_if_const(bytes_to_cut_for_ipv4_column_with_type_and_name.column);
1239
1240
9
        const auto* ipv6_addr_column = assert_cast<const ColumnIPv6*>(ipv6_column.get());
1241
9
        const auto* to_cut_for_ipv6_bytes_column =
1242
9
                assert_cast<const ColumnInt8*>(bytes_to_cut_for_ipv6_column.get());
1243
9
        const auto* to_cut_for_ipv4_bytes_column =
1244
9
                assert_cast<const ColumnInt8*>(bytes_to_cut_for_ipv4_column.get());
1245
1246
9
        const auto& ipv6_addr_column_data = ipv6_addr_column->get_data();
1247
9
        const auto& to_cut_for_ipv6_bytes_column_data = to_cut_for_ipv6_bytes_column->get_data();
1248
9
        const auto& to_cut_for_ipv4_bytes_column_data = to_cut_for_ipv4_bytes_column->get_data();
1249
1250
9
        auto col_res = ColumnString::create();
1251
9
        ColumnString::Chars& chars_res = col_res->get_chars();
1252
9
        ColumnString::Offsets& offsets_res = col_res->get_offsets();
1253
9
        chars_res.resize(input_rows_count * (IPV6_MAX_TEXT_LENGTH + 1)); // + 1 for ending '\0'
1254
9
        offsets_res.resize(input_rows_count);
1255
9
        auto* begin = reinterpret_cast<char*>(chars_res.data());
1256
9
        auto* pos = begin;
1257
1258
36
        for (size_t i = 0; i < input_rows_count; ++i) {
1259
27
            auto ipv6_idx = index_check_const(i, ipv6_const);
1260
27
            auto bytes_to_cut_for_ipv6_idx = index_check_const(i, bytes_to_cut_for_ipv6_const);
1261
27
            auto bytes_to_cut_for_ipv4_idx = index_check_const(i, bytes_to_cut_for_ipv4_const);
1262
            // the current function logic is processed in big endian manner
1263
            // But ipv6 in doris is stored in little-endian byte order
1264
            // need transfer to big-endian byte order first, so we can't deal this process in column
1265
27
            auto val_128 = ipv6_addr_column_data[ipv6_idx];
1266
27
            auto* address = reinterpret_cast<unsigned char*>(&val_128);
1267
1268
27
            Int8 bytes_to_cut_for_ipv6_count =
1269
27
                    to_cut_for_ipv6_bytes_column_data[bytes_to_cut_for_ipv6_idx];
1270
27
            Int8 bytes_to_cut_for_ipv4_count =
1271
27
                    to_cut_for_ipv4_bytes_column_data[bytes_to_cut_for_ipv4_idx];
1272
1273
27
            if (bytes_to_cut_for_ipv6_count > IPV6_BINARY_LENGTH) [[unlikely]] {
1274
0
                throw Exception(ErrorCode::INVALID_ARGUMENT,
1275
0
                                "Illegal value for argument 2 {} of function {}",
1276
0
                                bytes_to_cut_for_ipv6_column_with_type_and_name.type->get_name(),
1277
0
                                get_name());
1278
0
            }
1279
1280
27
            if (bytes_to_cut_for_ipv4_count > IPV6_BINARY_LENGTH) [[unlikely]] {
1281
0
                throw Exception(ErrorCode::INVALID_ARGUMENT,
1282
0
                                "Illegal value for argument 3 {} of function {}",
1283
0
                                bytes_to_cut_for_ipv4_column_with_type_and_name.type->get_name(),
1284
0
                                get_name());
1285
0
            }
1286
1287
27
            UInt8 bytes_to_cut_count = is_ipv4_mapped(address) ? bytes_to_cut_for_ipv4_count
1288
27
                                                               : bytes_to_cut_for_ipv6_count;
1289
27
            cut_address(address, pos, bytes_to_cut_count);
1290
27
            offsets_res[i] = cast_set<uint32_t>(pos - begin);
1291
27
        }
1292
1293
9
        chars_res.resize(offsets_res[offsets_res.size() - 1]);
1294
1295
9
        block.replace_by_position(result, std::move(col_res));
1296
9
        return Status::OK();
1297
9
    }
1298
1299
private:
1300
27
    static bool is_ipv4_mapped(const UInt8* address) {
1301
27
        return (LittleEndian::Load64(address + 8) == 0) &&
1302
27
               ((LittleEndian::Load64(address) & 0xFFFFFFFF00000000ULL) == 0x0000FFFF00000000ULL);
1303
27
    }
1304
1305
27
    static void cut_address(unsigned char* address, char*& dst, UInt8 zeroed_tail_bytes_count) {
1306
27
        format_ipv6(address, dst, zeroed_tail_bytes_count);
1307
27
    }
1308
};
1309
1310
class FunctionIPv6FromUInt128StringOrNull : public IFunction {
1311
public:
1312
    static constexpr auto name = "ipv6_from_uint128_string_or_null";
1313
9
    static FunctionPtr create() { return std::make_shared<FunctionIPv6FromUInt128StringOrNull>(); }
1314
1315
1
    String get_name() const override { return name; }
1316
1317
2
    size_t get_number_of_arguments() const override { return 1; }
1318
1319
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1320
2
        return std::make_shared<DataTypeNullable>(std::make_shared<DataTypeIPv6>());
1321
2
    }
1322
1323
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
1324
6
                        uint32_t result, size_t input_rows_count) const override {
1325
6
        const auto& ipv6_column_with_type_and_name = block.get_by_position(arguments[0]);
1326
6
        const auto& [ipv6_column, ipv6_const] =
1327
6
                unpack_if_const(ipv6_column_with_type_and_name.column);
1328
6
        const auto* ipv6_addr_column = assert_cast<const ColumnString*>(ipv6_column.get());
1329
        // result is nullable column
1330
6
        auto col_res_nested = ColumnIPv6::create(input_rows_count, 0);
1331
6
        auto col_res_null_map = ColumnUInt8::create(input_rows_count, 1);
1332
6
        auto& col_res_data = col_res_nested->get_data();
1333
6
        auto& res_null_map_data = col_res_null_map->get_data();
1334
1335
216
        for (size_t i = 0; i < input_rows_count; ++i) {
1336
210
            IPv6 ipv6 = 0;
1337
210
            auto ipv6_idx = index_check_const(i, ipv6_const);
1338
210
            StringRef uint128_string = ipv6_addr_column->get_data_at(ipv6_idx);
1339
210
            if (!IPv6Value::from_uint128_string(ipv6, uint128_string.data, uint128_string.size)) {
1340
0
                VLOG_DEBUG << "Invalid uin128 IPv6 value '" << uint128_string.to_string_view()
1341
0
                           << "'";
1342
                // we should set null to the result not throw exception for load senior
1343
210
            } else {
1344
210
                col_res_data[i] = ipv6;
1345
210
                res_null_map_data[i] = 0;
1346
210
            }
1347
210
        }
1348
1349
6
        block.replace_by_position(result, ColumnNullable::create(std::move(col_res_nested),
1350
6
                                                                 std::move(col_res_null_map)));
1351
6
        return Status::OK();
1352
6
    }
1353
};
1354
1355
} // namespace doris