Coverage Report

Created: 2026-03-13 03:47

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