Coverage Report

Created: 2026-03-16 12:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/function_interval.cpp
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
#include <algorithm>
19
#include <cstddef>
20
#include <cstdint>
21
#include <limits>
22
#include <memory>
23
#include <vector>
24
25
#include "common/status.h"
26
#include "core/assert_cast.h"
27
#include "core/block/block.h"
28
#include "core/block/column_numbers.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_vector.h"
34
#include "core/data_type/data_type.h"
35
#include "core/data_type/data_type_number.h"
36
#include "core/data_type/define_primitive_type.h"
37
#include "core/data_type/primitive_type.h"
38
#include "core/types.h"
39
#include "exec/common/util.hpp"
40
#include "exprs/function/function.h"
41
#include "exprs/function/function_needs_to_handle_null.h"
42
#include "exprs/function/simple_function_factory.h"
43
44
namespace doris {
45
class FunctionInterval : public IFunction {
46
public:
47
    static constexpr auto name = "interval";
48
24
    static FunctionPtr create() { return std::make_shared<FunctionInterval>(); }
49
0
    String get_name() const override { return name; }
50
16
    bool is_variadic() const override { return true; }
51
0
    size_t get_number_of_arguments() const override { return 0; }
52
30
    bool use_default_implementation_for_nulls() const override { return false; }
53
15
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
54
15
        return std::make_shared<DataTypeInt32>();
55
15
    }
56
57
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
58
15
                        uint32_t result, size_t input_rows_count) const override {
59
15
        auto res_col = ColumnInt32::create();
60
61
15
        const size_t arg_size = arguments.size();
62
15
        std::vector<ColumnPtr> arg_cols(arg_size);
63
15
        std::vector<uint8_t> is_const(arg_size);
64
15
        std::vector<size_t> param_idx(arg_size - 1);
65
15
        bool all_const = true;
66
97
        for (int i = 0; i < arg_size; ++i) {
67
82
            is_const[i] = is_column_const(*block.get_by_position(arguments[i]).column);
68
82
            if (i != 0) {
69
67
                param_idx[i - 1] = i;
70
67
                all_const = all_const & is_const[i];
71
67
            }
72
82
        }
73
15
        arg_cols[0] = is_const[0] ? assert_cast<const ColumnConst&>(
74
2
                                            *block.get_by_position(arguments[0]).column)
75
2
                                            .get_data_column_ptr()
76
15
                                  : block.get_by_position(arguments[0]).column;
77
15
        default_preprocess_parameter_columns(arg_cols.data(),
78
15
                                             reinterpret_cast<const bool*>(is_const.data()),
79
15
                                             param_idx, block, arguments);
80
82
        for (int i = 1; i < arg_size; ++i) {
81
67
            arg_cols[i] = remove_nullable(arg_cols[i]);
82
67
        }
83
84
15
        const NullMap* compare_null_map = VectorizedUtils::get_null_map(arg_cols[0]);
85
15
        arg_cols[0] = remove_nullable(arg_cols[0]);
86
15
        const auto& compare_data = assert_cast<const ColumnInt64&>(*arg_cols[0]).get_data();
87
120
        for (int row = 0; row < input_rows_count; ++row) {
88
105
            const size_t compare_idx = index_check_const(row, is_const[0]);
89
105
            const size_t arr_idx = all_const ? 0 : row;
90
105
            if (compare_null_map && (*compare_null_map)[compare_idx]) {
91
0
                res_col->insert_value(-1);
92
0
                continue;
93
0
            }
94
95
105
            res_col->insert_value(compute_interval(compare_data[compare_idx], arg_cols, is_const,
96
105
                                                   arr_idx, arg_size));
97
105
        }
98
15
        block.get_by_position(result).column = std::move(res_col);
99
15
        return Status::OK();
100
15
    }
101
102
private:
103
    int32_t compute_interval(int64_t compare_val, const std::vector<ColumnPtr>& arg_cols,
104
                             std::vector<uint8_t>& is_const, size_t row_idx,
105
105
                             size_t arg_size) const {
106
105
        size_t l = 1, r = arg_size;
107
356
        while (l < r) {
108
251
            size_t mid = (l + r) >> 1;
109
251
            const auto mid_val =
110
251
                    assert_cast<const ColumnInt64&>(*arg_cols[mid]).get_data()[row_idx];
111
251
            if (mid_val <= compare_val) {
112
139
                l = mid + 1;
113
139
            } else {
114
112
                r = mid;
115
112
            }
116
251
        }
117
105
        return static_cast<int32_t>(l - 1);
118
105
    }
119
};
120
121
8
void register_function_interval(SimpleFunctionFactory& factory) {
122
8
    factory.register_function<FunctionInterval>();
123
8
}
124
125
} // namespace doris