Coverage Report

Created: 2024-11-21 14:00

/root/doris/be/src/vec/functions/if.cpp
Line
Count
Source (jump to first uncovered line)
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/If.cpp
19
// and modified by Doris
20
21
#include <glog/logging.h>
22
#include <stddef.h>
23
24
#include <algorithm>
25
#include <boost/iterator/iterator_facade.hpp>
26
#include <memory>
27
#include <ostream>
28
#include <type_traits>
29
#include <utility>
30
31
#include "common/status.h"
32
#include "util/simd/bits.h"
33
#include "vec/aggregate_functions/aggregate_function.h"
34
#include "vec/columns/column.h"
35
#include "vec/columns/column_const.h"
36
#include "vec/columns/column_nullable.h"
37
#include "vec/columns/column_vector.h"
38
#include "vec/columns/columns_number.h"
39
#include "vec/common/assert_cast.h"
40
#include "vec/common/pod_array_fwd.h"
41
#include "vec/common/typeid_cast.h"
42
#include "vec/core/block.h"
43
#include "vec/core/call_on_type_index.h"
44
#include "vec/core/column_numbers.h"
45
#include "vec/core/column_with_type_and_name.h"
46
#include "vec/core/types.h"
47
#include "vec/data_types/data_type.h"
48
#include "vec/data_types/data_type_nullable.h"
49
#include "vec/data_types/data_type_number.h"
50
#include "vec/functions/function.h"
51
#include "vec/functions/function_helpers.h"
52
#include "vec/functions/simple_function_factory.h"
53
namespace doris {
54
class FunctionContext;
55
56
namespace vectorized {
57
namespace NumberTraits {
58
struct Error;
59
} // namespace NumberTraits
60
} // namespace vectorized
61
} // namespace doris
62
63
namespace doris::vectorized {
64
65
template <typename A, typename B, typename ResultType>
66
struct NumIfImpl {
67
    using ArrayCond = PaddedPODArray<UInt8>;
68
    using ArrayA = PaddedPODArray<A>;
69
    using ArrayB = PaddedPODArray<B>;
70
    using ColVecResult = ColumnVector<ResultType>;
71
72
    static void vector_vector(const ArrayCond& cond, const ArrayA& a, const ArrayB& b, Block& block,
73
3
                              uint32_t result, UInt32) {
74
3
        size_t size = cond.size();
75
3
        auto col_res = ColVecResult::create(size);
76
3
        typename ColVecResult::Container& res = col_res->get_data();
77
78
12
        for (size_t i = 0; i < size; ++i)
79
9
            res[i] = cond[i] ? static_cast<ResultType>(a[i]) : static_cast<ResultType>(b[i]);
80
3
        block.replace_by_position(result, std::move(col_res));
81
3
    }
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIhhhE13vector_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEES9_S9_RNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplItttE13vector_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_ItLm4096ES6_Lm16ELm15EEESC_RNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIjjjE13vector_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IjLm4096ES6_Lm16ELm15EEESC_RNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplImmmE13vector_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_ImLm4096ES6_Lm16ELm15EEESC_RNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIaaaE13vector_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IaLm4096ES6_Lm16ELm15EEESC_RNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIsssE13vector_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IsLm4096ES6_Lm16ELm15EEESC_RNS0_5BlockEjj
_ZN5doris10vectorized9NumIfImplIiiiE13vector_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IiLm4096ES6_Lm16ELm15EEESC_RNS0_5BlockEjj
Line
Count
Source
73
2
                              uint32_t result, UInt32) {
74
2
        size_t size = cond.size();
75
2
        auto col_res = ColVecResult::create(size);
76
2
        typename ColVecResult::Container& res = col_res->get_data();
77
78
8
        for (size_t i = 0; i < size; ++i)
79
6
            res[i] = cond[i] ? static_cast<ResultType>(a[i]) : static_cast<ResultType>(b[i]);
80
2
        block.replace_by_position(result, std::move(col_res));
81
2
    }
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIlllE13vector_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IlLm4096ES6_Lm16ELm15EEESC_RNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplInnnE13vector_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_InLm4096ES6_Lm16ELm15EEESC_RNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIfffE13vector_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IfLm4096ES6_Lm16ELm15EEESC_RNS0_5BlockEjj
_ZN5doris10vectorized9NumIfImplIdddE13vector_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IdLm4096ES6_Lm16ELm15EEESC_RNS0_5BlockEjj
Line
Count
Source
73
1
                              uint32_t result, UInt32) {
74
1
        size_t size = cond.size();
75
1
        auto col_res = ColVecResult::create(size);
76
1
        typename ColVecResult::Container& res = col_res->get_data();
77
78
4
        for (size_t i = 0; i < size; ++i)
79
3
            res[i] = cond[i] ? static_cast<ResultType>(a[i]) : static_cast<ResultType>(b[i]);
80
1
        block.replace_by_position(result, std::move(col_res));
81
1
    }
82
83
    static void vector_constant(const ArrayCond& cond, const ArrayA& a, B b, Block& block,
84
0
                                uint32_t result, UInt32) {
85
0
        size_t size = cond.size();
86
0
        auto col_res = ColVecResult::create(size);
87
0
        typename ColVecResult::Container& res = col_res->get_data();
88
89
0
        for (size_t i = 0; i < size; ++i)
90
0
            res[i] = cond[i] ? static_cast<ResultType>(a[i]) : static_cast<ResultType>(b);
91
0
        block.replace_by_position(result, std::move(col_res));
92
0
    }
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIhhhE15vector_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEES9_hRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplItttE15vector_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_ItLm4096ES6_Lm16ELm15EEEtRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIjjjE15vector_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IjLm4096ES6_Lm16ELm15EEEjRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplImmmE15vector_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_ImLm4096ES6_Lm16ELm15EEEmRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIaaaE15vector_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IaLm4096ES6_Lm16ELm15EEEaRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIsssE15vector_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IsLm4096ES6_Lm16ELm15EEEsRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIiiiE15vector_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IiLm4096ES6_Lm16ELm15EEEiRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIlllE15vector_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IlLm4096ES6_Lm16ELm15EEElRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplInnnE15vector_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_InLm4096ES6_Lm16ELm15EEEnRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIfffE15vector_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IfLm4096ES6_Lm16ELm15EEEfRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIdddE15vector_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEERKNS3_IdLm4096ES6_Lm16ELm15EEEdRNS0_5BlockEjj
93
94
    static void constant_vector(const ArrayCond& cond, A a, const ArrayB& b, Block& block,
95
0
                                uint32_t result, UInt32) {
96
0
        size_t size = cond.size();
97
0
        auto col_res = ColVecResult::create(size);
98
0
        typename ColVecResult::Container& res = col_res->get_data();
99
100
0
        for (size_t i = 0; i < size; ++i)
101
0
            res[i] = cond[i] ? static_cast<ResultType>(a) : static_cast<ResultType>(b[i]);
102
0
        block.replace_by_position(result, std::move(col_res));
103
0
    }
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIhhhE15constant_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEhS9_RNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplItttE15constant_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEtRKNS3_ItLm4096ES6_Lm16ELm15EEERNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIjjjE15constant_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEjRKNS3_IjLm4096ES6_Lm16ELm15EEERNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplImmmE15constant_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEmRKNS3_ImLm4096ES6_Lm16ELm15EEERNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIaaaE15constant_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEaRKNS3_IaLm4096ES6_Lm16ELm15EEERNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIsssE15constant_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEsRKNS3_IsLm4096ES6_Lm16ELm15EEERNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIiiiE15constant_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEiRKNS3_IiLm4096ES6_Lm16ELm15EEERNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIlllE15constant_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEElRKNS3_IlLm4096ES6_Lm16ELm15EEERNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplInnnE15constant_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEnRKNS3_InLm4096ES6_Lm16ELm15EEERNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIfffE15constant_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEfRKNS3_IfLm4096ES6_Lm16ELm15EEERNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIdddE15constant_vectorERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEdRKNS3_IdLm4096ES6_Lm16ELm15EEERNS0_5BlockEjj
104
105
    static void constant_constant(const ArrayCond& cond, A a, B b, Block& block, uint32_t result,
106
0
                                  UInt32) {
107
0
        size_t size = cond.size();
108
0
        auto col_res = ColVecResult::create(size);
109
0
        typename ColVecResult::Container& res = col_res->get_data();
110
111
0
        for (size_t i = 0; i < size; ++i)
112
0
            res[i] = cond[i] ? static_cast<ResultType>(a) : static_cast<ResultType>(b);
113
0
        block.replace_by_position(result, std::move(col_res));
114
0
    }
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIhhhE17constant_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEhhRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplItttE17constant_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEttRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIjjjE17constant_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEjjRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplImmmE17constant_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEmmRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIaaaE17constant_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEaaRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIsssE17constant_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEssRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIiiiE17constant_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEiiRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIlllE17constant_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEllRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplInnnE17constant_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEnnRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIfffE17constant_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEffRNS0_5BlockEjj
Unexecuted instantiation: _ZN5doris10vectorized9NumIfImplIdddE17constant_constantERKNS0_8PODArrayIhLm4096E9AllocatorILb0ELb0ELb0E22DefaultMemoryAllocatorELm16ELm15EEEddRNS0_5BlockEjj
115
};
116
117
template <typename A, typename B>
118
struct NumIfImpl<A, B, NumberTraits::Error> {
119
private:
120
    [[noreturn]] static void throw_error() {
121
        throw doris::Exception(ErrorCode::INTERNAL_ERROR,
122
                               "Internal logic error: invalid types of arguments 2 and 3 of if");
123
        __builtin_unreachable();
124
    }
125
126
public:
127
    template <typename... Args>
128
    static void vector_vector(Args&&...) {
129
        throw_error();
130
    }
131
    template <typename... Args>
132
    static void vector_constant(Args&&...) {
133
        throw_error();
134
    }
135
    template <typename... Args>
136
    static void constant_vector(Args&&...) {
137
        throw_error();
138
    }
139
    template <typename... Args>
140
    static void constant_constant(Args&&...) {
141
        throw_error();
142
    }
143
};
144
145
8
size_t count_true_with_notnull(const ColumnPtr& col) {
146
8
    if (col->only_null()) {
147
0
        return 0;
148
0
    }
149
150
8
    if (const auto* const_col = check_and_get_column_const<ColumnVector<UInt8>>(col.get())) {
151
0
        bool is_true = const_col->get_bool(0);
152
0
        return is_true ? col->size() : 0;
153
0
    }
154
155
8
    auto count = col->size();
156
8
    if (col->is_nullable()) {
157
3
        const auto* nullable = assert_cast<const ColumnNullable*>(col.get());
158
3
        const auto* __restrict null_data = nullable->get_null_map_data().data();
159
3
        const auto* __restrict bool_data =
160
3
                ((const ColumnVector<UInt8>&)(nullable->get_nested_column())).get_data().data();
161
162
3
        size_t null_count = count - simd::count_zero_num((const int8_t*)null_data, count);
163
164
3
        if (null_count == count) {
165
0
            return 0;
166
3
        } else if (null_count == 0) {
167
0
            size_t true_count = count - simd::count_zero_num((const int8_t*)bool_data, count);
168
0
            return true_count;
169
3
        } else {
170
            // In fact, the null_count maybe is different with true_count, but it's no impact
171
3
            return null_count;
172
3
        }
173
5
    } else {
174
5
        const auto* bool_col = assert_cast<const ColumnUInt8*>(col.get());
175
5
        const auto* __restrict bool_data = bool_col->get_data().data();
176
5
        return count - simd::count_zero_num((const int8_t*)bool_data, count);
177
5
    }
178
8
}
179
// todo(wb) support llvm codegen
180
class FunctionIf : public IFunction {
181
public:
182
    static constexpr auto name = "if";
183
184
9
    static FunctionPtr create() { return std::make_shared<FunctionIf>(); }
185
0
    String get_name() const override { return name; }
186
187
8
    size_t get_number_of_arguments() const override { return 3; }
188
16
    bool use_default_implementation_for_nulls() const override { return false; }
189
8
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
190
        // if return type is custom, one of nullable return type will be nullable
191
8
        bool nullable = arguments[1]->is_nullable() || arguments[2]->is_nullable();
192
8
        if (nullable) {
193
8
            return make_nullable(arguments[1]);
194
8
        } else {
195
0
            return arguments[1];
196
0
        }
197
8
    }
198
199
39
    static ColumnPtr materialize_column_if_const(const ColumnPtr& column) {
200
39
        return column->convert_to_full_column_if_const();
201
39
    }
202
203
0
    static ColumnPtr make_nullable_column_if_not(const ColumnPtr& column) {
204
0
        if (is_column_nullable(*column)) return column;
205
206
0
        return ColumnNullable::create(materialize_column_if_const(column),
207
0
                                      ColumnUInt8::create(column->size(), 0));
208
0
    }
209
210
10
    static ColumnPtr get_nested_column(const ColumnPtr& column) {
211
10
        if (auto* nullable = check_and_get_column<ColumnNullable>(*column))
212
10
            return nullable->get_nested_column_ptr();
213
0
        else if (const auto* column_const = check_and_get_column<ColumnConst>(*column))
214
0
            return ColumnConst::create(get_nested_column(column_const->get_data_column_ptr()),
215
0
                                       column->size());
216
217
0
        return column;
218
10
    }
219
220
    Status execute_generic(Block& block, const ColumnUInt8* cond_col,
221
                           const ColumnWithTypeAndName& then_col_type_name,
222
                           const ColumnWithTypeAndName& else_col_type_name, uint32_t result,
223
7
                           size_t input_row_count) const {
224
7
        MutableColumnPtr result_column = block.get_by_position(result).type->create_column();
225
7
        result_column->reserve(input_row_count);
226
227
7
        const IColumn& then_col = *then_col_type_name.column;
228
7
        const IColumn& else_col = *else_col_type_name.column;
229
7
        bool then_is_const = is_column_const(then_col);
230
7
        bool else_is_const = is_column_const(else_col);
231
232
7
        const auto& cond_array = cond_col->get_data();
233
234
7
        if (then_is_const && else_is_const) {
235
0
            const IColumn& then_nested_column =
236
0
                    assert_cast<const ColumnConst&>(then_col).get_data_column();
237
0
            const IColumn& else_nested_column =
238
0
                    assert_cast<const ColumnConst&>(else_col).get_data_column();
239
0
            for (size_t i = 0; i < input_row_count; i++) {
240
0
                if (cond_array[i])
241
0
                    result_column->insert_from(then_nested_column, 0);
242
0
                else
243
0
                    result_column->insert_from(else_nested_column, 0);
244
0
            }
245
7
        } else if (then_is_const) {
246
0
            const IColumn& then_nested_column =
247
0
                    assert_cast<const ColumnConst&>(then_col).get_data_column();
248
249
0
            for (size_t i = 0; i < input_row_count; i++) {
250
0
                if (cond_array[i])
251
0
                    result_column->insert_from(then_nested_column, 0);
252
0
                else
253
0
                    result_column->insert_from(else_col, i);
254
0
            }
255
7
        } else if (else_is_const) {
256
0
            const IColumn& else_nested_column =
257
0
                    assert_cast<const ColumnConst&>(else_col).get_data_column();
258
259
0
            for (size_t i = 0; i < input_row_count; i++) {
260
0
                if (cond_array[i])
261
0
                    result_column->insert_from(then_col, i);
262
0
                else
263
0
                    result_column->insert_from(else_nested_column, 0);
264
0
            }
265
7
        } else {
266
26
            for (size_t i = 0; i < input_row_count; i++) {
267
19
                result_column->insert_from(cond_array[i] ? then_col : else_col, i);
268
19
            }
269
7
        }
270
7
        block.replace_by_position(result, std::move(result_column));
271
7
        return Status::OK();
272
7
    }
273
274
    void execute_basic_type(Block& block, const ColumnUInt8* cond_col,
275
                            const ColumnWithTypeAndName& then_col,
276
                            const ColumnWithTypeAndName& else_col, uint32_t result,
277
3
                            Status& status) const {
278
3
        auto call = [&](const auto& types) -> bool {
279
3
            using Types = std::decay_t<decltype(types)>;
280
3
            using T0 = typename Types::LeftType;
281
3
            using result_type = typename Types::LeftType;
282
283
            // for doris, args type and return type must be sanme beacause of type cast has already done before, so here just need one type;
284
            // but code still need a better impelement
285
3
            using ColVecT0 = ColumnVector<T0>;
286
287
3
            if (auto col_then = check_and_get_column<ColVecT0>(then_col.column.get())) {
288
3
                if (auto col_else = check_and_get_column<ColVecT0>(else_col.column.get())) {
289
3
                    NumIfImpl<T0, T0, result_type>::vector_vector(
290
3
                            cond_col->get_data(), col_then->get_data(), col_else->get_data(), block,
291
3
                            result, 0);
292
3
                } else if (auto col_const_else =
293
0
                                   check_and_get_column_const<ColVecT0>(else_col.column.get())) {
294
0
                    NumIfImpl<T0, T0, result_type>::vector_constant(
295
0
                            cond_col->get_data(), col_then->get_data(),
296
0
                            col_const_else->template get_value<T0>(), block, result, 0);
297
0
                }
298
3
            } else if (auto col_const_then =
299
0
                               check_and_get_column_const<ColVecT0>(then_col.column.get())) {
300
0
                if (auto col_else = check_and_get_column<ColVecT0>(else_col.column.get())) {
301
0
                    NumIfImpl<T0, T0, result_type>::constant_vector(
302
0
                            cond_col->get_data(), col_const_then->template get_value<T0>(),
303
0
                            col_else->get_data(), block, result, 0);
304
0
                } else if (auto col_const_else =
305
0
                                   check_and_get_column_const<ColVecT0>(else_col.column.get())) {
306
0
                    NumIfImpl<T0, T0, result_type>::constant_constant(
307
0
                            cond_col->get_data(), col_const_then->template get_value<T0>(),
308
0
                            col_const_else->template get_value<T0>(), block, result, 0);
309
0
                }
310
0
            } else {
311
0
                status = Status::InternalError("unexpected args column type");
312
0
            }
313
3
            return true;
314
3
        };
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIhhEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIhtEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIhjEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIhmEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIhaEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIhsEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIhiEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIhlEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIhnEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIhfEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIhdEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIthEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIttEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairItjEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairItmEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairItaEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairItsEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairItiEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairItlEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairItnEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairItfEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairItdEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIjhEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIjtEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIjjEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIjmEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIjaEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIjsEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIjiEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIjlEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIjnEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIjfEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIjdEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairImhEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairImtEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairImjEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairImmEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairImaEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairImsEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairImiEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairImlEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairImnEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairImfEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairImdEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIahEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIatEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIajEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIamEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIaaEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIasEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIaiEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIalEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIanEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIafEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIadEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIshEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIstEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIsjEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIsmEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIsaEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIssEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIsiEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIslEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIsnEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIsfEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIsdEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIihEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIitEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIijEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIimEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIiaEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIisEEEEbSF_
_ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIiiEEEEbSF_
Line
Count
Source
278
2
        auto call = [&](const auto& types) -> bool {
279
2
            using Types = std::decay_t<decltype(types)>;
280
2
            using T0 = typename Types::LeftType;
281
2
            using result_type = typename Types::LeftType;
282
283
            // for doris, args type and return type must be sanme beacause of type cast has already done before, so here just need one type;
284
            // but code still need a better impelement
285
2
            using ColVecT0 = ColumnVector<T0>;
286
287
2
            if (auto col_then = check_and_get_column<ColVecT0>(then_col.column.get())) {
288
2
                if (auto col_else = check_and_get_column<ColVecT0>(else_col.column.get())) {
289
2
                    NumIfImpl<T0, T0, result_type>::vector_vector(
290
2
                            cond_col->get_data(), col_then->get_data(), col_else->get_data(), block,
291
2
                            result, 0);
292
2
                } else if (auto col_const_else =
293
0
                                   check_and_get_column_const<ColVecT0>(else_col.column.get())) {
294
0
                    NumIfImpl<T0, T0, result_type>::vector_constant(
295
0
                            cond_col->get_data(), col_then->get_data(),
296
0
                            col_const_else->template get_value<T0>(), block, result, 0);
297
0
                }
298
2
            } else if (auto col_const_then =
299
0
                               check_and_get_column_const<ColVecT0>(then_col.column.get())) {
300
0
                if (auto col_else = check_and_get_column<ColVecT0>(else_col.column.get())) {
301
0
                    NumIfImpl<T0, T0, result_type>::constant_vector(
302
0
                            cond_col->get_data(), col_const_then->template get_value<T0>(),
303
0
                            col_else->get_data(), block, result, 0);
304
0
                } else if (auto col_const_else =
305
0
                                   check_and_get_column_const<ColVecT0>(else_col.column.get())) {
306
0
                    NumIfImpl<T0, T0, result_type>::constant_constant(
307
0
                            cond_col->get_data(), col_const_then->template get_value<T0>(),
308
0
                            col_const_else->template get_value<T0>(), block, result, 0);
309
0
                }
310
0
            } else {
311
0
                status = Status::InternalError("unexpected args column type");
312
0
            }
313
2
            return true;
314
2
        };
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIilEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIinEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIifEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIidEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIlhEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIltEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIljEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIlmEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIlaEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIlsEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIliEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIllEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIlnEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIlfEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIldEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairInhEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIntEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairInjEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairInmEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairInaEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairInsEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIniEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairInlEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairInnEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairInfEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIndEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIfhEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIftEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIfjEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIfmEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIfaEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIfsEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIfiEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIflEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIfnEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIffEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIfdEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIdhEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIdtEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIdjEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIdmEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIdaEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIdsEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIdiEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIdlEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIdnEEEEbSF_
Unexecuted instantiation: _ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIdfEEEEbSF_
_ZZNK5doris10vectorized10FunctionIf18execute_basic_typeERNS0_5BlockEPKNS0_12ColumnVectorIhEERKNS0_21ColumnWithTypeAndNameESA_jRNS_6StatusEENKUlRKT_E_clINS0_8TypePairIddEEEEbSF_
Line
Count
Source
278
1
        auto call = [&](const auto& types) -> bool {
279
1
            using Types = std::decay_t<decltype(types)>;
280
1
            using T0 = typename Types::LeftType;
281
1
            using result_type = typename Types::LeftType;
282
283
            // for doris, args type and return type must be sanme beacause of type cast has already done before, so here just need one type;
284
            // but code still need a better impelement
285
1
            using ColVecT0 = ColumnVector<T0>;
286
287
1
            if (auto col_then = check_and_get_column<ColVecT0>(then_col.column.get())) {
288
1
                if (auto col_else = check_and_get_column<ColVecT0>(else_col.column.get())) {
289
1
                    NumIfImpl<T0, T0, result_type>::vector_vector(
290
1
                            cond_col->get_data(), col_then->get_data(), col_else->get_data(), block,
291
1
                            result, 0);
292
1
                } else if (auto col_const_else =
293
0
                                   check_and_get_column_const<ColVecT0>(else_col.column.get())) {
294
0
                    NumIfImpl<T0, T0, result_type>::vector_constant(
295
0
                            cond_col->get_data(), col_then->get_data(),
296
0
                            col_const_else->template get_value<T0>(), block, result, 0);
297
0
                }
298
1
            } else if (auto col_const_then =
299
0
                               check_and_get_column_const<ColVecT0>(then_col.column.get())) {
300
0
                if (auto col_else = check_and_get_column<ColVecT0>(else_col.column.get())) {
301
0
                    NumIfImpl<T0, T0, result_type>::constant_vector(
302
0
                            cond_col->get_data(), col_const_then->template get_value<T0>(),
303
0
                            col_else->get_data(), block, result, 0);
304
0
                } else if (auto col_const_else =
305
0
                                   check_and_get_column_const<ColVecT0>(else_col.column.get())) {
306
0
                    NumIfImpl<T0, T0, result_type>::constant_constant(
307
0
                            cond_col->get_data(), col_const_then->template get_value<T0>(),
308
0
                            col_const_else->template get_value<T0>(), block, result, 0);
309
0
                }
310
0
            } else {
311
0
                status = Status::InternalError("unexpected args column type");
312
0
            }
313
1
            return true;
314
1
        };
315
316
        // todo(wb): a better way to determine type
317
3
        call_on_basic_types<true, true, false, false>(then_col.type->get_type_id(),
318
3
                                                      else_col.type->get_type_id(), call);
319
3
    }
320
321
    Status execute_for_null_then_else(FunctionContext* context, Block& block,
322
                                      const ColumnWithTypeAndName& arg_cond,
323
                                      const ColumnWithTypeAndName& arg_then,
324
                                      const ColumnWithTypeAndName& arg_else, uint32_t result,
325
18
                                      size_t input_rows_count, bool& handled) const {
326
18
        bool then_is_null = arg_then.column->only_null();
327
18
        bool else_is_null = arg_else.column->only_null();
328
329
18
        handled = false;
330
18
        if (!then_is_null && !else_is_null) {
331
15
            return Status::OK();
332
15
        }
333
334
3
        if (then_is_null && else_is_null) {
335
0
            block.get_by_position(result).column =
336
0
                    block.get_by_position(result).type->create_column_const_with_default_value(
337
0
                            input_rows_count);
338
0
            handled = true;
339
0
            return Status::OK();
340
0
        }
341
342
3
        const auto* cond_col = typeid_cast<const ColumnUInt8*>(arg_cond.column.get());
343
3
        const ColumnConst* cond_const_col =
344
3
                check_and_get_column_const<ColumnVector<UInt8>>(arg_cond.column.get());
345
346
        /// If then is NULL, we create Nullable column with null mask OR-ed with condition.
347
3
        if (then_is_null) {
348
3
            if (cond_col) {
349
3
                if (is_column_nullable(*arg_else.column)) { // if(cond, null, nullable)
350
3
                    auto arg_else_column = arg_else.column;
351
3
                    auto result_column = (*std::move(arg_else_column)).mutate();
352
3
                    assert_cast<ColumnNullable&>(*result_column)
353
3
                            .apply_null_map(assert_cast<const ColumnUInt8&>(*arg_cond.column));
354
3
                    block.replace_by_position(result, std::move(result_column));
355
3
                } else { // if(cond, null, not_nullable)
356
0
                    block.replace_by_position(
357
0
                            result,
358
0
                            ColumnNullable::create(materialize_column_if_const(arg_else.column),
359
0
                                                   arg_cond.column));
360
0
                }
361
3
            } else if (cond_const_col) {
362
0
                if (cond_const_col->get_value<UInt8>()) { // if(true, null, else)
363
0
                    block.get_by_position(result).column =
364
0
                            block.get_by_position(result).type->create_column()->clone_resized(
365
0
                                    input_rows_count);
366
0
                } else { // if(false, null, else)
367
0
                    block.get_by_position(result).column =
368
0
                            make_nullable_column_if_not(arg_else.column);
369
0
                }
370
0
            } else {
371
0
                return Status::InternalError(
372
0
                        "Illegal column {} of first argument of function {}. Must be ColumnUInt8 "
373
0
                        "or ColumnConstUInt8.",
374
0
                        arg_cond.column->get_name(), get_name());
375
0
            }
376
3
        } else { /// If else is NULL, we create Nullable column with null mask OR-ed with negated condition.
377
0
            if (cond_col) {
378
0
                size_t size = input_rows_count;
379
380
0
                if (is_column_nullable(*arg_then.column)) { // if(cond, nullable, NULL)
381
0
                    auto arg_then_column = arg_then.column;
382
0
                    auto result_column = (*std::move(arg_then_column)).mutate();
383
0
                    assert_cast<ColumnNullable&>(*result_column)
384
0
                            .apply_negated_null_map(
385
0
                                    assert_cast<const ColumnUInt8&>(*arg_cond.column));
386
0
                    block.replace_by_position(result, std::move(result_column));
387
0
                } else { // if(cond, not_nullable, NULL)
388
0
                    const auto& null_map_data = cond_col->get_data();
389
0
                    auto negated_null_map = ColumnUInt8::create();
390
0
                    auto& negated_null_map_data = negated_null_map->get_data();
391
0
                    negated_null_map_data.resize(size);
392
393
0
                    for (size_t i = 0; i < size; ++i) {
394
0
                        negated_null_map_data[i] = !null_map_data[i];
395
0
                    }
396
397
0
                    block.replace_by_position(
398
0
                            result,
399
0
                            ColumnNullable::create(materialize_column_if_const(arg_then.column),
400
0
                                                   std::move(negated_null_map)));
401
0
                }
402
0
            } else if (cond_const_col) {
403
0
                if (cond_const_col->get_value<UInt8>()) { // if(true, then, NULL)
404
0
                    block.get_by_position(result).column =
405
0
                            make_nullable_column_if_not(arg_then.column);
406
0
                } else { // if(false, then, NULL)
407
0
                    block.get_by_position(result).column =
408
0
                            block.get_by_position(result).type->create_column()->clone_resized(
409
0
                                    input_rows_count);
410
0
                }
411
0
            } else {
412
0
                return Status::InternalError(
413
0
                        "Illegal column {} of first argument of function {}. Must be ColumnUInt8 "
414
0
                        "or ColumnConstUInt8.",
415
0
                        arg_cond.column->get_name(), get_name());
416
0
            }
417
0
        }
418
3
        handled = true;
419
3
        return Status::OK();
420
3
    }
421
422
    Status execute_for_nullable_then_else(FunctionContext* context, Block& block,
423
                                          const ColumnWithTypeAndName& arg_cond,
424
                                          const ColumnWithTypeAndName& arg_then,
425
                                          const ColumnWithTypeAndName& arg_else, uint32_t result,
426
15
                                          size_t input_rows_count, bool& handled) const {
427
15
        auto then_type_is_nullable = arg_then.type->is_nullable();
428
15
        auto else_type_is_nullable = arg_else.type->is_nullable();
429
15
        handled = false;
430
15
        if (!then_type_is_nullable && !else_type_is_nullable) {
431
10
            return Status::OK();
432
10
        }
433
434
5
        auto* then_is_nullable = check_and_get_column<ColumnNullable>(*arg_then.column);
435
5
        auto* else_is_nullable = check_and_get_column<ColumnNullable>(*arg_else.column);
436
5
        bool then_column_is_const_nullable = false;
437
5
        bool else_column_is_const_nullable = false;
438
5
        if (then_type_is_nullable && then_is_nullable == nullptr) {
439
            //this case is a const(nullable column)
440
0
            auto& const_column = assert_cast<const ColumnConst&>(*arg_then.column);
441
0
            then_is_nullable =
442
0
                    assert_cast<const ColumnNullable*>(const_column.get_data_column_ptr().get());
443
0
            then_column_is_const_nullable = true;
444
0
        }
445
446
5
        if (else_type_is_nullable && else_is_nullable == nullptr) {
447
            //this case is a const(nullable column)
448
0
            auto& const_column = assert_cast<const ColumnConst&>(*arg_else.column);
449
0
            else_is_nullable =
450
0
                    assert_cast<const ColumnNullable*>(const_column.get_data_column_ptr().get());
451
0
            else_column_is_const_nullable = true;
452
0
        }
453
454
        /** Calculate null mask of result and nested column separately.
455
          */
456
5
        ColumnPtr result_null_mask;
457
5
        {
458
            // get null map from column:
459
            // a. get_null_map_column_ptr() : it's a real nullable column, so could get it from nullable column
460
            // b. create a const_nullmap_column: it's a not nullable column or a const nullable column, contain a const value
461
5
            Block temporary_block;
462
5
            temporary_block.insert(arg_cond);
463
5
            auto then_nested_null_map =
464
5
                    (then_type_is_nullable && !then_column_is_const_nullable)
465
5
                            ? then_is_nullable->get_null_map_column_ptr()
466
5
                            : DataTypeUInt8().create_column_const_with_default_value(
467
0
                                      input_rows_count);
468
5
            temporary_block.insert({then_nested_null_map, std::make_shared<DataTypeUInt8>(),
469
5
                                    "then_column_null_map"});
470
471
5
            auto else_nested_null_map =
472
5
                    (else_type_is_nullable && !else_column_is_const_nullable)
473
5
                            ? else_is_nullable->get_null_map_column_ptr()
474
5
                            : DataTypeUInt8().create_column_const_with_default_value(
475
0
                                      input_rows_count);
476
5
            temporary_block.insert({else_nested_null_map, std::make_shared<DataTypeUInt8>(),
477
5
                                    "else_column_null_map"});
478
5
            temporary_block.insert(
479
5
                    {nullptr, std::make_shared<DataTypeUInt8>(), "result_column_null_map"});
480
481
5
            RETURN_IF_ERROR(_execute_impl_internal(context, temporary_block, {0, 1, 2}, 3,
482
5
                                                   temporary_block.rows()));
483
484
5
            result_null_mask = temporary_block.get_by_position(3).column;
485
5
        }
486
487
0
        ColumnPtr result_nested_column;
488
489
5
        {
490
5
            Block temporary_block(
491
5
                    {arg_cond,
492
5
                     {get_nested_column(arg_then.column), remove_nullable(arg_then.type), ""},
493
5
                     {get_nested_column(arg_else.column), remove_nullable(arg_else.type), ""},
494
5
                     {nullptr, remove_nullable(block.get_by_position(result).type), ""}});
495
496
5
            RETURN_IF_ERROR(_execute_impl_internal(context, temporary_block, {0, 1, 2}, 3,
497
5
                                                   temporary_block.rows()));
498
499
5
            result_nested_column = temporary_block.get_by_position(3).column;
500
5
        }
501
502
0
        auto column = ColumnNullable::create(materialize_column_if_const(result_nested_column),
503
5
                                             materialize_column_if_const(result_null_mask));
504
5
        block.replace_by_position(result, std::move(column));
505
5
        handled = true;
506
5
        return Status::OK();
507
5
    }
508
509
    Status execute_for_null_condition(FunctionContext* context, Block& block,
510
                                      const ColumnNumbers& arguments,
511
                                      const ColumnWithTypeAndName& arg_cond,
512
                                      const ColumnWithTypeAndName& arg_then,
513
                                      const ColumnWithTypeAndName& arg_else, uint32_t result,
514
21
                                      bool& handled) const {
515
21
        bool cond_is_null = arg_cond.column->only_null();
516
21
        handled = false;
517
518
21
        if (cond_is_null) {
519
0
            block.replace_by_position(result,
520
0
                                      arg_else.column->clone_resized(arg_cond.column->size()));
521
0
            handled = true;
522
0
            return Status::OK();
523
0
        }
524
525
21
        if (const auto* nullable = check_and_get_column<ColumnNullable>(*arg_cond.column)) {
526
3
            DCHECK(remove_nullable(arg_cond.type)->get_type_id() == TypeIndex::UInt8);
527
528
            // update nested column by null map
529
3
            const auto* __restrict null_map = nullable->get_null_map_data().data();
530
3
            auto* __restrict nested_bool_data =
531
3
                    ((ColumnVector<UInt8>&)(nullable->get_nested_column())).get_data().data();
532
3
            auto rows = nullable->size();
533
12
            for (size_t i = 0; i < rows; i++) {
534
9
                nested_bool_data[i] &= !null_map[i];
535
9
            }
536
3
            auto column_size = block.columns();
537
3
            block.insert({nullable->get_nested_column_ptr(), remove_nullable(arg_cond.type),
538
3
                          arg_cond.name});
539
540
3
            handled = true;
541
3
            return _execute_impl_internal(context, block, {column_size, arguments[1], arguments[2]},
542
3
                                          result, rows);
543
3
        }
544
18
        return Status::OK();
545
21
    }
546
547
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
548
8
                        uint32_t result, size_t input_rows_count) const override {
549
8
        const ColumnWithTypeAndName& arg_then = block.get_by_position(arguments[1]);
550
8
        const ColumnWithTypeAndName& arg_else = block.get_by_position(arguments[2]);
551
552
        /// A case for identical then and else (pointers are the same).
553
8
        if (arg_then.column.get() == arg_else.column.get()) {
554
            /// Just point result to them.
555
0
            block.replace_by_position(result, arg_then.column);
556
0
            return Status::OK();
557
0
        }
558
559
8
        ColumnWithTypeAndName& cond_column = block.get_by_position(arguments[0]);
560
8
        cond_column.column = materialize_column_if_const(cond_column.column);
561
8
        const ColumnWithTypeAndName& arg_cond = block.get_by_position(arguments[0]);
562
563
8
        auto true_count = count_true_with_notnull(arg_cond.column);
564
8
        auto item_count = arg_cond.column->size();
565
8
        if (true_count == item_count || true_count == 0) {
566
0
            bool result_nullable = block.get_by_position(result).type->is_nullable();
567
0
            if (true_count == item_count) {
568
0
                block.replace_by_position(
569
0
                        result,
570
0
                        result_nullable
571
0
                                ? make_nullable(arg_then.column->clone_resized(input_rows_count))
572
0
                                : arg_then.column->clone_resized(input_rows_count));
573
0
            } else {
574
0
                block.replace_by_position(
575
0
                        result,
576
0
                        result_nullable
577
0
                                ? make_nullable(arg_else.column->clone_resized(input_rows_count))
578
0
                                : arg_else.column->clone_resized(input_rows_count));
579
0
            }
580
0
            return Status::OK();
581
0
        }
582
583
8
        return _execute_impl_internal(context, block, arguments, result, input_rows_count);
584
8
    }
585
586
    Status _execute_impl_internal(FunctionContext* context, Block& block,
587
                                  const ColumnNumbers& arguments, uint32_t result,
588
21
                                  size_t input_rows_count) const {
589
21
        const ColumnWithTypeAndName& arg_then = block.get_by_position(arguments[1]);
590
21
        const ColumnWithTypeAndName& arg_else = block.get_by_position(arguments[2]);
591
21
        ColumnWithTypeAndName& cond_column = block.get_by_position(arguments[0]);
592
21
        cond_column.column = materialize_column_if_const(cond_column.column);
593
21
        const ColumnWithTypeAndName& arg_cond = block.get_by_position(arguments[0]);
594
595
21
        Status ret = Status::OK();
596
21
        bool handled = false;
597
21
        RETURN_IF_ERROR(execute_for_null_condition(context, block, arguments, arg_cond, arg_then,
598
21
                                                   arg_else, result, handled));
599
600
21
        if (!handled) {
601
18
            RETURN_IF_ERROR(execute_for_null_then_else(context, block, arg_cond, arg_then, arg_else,
602
18
                                                       result, input_rows_count, handled));
603
18
        }
604
605
21
        if (!handled) {
606
15
            RETURN_IF_ERROR(execute_for_nullable_then_else(context, block, arg_cond, arg_then,
607
15
                                                           arg_else, result, input_rows_count,
608
15
                                                           handled));
609
15
        }
610
611
21
        if (handled) {
612
11
            return Status::OK();
613
11
        }
614
615
10
        const auto* cond_col = assert_cast<const ColumnUInt8*>(arg_cond.column.get());
616
10
        const ColumnConst* cond_const_col =
617
10
                check_and_get_column_const<ColumnVector<UInt8>>(arg_cond.column.get());
618
619
10
        if (cond_const_col) {
620
0
            block.get_by_position(result).column =
621
0
                    cond_const_col->get_value<UInt8>() ? arg_then.column : arg_else.column;
622
0
            return Status::OK();
623
0
        }
624
625
10
        WhichDataType which_type(arg_then.type);
626
10
        if (which_type.is_int() || which_type.is_float()) {
627
3
            Status status;
628
3
            execute_basic_type(block, cond_col, arg_then, arg_else, result, status);
629
3
            return status;
630
7
        } else {
631
7
            return execute_generic(block, cond_col, arg_then, arg_else, result, input_rows_count);
632
7
        }
633
10
    }
634
};
635
636
1
void register_function_if(SimpleFunctionFactory& factory) {
637
1
    factory.register_function<FunctionIf>();
638
1
}
639
640
} // namespace doris::vectorized