Coverage Report

Created: 2026-09-18 04:34

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