Coverage Report

Created: 2026-04-10 18:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/array/function_array_distance.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 <faiss/impl/platform_macros.h>
21
#include <faiss/utils/distances.h>
22
#include <gen_cpp/Types_types.h>
23
24
#include <optional>
25
26
#include "common/exception.h"
27
#include "common/status.h"
28
#include "core/assert_cast.h"
29
#include "core/column/column.h"
30
#include "core/column/column_array.h"
31
#include "core/column/column_const.h"
32
#include "core/column/column_nullable.h"
33
#include "core/data_type/data_type.h"
34
#include "core/data_type/data_type_array.h"
35
#include "core/data_type/data_type_nullable.h"
36
#include "core/data_type/data_type_number.h"
37
#include "core/data_type/primitive_type.h"
38
#include "core/types.h"
39
#include "exec/common/util.hpp"
40
#include "exprs/function/array/function_array_utils.h"
41
#include "exprs/function/function.h"
42
43
namespace doris {
44
45
class L1Distance {
46
public:
47
    static constexpr auto name = "l1_distance";
48
0
    static float distance(const float* x, const float* y, size_t d) {
49
0
        return faiss::fvec_L1(x, y, d);
50
0
    }
51
};
52
53
class L2Distance {
54
public:
55
    static constexpr auto name = "l2_distance";
56
0
    static float distance(const float* x, const float* y, size_t d) {
57
0
        return std::sqrt(faiss::fvec_L2sqr(x, y, d));
58
0
    }
59
};
60
61
class InnerProduct {
62
public:
63
    static constexpr auto name = "inner_product";
64
0
    static float distance(const float* x, const float* y, size_t d) {
65
0
        return faiss::fvec_inner_product(x, y, d);
66
0
    }
67
};
68
69
class CosineDistance {
70
public:
71
    static constexpr auto name = "cosine_distance";
72
    static float distance(const float* x, const float* y, size_t d);
73
};
74
75
class CosineSimilarity {
76
public:
77
    static constexpr auto name = "cosine_similarity";
78
    static float distance(const float* x, const float* y, size_t d);
79
};
80
81
class L2DistanceApproximate : public L2Distance {
82
public:
83
    static constexpr auto name = "l2_distance_approximate";
84
};
85
86
class InnerProductApproximate : public InnerProduct {
87
public:
88
    static constexpr auto name = "inner_product_approximate";
89
};
90
91
template <typename DistanceImpl>
92
class FunctionArrayDistance : public IFunction {
93
public:
94
    using DataType = PrimitiveTypeTraits<TYPE_FLOAT>::DataType;
95
    using ColumnType = PrimitiveTypeTraits<TYPE_FLOAT>::ColumnType;
96
97
    static constexpr auto name = DistanceImpl::name;
98
47
    String get_name() const override { return name; }
_ZNK5doris21FunctionArrayDistanceINS_10L1DistanceEE8get_nameB5cxx11Ev
Line
Count
Source
98
1
    String get_name() const override { return name; }
_ZNK5doris21FunctionArrayDistanceINS_10L2DistanceEE8get_nameB5cxx11Ev
Line
Count
Source
98
1
    String get_name() const override { return name; }
_ZNK5doris21FunctionArrayDistanceINS_14CosineDistanceEE8get_nameB5cxx11Ev
Line
Count
Source
98
1
    String get_name() const override { return name; }
_ZNK5doris21FunctionArrayDistanceINS_16CosineSimilarityEE8get_nameB5cxx11Ev
Line
Count
Source
98
41
    String get_name() const override { return name; }
_ZNK5doris21FunctionArrayDistanceINS_12InnerProductEE8get_nameB5cxx11Ev
Line
Count
Source
98
1
    String get_name() const override { return name; }
_ZNK5doris21FunctionArrayDistanceINS_21L2DistanceApproximateEE8get_nameB5cxx11Ev
Line
Count
Source
98
1
    String get_name() const override { return name; }
_ZNK5doris21FunctionArrayDistanceINS_23InnerProductApproximateEE8get_nameB5cxx11Ev
Line
Count
Source
98
1
    String get_name() const override { return name; }
99
33
    static FunctionPtr create() { return std::make_shared<FunctionArrayDistance<DistanceImpl>>(); }
_ZN5doris21FunctionArrayDistanceINS_10L1DistanceEE6createEv
Line
Count
Source
99
2
    static FunctionPtr create() { return std::make_shared<FunctionArrayDistance<DistanceImpl>>(); }
_ZN5doris21FunctionArrayDistanceINS_10L2DistanceEE6createEv
Line
Count
Source
99
2
    static FunctionPtr create() { return std::make_shared<FunctionArrayDistance<DistanceImpl>>(); }
_ZN5doris21FunctionArrayDistanceINS_14CosineDistanceEE6createEv
Line
Count
Source
99
2
    static FunctionPtr create() { return std::make_shared<FunctionArrayDistance<DistanceImpl>>(); }
_ZN5doris21FunctionArrayDistanceINS_16CosineSimilarityEE6createEv
Line
Count
Source
99
12
    static FunctionPtr create() { return std::make_shared<FunctionArrayDistance<DistanceImpl>>(); }
_ZN5doris21FunctionArrayDistanceINS_12InnerProductEE6createEv
Line
Count
Source
99
2
    static FunctionPtr create() { return std::make_shared<FunctionArrayDistance<DistanceImpl>>(); }
_ZN5doris21FunctionArrayDistanceINS_21L2DistanceApproximateEE6createEv
Line
Count
Source
99
11
    static FunctionPtr create() { return std::make_shared<FunctionArrayDistance<DistanceImpl>>(); }
_ZN5doris21FunctionArrayDistanceINS_23InnerProductApproximateEE6createEv
Line
Count
Source
99
2
    static FunctionPtr create() { return std::make_shared<FunctionArrayDistance<DistanceImpl>>(); }
100
19
    size_t get_number_of_arguments() const override { return 2; }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_10L1DistanceEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_10L2DistanceEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_14CosineDistanceEE23get_number_of_argumentsEv
_ZNK5doris21FunctionArrayDistanceINS_16CosineSimilarityEE23get_number_of_argumentsEv
Line
Count
Source
100
10
    size_t get_number_of_arguments() const override { return 2; }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_12InnerProductEE23get_number_of_argumentsEv
_ZNK5doris21FunctionArrayDistanceINS_21L2DistanceApproximateEE23get_number_of_argumentsEv
Line
Count
Source
100
9
    size_t get_number_of_arguments() const override { return 2; }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_23InnerProductApproximateEE23get_number_of_argumentsEv
101
102
19
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
103
19
        if (arguments.size() != 2) {
104
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT, "Invalid number of arguments");
105
0
        }
106
107
        // primitive_type of Nullable is its nested type.
108
19
        if (arguments[0]->get_primitive_type() != TYPE_ARRAY ||
109
19
            arguments[1]->get_primitive_type() != TYPE_ARRAY) {
110
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
111
0
                                   "Arguments for function {} must be arrays", get_name());
112
0
        }
113
114
19
        return std::make_shared<DataTypeFloat32>();
115
19
    }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_10L1DistanceEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_10L2DistanceEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_14CosineDistanceEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
_ZNK5doris21FunctionArrayDistanceINS_16CosineSimilarityEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
102
10
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
103
10
        if (arguments.size() != 2) {
104
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT, "Invalid number of arguments");
105
0
        }
106
107
        // primitive_type of Nullable is its nested type.
108
10
        if (arguments[0]->get_primitive_type() != TYPE_ARRAY ||
109
10
            arguments[1]->get_primitive_type() != TYPE_ARRAY) {
110
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
111
0
                                   "Arguments for function {} must be arrays", get_name());
112
0
        }
113
114
10
        return std::make_shared<DataTypeFloat32>();
115
10
    }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_12InnerProductEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
_ZNK5doris21FunctionArrayDistanceINS_21L2DistanceApproximateEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
102
9
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
103
9
        if (arguments.size() != 2) {
104
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT, "Invalid number of arguments");
105
0
        }
106
107
        // primitive_type of Nullable is its nested type.
108
9
        if (arguments[0]->get_primitive_type() != TYPE_ARRAY ||
109
9
            arguments[1]->get_primitive_type() != TYPE_ARRAY) {
110
0
            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
111
0
                                   "Arguments for function {} must be arrays", get_name());
112
0
        }
113
114
9
        return std::make_shared<DataTypeFloat32>();
115
9
    }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_23InnerProductApproximateEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
116
117
    // All array distance functions has always not nullable return type.
118
    // We want to make sure throw exception if input columns contain NULL.
119
29
    bool use_default_implementation_for_nulls() const override { return false; }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_10L1DistanceEE36use_default_implementation_for_nullsEv
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_10L2DistanceEE36use_default_implementation_for_nullsEv
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_14CosineDistanceEE36use_default_implementation_for_nullsEv
_ZNK5doris21FunctionArrayDistanceINS_16CosineSimilarityEE36use_default_implementation_for_nullsEv
Line
Count
Source
119
20
    bool use_default_implementation_for_nulls() const override { return false; }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_12InnerProductEE36use_default_implementation_for_nullsEv
_ZNK5doris21FunctionArrayDistanceINS_21L2DistanceApproximateEE36use_default_implementation_for_nullsEv
Line
Count
Source
119
9
    bool use_default_implementation_for_nulls() const override { return false; }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_23InnerProductApproximateEE36use_default_implementation_for_nullsEv
120
121
    // Extract the ColumnArray from a column, unwrapping Nullable if present.
122
    // Validates that no NULL values exist.
123
    static const ColumnArray* _extract_array_column(const IColumn* col, const char* arg_name,
124
20
                                                    const String& func_name) {
125
20
        if (col->is_nullable()) {
126
20
            if (col->has_null()) {
127
0
                throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
128
0
                                       "{} for function {} cannot be null", arg_name, func_name);
129
0
            }
130
20
            auto nullable = assert_cast<const ColumnNullable*>(col);
131
20
            return assert_cast<const ColumnArray*>(nullable->get_nested_column_ptr().get());
132
20
        }
133
0
        return assert_cast<const ColumnArray*>(col);
134
20
    }
Unexecuted instantiation: _ZN5doris21FunctionArrayDistanceINS_10L1DistanceEE21_extract_array_columnEPKNS_7IColumnEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris21FunctionArrayDistanceINS_10L2DistanceEE21_extract_array_columnEPKNS_7IColumnEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris21FunctionArrayDistanceINS_14CosineDistanceEE21_extract_array_columnEPKNS_7IColumnEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZN5doris21FunctionArrayDistanceINS_16CosineSimilarityEE21_extract_array_columnEPKNS_7IColumnEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
124
20
                                                    const String& func_name) {
125
20
        if (col->is_nullable()) {
126
20
            if (col->has_null()) {
127
0
                throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
128
0
                                       "{} for function {} cannot be null", arg_name, func_name);
129
0
            }
130
20
            auto nullable = assert_cast<const ColumnNullable*>(col);
131
20
            return assert_cast<const ColumnArray*>(nullable->get_nested_column_ptr().get());
132
20
        }
133
0
        return assert_cast<const ColumnArray*>(col);
134
20
    }
Unexecuted instantiation: _ZN5doris21FunctionArrayDistanceINS_12InnerProductEE21_extract_array_columnEPKNS_7IColumnEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris21FunctionArrayDistanceINS_21L2DistanceApproximateEE21_extract_array_columnEPKNS_7IColumnEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris21FunctionArrayDistanceINS_23InnerProductApproximateEE21_extract_array_columnEPKNS_7IColumnEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
135
136
    // Extract the ColumnFloat32 data from an array column, unwrapping Nullable if present.
137
    // Validates that no NULL elements exist within the array.
138
    static const ColumnFloat32* _extract_float_data(const ColumnArray* arr, const char* arg_name,
139
20
                                                    const String& func_name) {
140
20
        if (arr->get_data_ptr()->is_nullable()) {
141
20
            if (arr->get_data_ptr()->has_null()) {
142
0
                throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
143
0
                                       "{} for function {} cannot have null", arg_name, func_name);
144
0
            }
145
20
            auto nullable = assert_cast<const ColumnNullable*>(arr->get_data_ptr().get());
146
20
            return assert_cast<const ColumnFloat32*>(nullable->get_nested_column_ptr().get());
147
20
        }
148
0
        return assert_cast<const ColumnFloat32*>(arr->get_data_ptr().get());
149
20
    }
Unexecuted instantiation: _ZN5doris21FunctionArrayDistanceINS_10L1DistanceEE19_extract_float_dataEPKNS_11ColumnArrayEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris21FunctionArrayDistanceINS_10L2DistanceEE19_extract_float_dataEPKNS_11ColumnArrayEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris21FunctionArrayDistanceINS_14CosineDistanceEE19_extract_float_dataEPKNS_11ColumnArrayEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZN5doris21FunctionArrayDistanceINS_16CosineSimilarityEE19_extract_float_dataEPKNS_11ColumnArrayEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
139
20
                                                    const String& func_name) {
140
20
        if (arr->get_data_ptr()->is_nullable()) {
141
20
            if (arr->get_data_ptr()->has_null()) {
142
0
                throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
143
0
                                       "{} for function {} cannot have null", arg_name, func_name);
144
0
            }
145
20
            auto nullable = assert_cast<const ColumnNullable*>(arr->get_data_ptr().get());
146
20
            return assert_cast<const ColumnFloat32*>(nullable->get_nested_column_ptr().get());
147
20
        }
148
0
        return assert_cast<const ColumnFloat32*>(arr->get_data_ptr().get());
149
20
    }
Unexecuted instantiation: _ZN5doris21FunctionArrayDistanceINS_12InnerProductEE19_extract_float_dataEPKNS_11ColumnArrayEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris21FunctionArrayDistanceINS_21L2DistanceApproximateEE19_extract_float_dataEPKNS_11ColumnArrayEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris21FunctionArrayDistanceINS_23InnerProductApproximateEE19_extract_float_dataEPKNS_11ColumnArrayEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
150
151
    // Holds the extracted float data pointer and dimension for a const array argument,
152
    // avoiding repeated per-row extraction.
153
    struct ConstArrayInfo {
154
        const float* data = nullptr;
155
        ssize_t dim = 0;
156
    };
157
158
    // Try to extract const array info from a column. If the column is ColumnConst,
159
    // extract the float data pointer and dimension once; otherwise return nullopt.
160
    std::optional<ConstArrayInfo> _try_extract_const(const ColumnPtr& col,
161
20
                                                     const char* arg_name) const {
162
20
        if (!is_column_const(*col)) {
163
20
            return std::nullopt;
164
20
        }
165
0
        auto const_col = assert_cast<const ColumnConst*>(col.get());
166
0
        const IColumn* inner = const_col->get_data_column_ptr().get();
167
0
        const ColumnArray* arr = _extract_array_column(inner, arg_name, get_name());
168
0
        const ColumnFloat32* float_col = _extract_float_data(arr, arg_name, get_name());
169
0
        ssize_t dim = static_cast<ssize_t>(float_col->size());
170
0
        return ConstArrayInfo {float_col->get_data().data(), dim};
171
20
    }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_10L1DistanceEE18_try_extract_constERKNS_3COWINS_7IColumnEE13immutable_ptrIS4_EEPKc
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_10L2DistanceEE18_try_extract_constERKNS_3COWINS_7IColumnEE13immutable_ptrIS4_EEPKc
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_14CosineDistanceEE18_try_extract_constERKNS_3COWINS_7IColumnEE13immutable_ptrIS4_EEPKc
_ZNK5doris21FunctionArrayDistanceINS_16CosineSimilarityEE18_try_extract_constERKNS_3COWINS_7IColumnEE13immutable_ptrIS4_EEPKc
Line
Count
Source
161
20
                                                     const char* arg_name) const {
162
20
        if (!is_column_const(*col)) {
163
20
            return std::nullopt;
164
20
        }
165
0
        auto const_col = assert_cast<const ColumnConst*>(col.get());
166
0
        const IColumn* inner = const_col->get_data_column_ptr().get();
167
0
        const ColumnArray* arr = _extract_array_column(inner, arg_name, get_name());
168
0
        const ColumnFloat32* float_col = _extract_float_data(arr, arg_name, get_name());
169
0
        ssize_t dim = static_cast<ssize_t>(float_col->size());
170
0
        return ConstArrayInfo {float_col->get_data().data(), dim};
171
20
    }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_12InnerProductEE18_try_extract_constERKNS_3COWINS_7IColumnEE13immutable_ptrIS4_EEPKc
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_21L2DistanceApproximateEE18_try_extract_constERKNS_3COWINS_7IColumnEE13immutable_ptrIS4_EEPKc
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_23InnerProductApproximateEE18_try_extract_constERKNS_3COWINS_7IColumnEE13immutable_ptrIS4_EEPKc
172
173
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
174
10
                        uint32_t result, size_t input_rows_count) const override {
175
10
        const auto& arg1 = block.get_by_position(arguments[0]);
176
10
        const auto& arg2 = block.get_by_position(arguments[1]);
177
178
        // Try to handle const columns without expanding them.
179
10
        auto const_info1 = _try_extract_const(arg1.column, "First argument");
180
10
        auto const_info2 = _try_extract_const(arg2.column, "Second argument");
181
182
        // For non-const columns, expand and extract normally.
183
10
        ColumnPtr materialized_col1, materialized_col2;
184
10
        const ColumnArray* arr1 = nullptr;
185
10
        const ColumnArray* arr2 = nullptr;
186
10
        const ColumnFloat32* float1 = nullptr;
187
10
        const ColumnFloat32* float2 = nullptr;
188
10
        const ColumnOffset64* offset1 = nullptr;
189
10
        const ColumnOffset64* offset2 = nullptr;
190
10
        const IColumn::Offsets64* offsets_data1 = nullptr;
191
10
        const IColumn::Offsets64* offsets_data2 = nullptr;
192
10
        const float* float_data1 = nullptr;
193
10
        const float* float_data2 = nullptr;
194
195
10
        if (!const_info1) {
196
10
            materialized_col1 = arg1.column->convert_to_full_column_if_const();
197
10
            arr1 = _extract_array_column(materialized_col1.get(), "First argument", get_name());
198
10
            float1 = _extract_float_data(arr1, "First argument", get_name());
199
10
            offset1 = assert_cast<const ColumnArray::ColumnOffsets*>(arr1->get_offsets_ptr().get());
200
10
            offsets_data1 = &offset1->get_data();
201
10
            float_data1 = float1->get_data().data();
202
10
        }
203
204
10
        if (!const_info2) {
205
10
            materialized_col2 = arg2.column->convert_to_full_column_if_const();
206
10
            arr2 = _extract_array_column(materialized_col2.get(), "Second argument", get_name());
207
10
            float2 = _extract_float_data(arr2, "Second argument", get_name());
208
10
            offset2 = assert_cast<const ColumnArray::ColumnOffsets*>(arr2->get_offsets_ptr().get());
209
10
            offsets_data2 = &offset2->get_data();
210
10
            float_data2 = float2->get_data().data();
211
10
        }
212
213
        // prepare return data
214
10
        auto dst = ColumnType::create(input_rows_count);
215
10
        auto& dst_data = dst->get_data();
216
217
22
        for (size_t row = 0; row < input_rows_count; ++row) {
218
12
            const float* data_ptr1;
219
12
            const float* data_ptr2;
220
12
            ssize_t size1, size2;
221
12
            const auto idx = static_cast<ssize_t>(row);
222
223
12
            if (const_info1) {
224
0
                data_ptr1 = const_info1->data;
225
0
                size1 = const_info1->dim;
226
12
            } else {
227
                // -1 is valid for PaddedPODArray-backed offsets.
228
12
                const auto prev_offset1 = (*offsets_data1)[idx - 1];
229
12
                size1 = (*offsets_data1)[idx] - prev_offset1;
230
12
                data_ptr1 = float_data1 + prev_offset1;
231
12
            }
232
233
12
            if (const_info2) {
234
0
                data_ptr2 = const_info2->data;
235
0
                size2 = const_info2->dim;
236
12
            } else {
237
12
                const auto prev_offset2 = (*offsets_data2)[idx - 1];
238
12
                size2 = (*offsets_data2)[idx] - prev_offset2;
239
12
                data_ptr2 = float_data2 + prev_offset2;
240
12
            }
241
242
12
            if (size1 != size2) [[unlikely]] {
243
0
                return Status::InvalidArgument(
244
0
                        "function {} have different input element sizes of array: {} and {}",
245
0
                        get_name(), size1, size2);
246
0
            }
247
12
            dst_data[row] = DistanceImpl::distance(data_ptr1, data_ptr2, size1);
248
12
        }
249
250
10
        block.replace_by_position(result, std::move(dst));
251
10
        return Status::OK();
252
10
    }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_10L1DistanceEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_10L2DistanceEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_14CosineDistanceEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris21FunctionArrayDistanceINS_16CosineSimilarityEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
174
10
                        uint32_t result, size_t input_rows_count) const override {
175
10
        const auto& arg1 = block.get_by_position(arguments[0]);
176
10
        const auto& arg2 = block.get_by_position(arguments[1]);
177
178
        // Try to handle const columns without expanding them.
179
10
        auto const_info1 = _try_extract_const(arg1.column, "First argument");
180
10
        auto const_info2 = _try_extract_const(arg2.column, "Second argument");
181
182
        // For non-const columns, expand and extract normally.
183
10
        ColumnPtr materialized_col1, materialized_col2;
184
10
        const ColumnArray* arr1 = nullptr;
185
10
        const ColumnArray* arr2 = nullptr;
186
10
        const ColumnFloat32* float1 = nullptr;
187
10
        const ColumnFloat32* float2 = nullptr;
188
10
        const ColumnOffset64* offset1 = nullptr;
189
10
        const ColumnOffset64* offset2 = nullptr;
190
10
        const IColumn::Offsets64* offsets_data1 = nullptr;
191
10
        const IColumn::Offsets64* offsets_data2 = nullptr;
192
10
        const float* float_data1 = nullptr;
193
10
        const float* float_data2 = nullptr;
194
195
10
        if (!const_info1) {
196
10
            materialized_col1 = arg1.column->convert_to_full_column_if_const();
197
10
            arr1 = _extract_array_column(materialized_col1.get(), "First argument", get_name());
198
10
            float1 = _extract_float_data(arr1, "First argument", get_name());
199
10
            offset1 = assert_cast<const ColumnArray::ColumnOffsets*>(arr1->get_offsets_ptr().get());
200
10
            offsets_data1 = &offset1->get_data();
201
10
            float_data1 = float1->get_data().data();
202
10
        }
203
204
10
        if (!const_info2) {
205
10
            materialized_col2 = arg2.column->convert_to_full_column_if_const();
206
10
            arr2 = _extract_array_column(materialized_col2.get(), "Second argument", get_name());
207
10
            float2 = _extract_float_data(arr2, "Second argument", get_name());
208
10
            offset2 = assert_cast<const ColumnArray::ColumnOffsets*>(arr2->get_offsets_ptr().get());
209
10
            offsets_data2 = &offset2->get_data();
210
10
            float_data2 = float2->get_data().data();
211
10
        }
212
213
        // prepare return data
214
10
        auto dst = ColumnType::create(input_rows_count);
215
10
        auto& dst_data = dst->get_data();
216
217
22
        for (size_t row = 0; row < input_rows_count; ++row) {
218
12
            const float* data_ptr1;
219
12
            const float* data_ptr2;
220
12
            ssize_t size1, size2;
221
12
            const auto idx = static_cast<ssize_t>(row);
222
223
12
            if (const_info1) {
224
0
                data_ptr1 = const_info1->data;
225
0
                size1 = const_info1->dim;
226
12
            } else {
227
                // -1 is valid for PaddedPODArray-backed offsets.
228
12
                const auto prev_offset1 = (*offsets_data1)[idx - 1];
229
12
                size1 = (*offsets_data1)[idx] - prev_offset1;
230
12
                data_ptr1 = float_data1 + prev_offset1;
231
12
            }
232
233
12
            if (const_info2) {
234
0
                data_ptr2 = const_info2->data;
235
0
                size2 = const_info2->dim;
236
12
            } else {
237
12
                const auto prev_offset2 = (*offsets_data2)[idx - 1];
238
12
                size2 = (*offsets_data2)[idx] - prev_offset2;
239
12
                data_ptr2 = float_data2 + prev_offset2;
240
12
            }
241
242
12
            if (size1 != size2) [[unlikely]] {
243
0
                return Status::InvalidArgument(
244
0
                        "function {} have different input element sizes of array: {} and {}",
245
0
                        get_name(), size1, size2);
246
0
            }
247
12
            dst_data[row] = DistanceImpl::distance(data_ptr1, data_ptr2, size1);
248
12
        }
249
250
10
        block.replace_by_position(result, std::move(dst));
251
10
        return Status::OK();
252
10
    }
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_12InnerProductEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_21L2DistanceApproximateEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris21FunctionArrayDistanceINS_23InnerProductApproximateEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
253
};
254
255
} // namespace doris