Coverage Report

Created: 2026-07-15 12:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exec/common/varbinaryop_subbinary.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
18
#pragma once
19
20
#include "core/block/block.h"
21
#include "core/column/column_const.h"
22
#include "core/column/column_varbinary.h"
23
#include "core/data_type/data_type_number.h"
24
#include "core/data_type/data_type_varbinary.h"
25
#include "core/types.h"
26
27
namespace doris {
28
29
constexpr auto SIZE_OF_UINT = sizeof(uint32_t);
30
31
struct VarBinaryOP {
32
    static void check_and_insert_data(doris::StringView& sView, const char* data, uint32_t len,
33
20
                                      bool before_is_inline) {
34
20
        if (before_is_inline) {
35
14
            sView.set_size(len);
36
14
        } else {
37
6
            sView = doris::StringView(data, len);
38
6
        }
39
20
    }
40
41
33
    static std::pair<bool, char*> alloc(ColumnVarbinary* res_col, size_t index, uint32_t len) {
42
33
        bool is_inline = StringView::isInline(len);
43
33
        char* dst = nullptr;
44
33
        if (is_inline) {
45
27
            dst = reinterpret_cast<char*>(&(res_col->get_data()[index])) + SIZE_OF_UINT;
46
27
        } else {
47
6
            dst = res_col->alloc(len);
48
6
        }
49
33
        return {is_inline, dst};
50
33
    }
51
};
52
53
struct SubBinaryUtil {
54
    static void sub_binary_execute(Block& block, const ColumnNumbers& arguments, uint32_t result,
55
1.01k
                                   size_t input_rows_count) {
56
1.01k
        DCHECK_EQ(arguments.size(), 3);
57
1.01k
        auto res = ColumnVarbinary::create();
58
59
1.01k
        bool col_const[3];
60
1.01k
        ColumnPtr argument_columns[3];
61
4.04k
        for (int i = 0; i < 3; ++i) {
62
3.03k
            std::tie(argument_columns[i], col_const[i]) =
63
3.03k
                    unpack_if_const(block.get_by_position(arguments[i]).column);
64
3.03k
        }
65
66
1.01k
        const auto* specific_binary_column =
67
1.01k
                assert_cast<const ColumnVarbinary*>(argument_columns[0].get());
68
1.01k
        const auto* specific_start_column =
69
1.01k
                assert_cast<const ColumnInt32*>(argument_columns[1].get());
70
1.01k
        const auto* specific_len_column =
71
1.01k
                assert_cast<const ColumnInt32*>(argument_columns[2].get());
72
73
1.01k
        std::visit(
74
1.01k
                [&](auto binary_const, auto start_const, auto len_const) {
75
1.01k
                    vectors<binary_const, start_const, len_const>(
76
1.01k
                            specific_binary_column, specific_start_column, specific_len_column,
77
1.01k
                            res.get(), input_rows_count);
78
1.01k
                },
_ZZN5doris13SubBinaryUtil18sub_binary_executeERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlT_T0_T1_E_clISt17integral_constantIbLb0EESE_SE_EEDaS8_S9_SA_
Line
Count
Source
74
146
                [&](auto binary_const, auto start_const, auto len_const) {
75
146
                    vectors<binary_const, start_const, len_const>(
76
146
                            specific_binary_column, specific_start_column, specific_len_column,
77
146
                            res.get(), input_rows_count);
78
146
                },
_ZZN5doris13SubBinaryUtil18sub_binary_executeERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlT_T0_T1_E_clISt17integral_constantIbLb0EESE_SD_IbLb1EEEEDaS8_S9_SA_
Line
Count
Source
74
144
                [&](auto binary_const, auto start_const, auto len_const) {
75
144
                    vectors<binary_const, start_const, len_const>(
76
144
                            specific_binary_column, specific_start_column, specific_len_column,
77
144
                            res.get(), input_rows_count);
78
144
                },
_ZZN5doris13SubBinaryUtil18sub_binary_executeERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlT_T0_T1_E_clISt17integral_constantIbLb0EESD_IbLb1EESE_EEDaS8_S9_SA_
Line
Count
Source
74
144
                [&](auto binary_const, auto start_const, auto len_const) {
75
144
                    vectors<binary_const, start_const, len_const>(
76
144
                            specific_binary_column, specific_start_column, specific_len_column,
77
144
                            res.get(), input_rows_count);
78
144
                },
_ZZN5doris13SubBinaryUtil18sub_binary_executeERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlT_T0_T1_E_clISt17integral_constantIbLb0EESD_IbLb1EESF_EEDaS8_S9_SA_
Line
Count
Source
74
144
                [&](auto binary_const, auto start_const, auto len_const) {
75
144
                    vectors<binary_const, start_const, len_const>(
76
144
                            specific_binary_column, specific_start_column, specific_len_column,
77
144
                            res.get(), input_rows_count);
78
144
                },
_ZZN5doris13SubBinaryUtil18sub_binary_executeERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlT_T0_T1_E_clISt17integral_constantIbLb1EESD_IbLb0EESF_EEDaS8_S9_SA_
Line
Count
Source
74
144
                [&](auto binary_const, auto start_const, auto len_const) {
75
144
                    vectors<binary_const, start_const, len_const>(
76
144
                            specific_binary_column, specific_start_column, specific_len_column,
77
144
                            res.get(), input_rows_count);
78
144
                },
_ZZN5doris13SubBinaryUtil18sub_binary_executeERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlT_T0_T1_E_clISt17integral_constantIbLb1EESD_IbLb0EESE_EEDaS8_S9_SA_
Line
Count
Source
74
144
                [&](auto binary_const, auto start_const, auto len_const) {
75
144
                    vectors<binary_const, start_const, len_const>(
76
144
                            specific_binary_column, specific_start_column, specific_len_column,
77
144
                            res.get(), input_rows_count);
78
144
                },
_ZZN5doris13SubBinaryUtil18sub_binary_executeERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlT_T0_T1_E_clISt17integral_constantIbLb1EESE_SD_IbLb0EEEEDaS8_S9_SA_
Line
Count
Source
74
144
                [&](auto binary_const, auto start_const, auto len_const) {
75
144
                    vectors<binary_const, start_const, len_const>(
76
144
                            specific_binary_column, specific_start_column, specific_len_column,
77
144
                            res.get(), input_rows_count);
78
144
                },
Unexecuted instantiation: _ZZN5doris13SubBinaryUtil18sub_binary_executeERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlT_T0_T1_E_clISt17integral_constantIbLb1EESE_SE_EEDaS8_S9_SA_
79
1.01k
                make_bool_variant(col_const[0]), make_bool_variant(col_const[1]),
80
1.01k
                make_bool_variant(col_const[2]));
81
1.01k
        block.get_by_position(result).column = std::move(res);
82
1.01k
    }
83
84
private:
85
    template <bool binary_const, bool start_const, bool len_const>
86
    static void vectors(const ColumnVarbinary* binarys, const ColumnInt32* start,
87
1.01k
                        const ColumnInt32* len, ColumnVarbinary* res, size_t size) {
88
1.01k
        res->get_data().reserve(size);
89
1.01k
        bool has_non_inline_value = false;
90
91
2.27k
        for (size_t i = 0; i < size; ++i) {
92
1.26k
            doris::StringView binary = binarys->get_data()[index_check_const<binary_const>(i)];
93
1.26k
            int binary_size = static_cast<int>(binary.size());
94
95
1.26k
            int start_value = start->get_data()[index_check_const<start_const>(i)];
96
1.26k
            int len_value = len->get_data()[index_check_const<len_const>(i)];
97
98
1.26k
            bool start_out_of_range = (start_value > binary_size) || (start_value < -binary_size);
99
1.26k
            bool len_non_positive = len_value <= 0;
100
1.26k
            bool input_empty = binary_size == 0;
101
102
1.26k
            if (start_out_of_range || len_non_positive || input_empty) {
103
658
                res->insert_default();
104
658
                continue;
105
658
            }
106
602
            int fixed_pos = start_value - 1;
107
602
            if (fixed_pos < 0) {
108
216
                fixed_pos = binary_size + fixed_pos + 1;
109
216
            }
110
602
            int fixed_len = std::min(binary_size - fixed_pos, len_value);
111
602
            const auto result_size = cast_set<uint32_t>(fixed_len);
112
113
602
            has_non_inline_value |= !StringView::isInline(result_size);
114
602
            res->get_data().emplace_back(binary.data() + fixed_pos, result_size);
115
602
        }
116
117
1.01k
        if (has_non_inline_value) {
118
23
            res->add_auxiliary_owners_from(*binarys);
119
23
        }
120
1.01k
    }
_ZN5doris13SubBinaryUtil7vectorsILb0ELb0ELb0EEEvPKNS_15ColumnVarbinaryEPKNS_12ColumnVectorILNS_13PrimitiveTypeE5EEES9_PS2_m
Line
Count
Source
87
146
                        const ColumnInt32* len, ColumnVarbinary* res, size_t size) {
88
146
        res->get_data().reserve(size);
89
146
        bool has_non_inline_value = false;
90
91
542
        for (size_t i = 0; i < size; ++i) {
92
396
            doris::StringView binary = binarys->get_data()[index_check_const<binary_const>(i)];
93
396
            int binary_size = static_cast<int>(binary.size());
94
95
396
            int start_value = start->get_data()[index_check_const<start_const>(i)];
96
396
            int len_value = len->get_data()[index_check_const<len_const>(i)];
97
98
396
            bool start_out_of_range = (start_value > binary_size) || (start_value < -binary_size);
99
396
            bool len_non_positive = len_value <= 0;
100
396
            bool input_empty = binary_size == 0;
101
102
396
            if (start_out_of_range || len_non_positive || input_empty) {
103
226
                res->insert_default();
104
226
                continue;
105
226
            }
106
170
            int fixed_pos = start_value - 1;
107
170
            if (fixed_pos < 0) {
108
72
                fixed_pos = binary_size + fixed_pos + 1;
109
72
            }
110
170
            int fixed_len = std::min(binary_size - fixed_pos, len_value);
111
170
            const auto result_size = cast_set<uint32_t>(fixed_len);
112
113
170
            has_non_inline_value |= !StringView::isInline(result_size);
114
170
            res->get_data().emplace_back(binary.data() + fixed_pos, result_size);
115
170
        }
116
117
146
        if (has_non_inline_value) {
118
5
            res->add_auxiliary_owners_from(*binarys);
119
5
        }
120
146
    }
_ZN5doris13SubBinaryUtil7vectorsILb0ELb0ELb1EEEvPKNS_15ColumnVarbinaryEPKNS_12ColumnVectorILNS_13PrimitiveTypeE5EEES9_PS2_m
Line
Count
Source
87
144
                        const ColumnInt32* len, ColumnVarbinary* res, size_t size) {
88
144
        res->get_data().reserve(size);
89
144
        bool has_non_inline_value = false;
90
91
288
        for (size_t i = 0; i < size; ++i) {
92
144
            doris::StringView binary = binarys->get_data()[index_check_const<binary_const>(i)];
93
144
            int binary_size = static_cast<int>(binary.size());
94
95
144
            int start_value = start->get_data()[index_check_const<start_const>(i)];
96
144
            int len_value = len->get_data()[index_check_const<len_const>(i)];
97
98
144
            bool start_out_of_range = (start_value > binary_size) || (start_value < -binary_size);
99
144
            bool len_non_positive = len_value <= 0;
100
144
            bool input_empty = binary_size == 0;
101
102
144
            if (start_out_of_range || len_non_positive || input_empty) {
103
72
                res->insert_default();
104
72
                continue;
105
72
            }
106
72
            int fixed_pos = start_value - 1;
107
72
            if (fixed_pos < 0) {
108
24
                fixed_pos = binary_size + fixed_pos + 1;
109
24
            }
110
72
            int fixed_len = std::min(binary_size - fixed_pos, len_value);
111
72
            const auto result_size = cast_set<uint32_t>(fixed_len);
112
113
72
            has_non_inline_value |= !StringView::isInline(result_size);
114
72
            res->get_data().emplace_back(binary.data() + fixed_pos, result_size);
115
72
        }
116
117
144
        if (has_non_inline_value) {
118
3
            res->add_auxiliary_owners_from(*binarys);
119
3
        }
120
144
    }
_ZN5doris13SubBinaryUtil7vectorsILb0ELb1ELb0EEEvPKNS_15ColumnVarbinaryEPKNS_12ColumnVectorILNS_13PrimitiveTypeE5EEES9_PS2_m
Line
Count
Source
87
144
                        const ColumnInt32* len, ColumnVarbinary* res, size_t size) {
88
144
        res->get_data().reserve(size);
89
144
        bool has_non_inline_value = false;
90
91
288
        for (size_t i = 0; i < size; ++i) {
92
144
            doris::StringView binary = binarys->get_data()[index_check_const<binary_const>(i)];
93
144
            int binary_size = static_cast<int>(binary.size());
94
95
144
            int start_value = start->get_data()[index_check_const<start_const>(i)];
96
144
            int len_value = len->get_data()[index_check_const<len_const>(i)];
97
98
144
            bool start_out_of_range = (start_value > binary_size) || (start_value < -binary_size);
99
144
            bool len_non_positive = len_value <= 0;
100
144
            bool input_empty = binary_size == 0;
101
102
144
            if (start_out_of_range || len_non_positive || input_empty) {
103
72
                res->insert_default();
104
72
                continue;
105
72
            }
106
72
            int fixed_pos = start_value - 1;
107
72
            if (fixed_pos < 0) {
108
24
                fixed_pos = binary_size + fixed_pos + 1;
109
24
            }
110
72
            int fixed_len = std::min(binary_size - fixed_pos, len_value);
111
72
            const auto result_size = cast_set<uint32_t>(fixed_len);
112
113
72
            has_non_inline_value |= !StringView::isInline(result_size);
114
72
            res->get_data().emplace_back(binary.data() + fixed_pos, result_size);
115
72
        }
116
117
144
        if (has_non_inline_value) {
118
3
            res->add_auxiliary_owners_from(*binarys);
119
3
        }
120
144
    }
_ZN5doris13SubBinaryUtil7vectorsILb0ELb1ELb1EEEvPKNS_15ColumnVarbinaryEPKNS_12ColumnVectorILNS_13PrimitiveTypeE5EEES9_PS2_m
Line
Count
Source
87
144
                        const ColumnInt32* len, ColumnVarbinary* res, size_t size) {
88
144
        res->get_data().reserve(size);
89
144
        bool has_non_inline_value = false;
90
91
288
        for (size_t i = 0; i < size; ++i) {
92
144
            doris::StringView binary = binarys->get_data()[index_check_const<binary_const>(i)];
93
144
            int binary_size = static_cast<int>(binary.size());
94
95
144
            int start_value = start->get_data()[index_check_const<start_const>(i)];
96
144
            int len_value = len->get_data()[index_check_const<len_const>(i)];
97
98
144
            bool start_out_of_range = (start_value > binary_size) || (start_value < -binary_size);
99
144
            bool len_non_positive = len_value <= 0;
100
144
            bool input_empty = binary_size == 0;
101
102
144
            if (start_out_of_range || len_non_positive || input_empty) {
103
72
                res->insert_default();
104
72
                continue;
105
72
            }
106
72
            int fixed_pos = start_value - 1;
107
72
            if (fixed_pos < 0) {
108
24
                fixed_pos = binary_size + fixed_pos + 1;
109
24
            }
110
72
            int fixed_len = std::min(binary_size - fixed_pos, len_value);
111
72
            const auto result_size = cast_set<uint32_t>(fixed_len);
112
113
72
            has_non_inline_value |= !StringView::isInline(result_size);
114
72
            res->get_data().emplace_back(binary.data() + fixed_pos, result_size);
115
72
        }
116
117
144
        if (has_non_inline_value) {
118
3
            res->add_auxiliary_owners_from(*binarys);
119
3
        }
120
144
    }
_ZN5doris13SubBinaryUtil7vectorsILb1ELb0ELb0EEEvPKNS_15ColumnVarbinaryEPKNS_12ColumnVectorILNS_13PrimitiveTypeE5EEES9_PS2_m
Line
Count
Source
87
144
                        const ColumnInt32* len, ColumnVarbinary* res, size_t size) {
88
144
        res->get_data().reserve(size);
89
144
        bool has_non_inline_value = false;
90
91
288
        for (size_t i = 0; i < size; ++i) {
92
144
            doris::StringView binary = binarys->get_data()[index_check_const<binary_const>(i)];
93
144
            int binary_size = static_cast<int>(binary.size());
94
95
144
            int start_value = start->get_data()[index_check_const<start_const>(i)];
96
144
            int len_value = len->get_data()[index_check_const<len_const>(i)];
97
98
144
            bool start_out_of_range = (start_value > binary_size) || (start_value < -binary_size);
99
144
            bool len_non_positive = len_value <= 0;
100
144
            bool input_empty = binary_size == 0;
101
102
144
            if (start_out_of_range || len_non_positive || input_empty) {
103
72
                res->insert_default();
104
72
                continue;
105
72
            }
106
72
            int fixed_pos = start_value - 1;
107
72
            if (fixed_pos < 0) {
108
24
                fixed_pos = binary_size + fixed_pos + 1;
109
24
            }
110
72
            int fixed_len = std::min(binary_size - fixed_pos, len_value);
111
72
            const auto result_size = cast_set<uint32_t>(fixed_len);
112
113
72
            has_non_inline_value |= !StringView::isInline(result_size);
114
72
            res->get_data().emplace_back(binary.data() + fixed_pos, result_size);
115
72
        }
116
117
144
        if (has_non_inline_value) {
118
3
            res->add_auxiliary_owners_from(*binarys);
119
3
        }
120
144
    }
_ZN5doris13SubBinaryUtil7vectorsILb1ELb0ELb1EEEvPKNS_15ColumnVarbinaryEPKNS_12ColumnVectorILNS_13PrimitiveTypeE5EEES9_PS2_m
Line
Count
Source
87
144
                        const ColumnInt32* len, ColumnVarbinary* res, size_t size) {
88
144
        res->get_data().reserve(size);
89
144
        bool has_non_inline_value = false;
90
91
288
        for (size_t i = 0; i < size; ++i) {
92
144
            doris::StringView binary = binarys->get_data()[index_check_const<binary_const>(i)];
93
144
            int binary_size = static_cast<int>(binary.size());
94
95
144
            int start_value = start->get_data()[index_check_const<start_const>(i)];
96
144
            int len_value = len->get_data()[index_check_const<len_const>(i)];
97
98
144
            bool start_out_of_range = (start_value > binary_size) || (start_value < -binary_size);
99
144
            bool len_non_positive = len_value <= 0;
100
144
            bool input_empty = binary_size == 0;
101
102
144
            if (start_out_of_range || len_non_positive || input_empty) {
103
72
                res->insert_default();
104
72
                continue;
105
72
            }
106
72
            int fixed_pos = start_value - 1;
107
72
            if (fixed_pos < 0) {
108
24
                fixed_pos = binary_size + fixed_pos + 1;
109
24
            }
110
72
            int fixed_len = std::min(binary_size - fixed_pos, len_value);
111
72
            const auto result_size = cast_set<uint32_t>(fixed_len);
112
113
72
            has_non_inline_value |= !StringView::isInline(result_size);
114
72
            res->get_data().emplace_back(binary.data() + fixed_pos, result_size);
115
72
        }
116
117
144
        if (has_non_inline_value) {
118
3
            res->add_auxiliary_owners_from(*binarys);
119
3
        }
120
144
    }
_ZN5doris13SubBinaryUtil7vectorsILb1ELb1ELb0EEEvPKNS_15ColumnVarbinaryEPKNS_12ColumnVectorILNS_13PrimitiveTypeE5EEES9_PS2_m
Line
Count
Source
87
144
                        const ColumnInt32* len, ColumnVarbinary* res, size_t size) {
88
144
        res->get_data().reserve(size);
89
144
        bool has_non_inline_value = false;
90
91
288
        for (size_t i = 0; i < size; ++i) {
92
144
            doris::StringView binary = binarys->get_data()[index_check_const<binary_const>(i)];
93
144
            int binary_size = static_cast<int>(binary.size());
94
95
144
            int start_value = start->get_data()[index_check_const<start_const>(i)];
96
144
            int len_value = len->get_data()[index_check_const<len_const>(i)];
97
98
144
            bool start_out_of_range = (start_value > binary_size) || (start_value < -binary_size);
99
144
            bool len_non_positive = len_value <= 0;
100
144
            bool input_empty = binary_size == 0;
101
102
144
            if (start_out_of_range || len_non_positive || input_empty) {
103
72
                res->insert_default();
104
72
                continue;
105
72
            }
106
72
            int fixed_pos = start_value - 1;
107
72
            if (fixed_pos < 0) {
108
24
                fixed_pos = binary_size + fixed_pos + 1;
109
24
            }
110
72
            int fixed_len = std::min(binary_size - fixed_pos, len_value);
111
72
            const auto result_size = cast_set<uint32_t>(fixed_len);
112
113
72
            has_non_inline_value |= !StringView::isInline(result_size);
114
72
            res->get_data().emplace_back(binary.data() + fixed_pos, result_size);
115
72
        }
116
117
144
        if (has_non_inline_value) {
118
3
            res->add_auxiliary_owners_from(*binarys);
119
3
        }
120
144
    }
Unexecuted instantiation: _ZN5doris13SubBinaryUtil7vectorsILb1ELb1ELb1EEEvPKNS_15ColumnVarbinaryEPKNS_12ColumnVectorILNS_13PrimitiveTypeE5EEES9_PS2_m
121
};
122
123
} // namespace doris