Coverage Report

Created: 2026-04-10 04:10

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