Coverage Report

Created: 2026-03-12 17:15

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
8
    static FunctionPtr create() { return std::make_shared<FunctionInterval>(); }
49
0
    String get_name() const override { return name; }
50
1
    bool is_variadic() const override { return true; }
51
0
    size_t get_number_of_arguments() const override { return 0; }
52
0
    bool use_default_implementation_for_nulls() const override { return false; }
53
0
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
54
0
        return std::make_shared<DataTypeInt32>();
55
0
    }
56
57
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
58
0
                        uint32_t result, size_t input_rows_count) const override {
59
0
        auto res_col = ColumnInt32::create();
60
61
0
        const size_t arg_size = arguments.size();
62
0
        std::vector<ColumnPtr> arg_cols(arg_size);
63
0
        std::vector<uint8_t> is_const(arg_size);
64
0
        std::vector<size_t> param_idx(arg_size - 1);
65
0
        bool all_const = true;
66
0
        for (int i = 0; i < arg_size; ++i) {
67
0
            is_const[i] = is_column_const(*block.get_by_position(arguments[i]).column);
68
0
            if (i != 0) {
69
0
                param_idx[i - 1] = i;
70
0
                all_const = all_const & is_const[i];
71
0
            }
72
0
        }
73
0
        arg_cols[0] = is_const[0] ? assert_cast<const ColumnConst&>(
74
0
                                            *block.get_by_position(arguments[0]).column)
75
0
                                            .get_data_column_ptr()
76
0
                                  : block.get_by_position(arguments[0]).column;
77
0
        default_preprocess_parameter_columns(arg_cols.data(),
78
0
                                             reinterpret_cast<const bool*>(is_const.data()),
79
0
                                             param_idx, block, arguments);
80
0
        for (int i = 1; i < arg_size; ++i) {
81
0
            arg_cols[i] = remove_nullable(arg_cols[i]);
82
0
        }
83
84
0
        const NullMap* compare_null_map = VectorizedUtils::get_null_map(arg_cols[0]);
85
0
        arg_cols[0] = remove_nullable(arg_cols[0]);
86
0
        const auto& compare_data = assert_cast<const ColumnInt64&>(*arg_cols[0]).get_data();
87
0
        for (int row = 0; row < input_rows_count; ++row) {
88
0
            const size_t compare_idx = index_check_const(row, is_const[0]);
89
0
            const size_t arr_idx = all_const ? 0 : row;
90
0
            if (compare_null_map && (*compare_null_map)[compare_idx]) {
91
0
                res_col->insert_value(-1);
92
0
                continue;
93
0
            }
94
95
0
            res_col->insert_value(compute_interval(compare_data[compare_idx], arg_cols, is_const,
96
0
                                                   arr_idx, arg_size));
97
0
        }
98
0
        block.get_by_position(result).column = std::move(res_col);
99
0
        return Status::OK();
100
0
    }
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
0
                             size_t arg_size) const {
106
0
        size_t l = 1, r = arg_size;
107
0
        while (l < r) {
108
0
            size_t mid = (l + r) >> 1;
109
0
            const auto mid_val =
110
0
                    assert_cast<const ColumnInt64&>(*arg_cols[mid]).get_data()[row_idx];
111
0
            if (mid_val <= compare_val) {
112
0
                l = mid + 1;
113
0
            } else {
114
0
                r = mid;
115
0
            }
116
0
        }
117
0
        return static_cast<int32_t>(l - 1);
118
0
    }
119
};
120
121
7
void register_function_interval(SimpleFunctionFactory& factory) {
122
7
    factory.register_function<FunctionInterval>();
123
7
}
124
125
} // namespace doris