Coverage Report

Created: 2026-06-17 13:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/vcondition_expr.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "exprs/vcondition_expr.h"
19
20
#include <glog/logging.h>
21
22
#include "core/column/column.h"
23
#include "core/column/column_const.h"
24
#include "exprs/function_context.h"
25
#include "util/simd/bits.h"
26
27
namespace doris {
28
29
Status VConditionExpr::prepare(RuntimeState* state, const RowDescriptor& desc,
30
5.77k
                               VExprContext* context) {
31
5.77k
    RETURN_IF_ERROR_OR_PREPARED(VExpr::prepare(state, desc, context));
32
5.77k
    _prepare_finished = true;
33
5.77k
    return Status::OK();
34
5.77k
}
35
36
Status VConditionExpr::open(RuntimeState* state, VExprContext* context,
37
18.5k
                            FunctionContext::FunctionStateScope scope) {
38
18.5k
    DCHECK(_prepare_finished);
39
18.5k
    RETURN_IF_ERROR(VExpr::open(state, context, scope));
40
18.5k
    _open_finished = true;
41
18.5k
    return Status::OK();
42
18.5k
}
43
44
18.7k
void VConditionExpr::close(VExprContext* context, FunctionContext::FunctionStateScope scope) {
45
18.7k
    DCHECK(_prepare_finished);
46
18.7k
    VExpr::close(context, scope);
47
18.7k
}
48
49
0
std::string VConditionExpr::debug_string() const {
50
0
    std::string result = expr_name() + "(";
51
0
    for (size_t i = 0; i < _children.size(); ++i) {
52
0
        if (i != 0) {
53
0
            result += ", ";
54
0
        }
55
0
        result += _children[i]->debug_string();
56
0
    }
57
0
    result += ")";
58
0
    return result;
59
0
}
60
61
10.2k
size_t VConditionExpr::count_true_with_notnull(const ColumnPtr& col) {
62
10.2k
    if (col->only_null()) {
63
11
        return 0;
64
11
    }
65
66
10.1k
    if (const auto* const_col = check_and_get_column<ColumnConst>(col.get())) {
67
        // if is null , get_bool will return false
68
        // bool get_bool(size_t n) const override {
69
        //     return is_null_at(n) ? false : _nested_column->get_bool(n);
70
        // }
71
1.91k
        bool is_true = const_col->get_bool(0);
72
1.91k
        return is_true ? col->size() : 0;
73
1.91k
    }
74
75
8.27k
    auto count = col->size();
76
8.27k
    if (const auto* nullable = check_and_get_column<ColumnNullable>(col.get())) {
77
930
        const auto* __restrict null_data = nullable->get_null_map_data().data();
78
930
        const auto* __restrict bool_data =
79
930
                ((const ColumnUInt8&)(nullable->get_nested_column())).get_data().data();
80
81
930
        size_t null_count = count - simd::count_zero_num((const int8_t*)null_data, count);
82
83
930
        if (null_count == count) {
84
0
            return 0;
85
930
        } else if (null_count == 0) {
86
873
            size_t true_count = count - simd::count_zero_num((const int8_t*)bool_data, count);
87
873
            return true_count;
88
873
        } else {
89
            // In fact, the null_count maybe is different with true_count, but it's no impact
90
57
            return null_count;
91
57
        }
92
7.34k
    } else {
93
7.34k
        const auto* bool_col = assert_cast<const ColumnUInt8*>(col.get());
94
7.34k
        const auto* __restrict bool_data = bool_col->get_data().data();
95
7.34k
        return count - simd::count_zero_num((const int8_t*)bool_data, count);
96
7.34k
    }
97
8.27k
}
98
99
4.84k
ColumnPtr materialize_column_if_const(const ColumnPtr& column) {
100
4.84k
    return column->convert_to_full_column_if_const();
101
4.84k
}
102
103
0
ColumnPtr make_nullable_column_if_not(const ColumnPtr& column) {
104
0
    if (is_column_nullable(*column)) return column;
105
106
0
    return ColumnNullable::create(materialize_column_if_const(column),
107
0
                                  ColumnUInt8::create(column->size(), 0));
108
0
}
109
110
592
ColumnPtr get_nested_column(const ColumnPtr& column) {
111
592
    if (auto* nullable = check_and_get_column<ColumnNullable>(*column))
112
351
        return nullable->get_nested_column_ptr();
113
241
    else if (const auto* column_const = check_and_get_column<ColumnConst>(*column))
114
79
        return ColumnConst::create(get_nested_column(column_const->get_data_column_ptr()),
115
79
                                   column->size());
116
117
162
    return column;
118
592
}
119
120
Status VectorizedIfExpr::execute_generic(Block& block, const ColumnUInt8* cond_col,
121
                                         const ColumnWithTypeAndName& then_col_type_name,
122
                                         const ColumnWithTypeAndName& else_col_type_name,
123
2.12k
                                         uint32_t result, size_t input_row_count) const {
124
2.12k
    MutableColumnPtr result_column = block.get_by_position(result).type->create_column();
125
2.12k
    result_column->reserve(input_row_count);
126
127
2.12k
    const IColumn& then_col = *then_col_type_name.column;
128
2.12k
    const IColumn& else_col = *else_col_type_name.column;
129
2.12k
    bool then_is_const = is_column_const(then_col);
130
2.12k
    bool else_is_const = is_column_const(else_col);
131
132
2.12k
    const auto& cond_array = cond_col->get_data();
133
134
2.12k
    if (then_is_const && else_is_const) {
135
30
        const IColumn& then_nested_column =
136
30
                assert_cast<const ColumnConst&>(then_col).get_data_column();
137
30
        const IColumn& else_nested_column =
138
30
                assert_cast<const ColumnConst&>(else_col).get_data_column();
139
137
        for (size_t i = 0; i < input_row_count; i++) {
140
107
            if (cond_array[i])
141
50
                result_column->insert_from(then_nested_column, 0);
142
57
            else
143
57
                result_column->insert_from(else_nested_column, 0);
144
107
        }
145
2.09k
    } else if (then_is_const) {
146
2.02k
        const IColumn& then_nested_column =
147
2.02k
                assert_cast<const ColumnConst&>(then_col).get_data_column();
148
149
4.17k
        for (size_t i = 0; i < input_row_count; i++) {
150
2.14k
            if (cond_array[i])
151
55
                result_column->insert_from(then_nested_column, 0);
152
2.09k
            else
153
2.09k
                result_column->insert_from(else_col, i);
154
2.14k
        }
155
2.02k
    } else if (else_is_const) {
156
4
        const IColumn& else_nested_column =
157
4
                assert_cast<const ColumnConst&>(else_col).get_data_column();
158
159
14
        for (size_t i = 0; i < input_row_count; i++) {
160
10
            if (cond_array[i])
161
6
                result_column->insert_from(then_col, i);
162
4
            else
163
4
                result_column->insert_from(else_nested_column, 0);
164
10
        }
165
62
    } else {
166
250
        for (size_t i = 0; i < input_row_count; i++) {
167
188
            result_column->insert_from(cond_array[i] ? then_col : else_col, i);
168
188
        }
169
62
    }
170
2.12k
    block.replace_by_position(result, std::move(result_column));
171
2.12k
    return Status::OK();
172
2.12k
}
173
174
Status VectorizedIfExpr::execute_for_null_then_else(Block& block,
175
                                                    const ColumnWithTypeAndName& arg_cond,
176
                                                    const ColumnWithTypeAndName& arg_then,
177
                                                    const ColumnWithTypeAndName& arg_else,
178
                                                    uint32_t result, size_t input_rows_count,
179
4.08k
                                                    bool& handled) const {
180
4.08k
    bool then_is_null = arg_then.column->only_null();
181
4.08k
    bool else_is_null = arg_else.column->only_null();
182
183
4.08k
    handled = false;
184
4.08k
    if (!then_is_null && !else_is_null) {
185
3.87k
        return Status::OK();
186
3.87k
    }
187
188
206
    if (then_is_null && else_is_null) {
189
0
        block.get_by_position(result).column =
190
0
                block.get_by_position(result).type->create_column_const_with_default_value(
191
0
                        input_rows_count);
192
0
        handled = true;
193
0
        return Status::OK();
194
0
    }
195
196
206
    const auto* cond_col = check_and_get_column<ColumnUInt8>(arg_cond.column.get());
197
206
    const ColumnConst* cond_const_col =
198
206
            check_and_get_column_const<ColumnUInt8>(arg_cond.column.get());
199
200
    /// If then is NULL, we create Nullable column with null mask OR-ed with condition.
201
206
    if (then_is_null) {
202
30
        if (cond_col) {
203
30
            if (is_column_nullable(*arg_else.column)) { // if(cond, null, nullable)
204
30
                auto arg_else_column = arg_else.column;
205
30
                auto result_column = (*std::move(arg_else_column)).mutate();
206
30
                assert_cast<ColumnNullable&>(*result_column)
207
30
                        .apply_null_map(assert_cast<const ColumnUInt8&>(*arg_cond.column));
208
30
                block.replace_by_position(result, std::move(result_column));
209
30
            } else { // if(cond, null, not_nullable)
210
0
                block.replace_by_position(
211
0
                        result, ColumnNullable::create(materialize_column_if_const(arg_else.column),
212
0
                                                       arg_cond.column));
213
0
            }
214
30
        } else if (cond_const_col) {
215
0
            if (cond_const_col->get_value<TYPE_BOOLEAN>()) { // if(true, null, else)
216
0
                block.get_by_position(result).column =
217
0
                        block.get_by_position(result).type->create_column()->clone_resized(
218
0
                                input_rows_count);
219
0
            } else { // if(false, null, else)
220
0
                block.get_by_position(result).column = make_nullable_column_if_not(arg_else.column);
221
0
            }
222
0
        } else {
223
0
            return Status::InternalError(
224
0
                    "Illegal column {} of first argument of function {}. Must be ColumnUInt8 "
225
0
                    "or ColumnConstUInt8.",
226
0
                    arg_cond.column->get_name(), expr_name());
227
0
        }
228
176
    } else { /// If else is NULL, we create Nullable column with null mask OR-ed with negated condition.
229
176
        if (cond_col) {
230
176
            size_t size = input_rows_count;
231
232
176
            if (is_column_nullable(*arg_then.column)) { // if(cond, nullable, NULL)
233
140
                auto arg_then_column = arg_then.column;
234
140
                auto result_column = (*std::move(arg_then_column)).mutate();
235
140
                assert_cast<ColumnNullable&>(*result_column)
236
140
                        .apply_negated_null_map(assert_cast<const ColumnUInt8&>(*arg_cond.column));
237
140
                block.replace_by_position(result, std::move(result_column));
238
140
            } else { // if(cond, not_nullable, NULL)
239
36
                const auto& null_map_data = cond_col->get_data();
240
36
                auto negated_null_map = ColumnUInt8::create();
241
36
                auto& negated_null_map_data = negated_null_map->get_data();
242
36
                negated_null_map_data.resize(size);
243
244
128
                for (size_t i = 0; i < size; ++i) {
245
92
                    negated_null_map_data[i] = !null_map_data[i];
246
92
                }
247
248
36
                block.replace_by_position(
249
36
                        result, ColumnNullable::create(materialize_column_if_const(arg_then.column),
250
36
                                                       std::move(negated_null_map)));
251
36
            }
252
176
        } else if (cond_const_col) {
253
0
            if (cond_const_col->get_value<TYPE_BOOLEAN>()) { // if(true, then, NULL)
254
0
                block.get_by_position(result).column = make_nullable_column_if_not(arg_then.column);
255
0
            } else { // if(false, then, NULL)
256
0
                block.get_by_position(result).column =
257
0
                        block.get_by_position(result).type->create_column()->clone_resized(
258
0
                                input_rows_count);
259
0
            }
260
0
        } else {
261
0
            return Status::InternalError(
262
0
                    "Illegal column {} of first argument of function {}. Must be ColumnUInt8 "
263
0
                    "or ColumnConstUInt8.",
264
0
                    arg_cond.column->get_name(), expr_name());
265
0
        }
266
176
    }
267
206
    handled = true;
268
206
    return Status::OK();
269
206
}
270
271
Status VectorizedIfExpr::execute_for_nullable_then_else(Block& block,
272
                                                        const ColumnWithTypeAndName& arg_cond,
273
                                                        const ColumnWithTypeAndName& arg_then,
274
                                                        const ColumnWithTypeAndName& arg_else,
275
                                                        uint32_t result, size_t input_rows_count,
276
3.87k
                                                        bool& handled) const {
277
3.87k
    auto then_type_is_nullable = arg_then.type->is_nullable();
278
3.87k
    auto else_type_is_nullable = arg_else.type->is_nullable();
279
3.87k
    handled = false;
280
3.87k
    if (!then_type_is_nullable && !else_type_is_nullable) {
281
3.62k
        return Status::OK();
282
3.62k
    }
283
284
257
    const auto* then_is_nullable = check_and_get_column<ColumnNullable>(*arg_then.column);
285
257
    const auto* else_is_nullable = check_and_get_column<ColumnNullable>(*arg_else.column);
286
257
    bool then_column_is_const_nullable = false;
287
257
    bool else_column_is_const_nullable = false;
288
257
    if (then_type_is_nullable && then_is_nullable == nullptr) {
289
        //this case is a const(nullable column)
290
4
        const auto& const_column = assert_cast<const ColumnConst&>(*arg_then.column);
291
4
        then_is_nullable =
292
4
                assert_cast<const ColumnNullable*>(const_column.get_data_column_ptr().get());
293
4
        then_column_is_const_nullable = true;
294
4
    }
295
296
257
    if (else_type_is_nullable && else_is_nullable == nullptr) {
297
        //this case is a const(nullable column)
298
0
        const auto& const_column = assert_cast<const ColumnConst&>(*arg_else.column);
299
0
        else_is_nullable =
300
0
                assert_cast<const ColumnNullable*>(const_column.get_data_column_ptr().get());
301
0
        else_column_is_const_nullable = true;
302
0
    }
303
304
    /** Calculate null mask of result and nested column separately.
305
      */
306
257
    ColumnPtr result_null_mask;
307
257
    {
308
        // get null map from column:
309
        // a. get_null_map_column_ptr() : it's a real nullable column, so could get it from nullable column
310
        // b. create a const_nullmap_column: it's a not nullable column or a const nullable column, contain a const value
311
257
        Block temporary_block;
312
257
        temporary_block.insert(arg_cond);
313
257
        ColumnPtr then_nested_null_map;
314
257
        if (then_type_is_nullable && !then_column_is_const_nullable) {
315
103
            then_nested_null_map = then_is_nullable->get_null_map_column_ptr();
316
154
        } else {
317
154
            then_nested_null_map =
318
154
                    DataTypeUInt8().create_column_const_with_default_value(input_rows_count);
319
154
        }
320
257
        temporary_block.insert(
321
257
                {then_nested_null_map, std::make_shared<DataTypeUInt8>(), "then_column_null_map"});
322
323
257
        ColumnPtr else_nested_null_map;
324
257
        if (else_type_is_nullable && !else_column_is_const_nullable) {
325
244
            else_nested_null_map = else_is_nullable->get_null_map_column_ptr();
326
244
        } else {
327
13
            else_nested_null_map =
328
13
                    DataTypeUInt8().create_column_const_with_default_value(input_rows_count);
329
13
        }
330
257
        temporary_block.insert(
331
257
                {else_nested_null_map, std::make_shared<DataTypeUInt8>(), "else_column_null_map"});
332
257
        temporary_block.insert(
333
257
                {nullptr, std::make_shared<DataTypeUInt8>(), "result_column_null_map"});
334
335
257
        RETURN_IF_ERROR(
336
257
                _execute_impl_internal(temporary_block, {0, 1, 2}, 3, temporary_block.rows()));
337
338
257
        result_null_mask = temporary_block.get_by_position(3).column;
339
257
    }
340
341
0
    ColumnPtr result_nested_column;
342
343
257
    {
344
257
        Block temporary_block(
345
257
                {arg_cond,
346
257
                 {get_nested_column(arg_then.column), remove_nullable(arg_then.type), ""},
347
257
                 {get_nested_column(arg_else.column), remove_nullable(arg_else.type), ""},
348
257
                 {nullptr, remove_nullable(block.get_by_position(result).type), ""}});
349
350
257
        RETURN_IF_ERROR(
351
257
                _execute_impl_internal(temporary_block, {0, 1, 2}, 3, temporary_block.rows()));
352
353
257
        result_nested_column = temporary_block.get_by_position(3).column;
354
257
    }
355
356
0
    auto column = ColumnNullable::create(materialize_column_if_const(result_nested_column),
357
257
                                         materialize_column_if_const(result_null_mask));
358
257
    block.replace_by_position(result, std::move(column));
359
257
    handled = true;
360
257
    return Status::OK();
361
257
}
362
363
Status VectorizedIfExpr::execute_for_null_condition(Block& block, const ColumnNumbers& arguments,
364
                                                    const ColumnWithTypeAndName& arg_cond,
365
                                                    const ColumnWithTypeAndName& arg_then,
366
                                                    const ColumnWithTypeAndName& arg_else,
367
4.29k
                                                    uint32_t result, bool& handled) const {
368
4.29k
    bool cond_is_null = arg_cond.column->only_null();
369
4.29k
    handled = false;
370
371
4.29k
    if (cond_is_null) {
372
0
        block.replace_by_position(result, arg_else.column->clone_resized(arg_cond.column->size()));
373
0
        handled = true;
374
0
        return Status::OK();
375
0
    }
376
377
4.29k
    if (const auto* nullable = check_and_get_column<ColumnNullable>(*arg_cond.column)) {
378
209
        DCHECK(remove_nullable(arg_cond.type)->get_primitive_type() == PrimitiveType::TYPE_BOOLEAN);
379
380
        // update nested column by null map
381
209
        const auto* __restrict null_map = nullable->get_null_map_data().data();
382
209
        auto* __restrict nested_bool_data =
383
209
                ((ColumnUInt8&)(nullable->get_nested_column())).get_data().data();
384
209
        auto rows = nullable->size();
385
7.79k
        for (size_t i = 0; i < rows; i++) {
386
7.58k
            nested_bool_data[i] &= !null_map[i];
387
7.58k
        }
388
209
        auto column_size = block.columns();
389
209
        block.insert(
390
209
                {nullable->get_nested_column_ptr(), remove_nullable(arg_cond.type), arg_cond.name});
391
392
209
        handled = true;
393
209
        return _execute_impl_internal(block, {column_size, arguments[1], arguments[2]}, result,
394
209
                                      rows);
395
209
    }
396
4.08k
    return Status::OK();
397
4.29k
}
398
399
Status VectorizedIfExpr::_execute_impl_internal(Block& block, const ColumnNumbers& arguments,
400
4.29k
                                                uint32_t result, size_t input_rows_count) const {
401
4.29k
    const ColumnWithTypeAndName& arg_then = block.get_by_position(arguments[1]);
402
4.29k
    const ColumnWithTypeAndName& arg_else = block.get_by_position(arguments[2]);
403
4.29k
    ColumnWithTypeAndName& cond_column = block.get_by_position(arguments[0]);
404
4.29k
    cond_column.column = materialize_column_if_const(cond_column.column);
405
4.29k
    const ColumnWithTypeAndName& arg_cond = block.get_by_position(arguments[0]);
406
407
4.29k
    Status ret = Status::OK();
408
4.29k
    bool handled = false;
409
4.29k
    RETURN_IF_ERROR(execute_for_null_condition(block, arguments, arg_cond, arg_then, arg_else,
410
4.29k
                                               result, handled));
411
412
4.29k
    if (!handled) {
413
4.08k
        RETURN_IF_ERROR(execute_for_null_then_else(block, arg_cond, arg_then, arg_else, result,
414
4.08k
                                                   input_rows_count, handled));
415
4.08k
    }
416
417
4.29k
    if (!handled) {
418
3.87k
        RETURN_IF_ERROR(execute_for_nullable_then_else(block, arg_cond, arg_then, arg_else, result,
419
3.87k
                                                       input_rows_count, handled));
420
3.87k
    }
421
422
4.29k
    if (handled) {
423
673
        return Status::OK();
424
673
    }
425
426
3.61k
    const auto* cond_col = assert_cast<const ColumnUInt8*>(arg_cond.column.get());
427
3.61k
    const ColumnConst* cond_const_col =
428
3.61k
            check_and_get_column_const<ColumnUInt8>(arg_cond.column.get());
429
430
3.61k
    if (cond_const_col) {
431
0
        block.get_by_position(result).column =
432
0
                cond_const_col->get_value<TYPE_BOOLEAN>() ? arg_then.column : arg_else.column;
433
0
        return Status::OK();
434
0
    }
435
436
3.61k
    Status vec_exec;
437
438
3.61k
    auto call = [&](const auto& type) -> bool {
439
1.49k
        using DataType = std::decay_t<decltype(type)>;
440
1.49k
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
1.49k
                                                       vec_exec);
442
1.49k
        return true;
443
1.49k
    };
vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE2EEEEEbRKT_
Line
Count
Source
438
451
    auto call = [&](const auto& type) -> bool {
439
451
        using DataType = std::decay_t<decltype(type)>;
440
451
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
451
                                                       vec_exec);
442
451
        return true;
443
451
    };
vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE3EEEEEbRKT_
Line
Count
Source
438
594
    auto call = [&](const auto& type) -> bool {
439
594
        using DataType = std::decay_t<decltype(type)>;
440
594
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
594
                                                       vec_exec);
442
594
        return true;
443
594
    };
vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE4EEEEEbRKT_
Line
Count
Source
438
4
    auto call = [&](const auto& type) -> bool {
439
4
        using DataType = std::decay_t<decltype(type)>;
440
4
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
4
                                                       vec_exec);
442
4
        return true;
443
4
    };
vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE5EEEEEbRKT_
Line
Count
Source
438
244
    auto call = [&](const auto& type) -> bool {
439
244
        using DataType = std::decay_t<decltype(type)>;
440
244
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
244
                                                       vec_exec);
442
244
        return true;
443
244
    };
vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE6EEEEEbRKT_
Line
Count
Source
438
122
    auto call = [&](const auto& type) -> bool {
439
122
        using DataType = std::decay_t<decltype(type)>;
440
122
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
122
                                                       vec_exec);
442
122
        return true;
443
122
    };
Unexecuted instantiation: vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE7EEEEEbRKT_
Unexecuted instantiation: vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE8EEEEEbRKT_
vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE9EEEEEbRKT_
Line
Count
Source
438
12
    auto call = [&](const auto& type) -> bool {
439
12
        using DataType = std::decay_t<decltype(type)>;
440
12
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
12
                                                       vec_exec);
442
12
        return true;
443
12
    };
Unexecuted instantiation: vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE28EEEEEbRKT_
vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE29EEEEEbRKT_
Line
Count
Source
438
10
    auto call = [&](const auto& type) -> bool {
439
10
        using DataType = std::decay_t<decltype(type)>;
440
10
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
10
                                                       vec_exec);
442
10
        return true;
443
10
    };
Unexecuted instantiation: vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE20EEEEEbRKT_
vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE30EEEEEbRKT_
Line
Count
Source
438
27
    auto call = [&](const auto& type) -> bool {
439
27
        using DataType = std::decay_t<decltype(type)>;
440
27
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
27
                                                       vec_exec);
442
27
        return true;
443
27
    };
vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE35EEEEEbRKT_
Line
Count
Source
438
1
    auto call = [&](const auto& type) -> bool {
439
1
        using DataType = std::decay_t<decltype(type)>;
440
1
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
1
                                                       vec_exec);
442
1
        return true;
443
1
    };
Unexecuted instantiation: vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE11EEEEEbRKT_
vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE25EEEEEbRKT_
Line
Count
Source
438
26
    auto call = [&](const auto& type) -> bool {
439
26
        using DataType = std::decay_t<decltype(type)>;
440
26
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
26
                                                       vec_exec);
442
26
        return true;
443
26
    };
vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE26EEEEEbRKT_
Line
Count
Source
438
1
    auto call = [&](const auto& type) -> bool {
439
1
        using DataType = std::decay_t<decltype(type)>;
440
1
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
1
                                                       vec_exec);
442
1
        return true;
443
1
    };
Unexecuted instantiation: vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE12EEEEEbRKT_
vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE27EEEEEbRKT_
Line
Count
Source
438
4
    auto call = [&](const auto& type) -> bool {
439
4
        using DataType = std::decay_t<decltype(type)>;
440
4
        vec_exec = execute_basic_type<DataType::PType>(block, cond_col, arg_then, arg_else, result,
441
4
                                                       vec_exec);
442
4
        return true;
443
4
    };
Unexecuted instantiation: vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE42EEEEEbRKT_
Unexecuted instantiation: vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE36EEEEEbRKT_
Unexecuted instantiation: vcondition_expr.cpp:_ZZNK5doris16VectorizedIfExpr22_execute_impl_internalERNS_5BlockERKSt6vectorIjSaIjEEjmENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE37EEEEEbRKT_
444
445
3.61k
    auto can_use_vec_exec = dispatch_switch_scalar(arg_then.type->get_primitive_type(), call);
446
3.61k
    if (can_use_vec_exec) {
447
1.49k
        return vec_exec;
448
2.12k
    } else {
449
2.12k
        return execute_generic(block, cond_col, arg_then, arg_else, result, input_rows_count);
450
2.12k
    }
451
3.61k
}
452
453
Status VectorizedIfExpr::execute_column_impl(VExprContext* context, const Block* block,
454
                                             const Selector* selector, size_t count,
455
10.1k
                                             ColumnPtr& result_column) const {
456
18.4E
    DCHECK(_open_finished || block == nullptr) << debug_string();
457
10.1k
    DCHECK_EQ(_children.size(), 3) << "IF expr must have three children";
458
459
10.1k
    ColumnPtr cond_column;
460
10.1k
    RETURN_IF_ERROR(_children[0]->execute_column(context, block, selector, count, cond_column));
461
462
10.1k
    ColumnPtr then_column;
463
10.1k
    ColumnPtr else_column;
464
465
10.1k
    auto true_count = count_true_with_notnull(cond_column);
466
10.1k
    auto item_count = cond_column->size();
467
10.1k
    if (true_count == item_count) {
468
926
        RETURN_IF_ERROR(_children[1]->execute_column(context, block, selector, count, then_column));
469
926
        result_column = _data_type->is_nullable() ? make_nullable(then_column) : then_column;
470
926
        return Status::OK();
471
9.27k
    } else if (true_count == 0) {
472
8.15k
        RETURN_IF_ERROR(_children[2]->execute_column(context, block, selector, count, else_column));
473
8.15k
        result_column = _data_type->is_nullable() ? make_nullable(else_column) : else_column;
474
8.15k
        return Status::OK();
475
8.15k
    }
476
477
1.11k
    RETURN_IF_ERROR(_children[1]->execute_column(context, block, selector, count, then_column));
478
1.11k
    RETURN_IF_ERROR(_children[2]->execute_column(context, block, selector, count, else_column));
479
480
1.11k
    Block temp_block;
481
482
1.11k
    temp_block.insert({cond_column, _children[0]->execute_type(block), _children[0]->expr_name()});
483
1.11k
    temp_block.insert({then_column, _children[1]->execute_type(block), _children[1]->expr_name()});
484
1.11k
    temp_block.insert({else_column, _children[2]->execute_type(block), _children[2]->expr_name()});
485
486
    // prepare a column to save result
487
1.11k
    temp_block.insert({nullptr, _data_type, IF_NAME});
488
1.11k
    RETURN_IF_ERROR(_execute_impl_internal(temp_block, {0, 1, 2}, 3, temp_block.rows()));
489
1.11k
    result_column = temp_block.get_by_position(3).column;
490
1.11k
    DCHECK_EQ(result_column->size(), count);
491
1.11k
    return Status::OK();
492
1.11k
}
493
494
Status VectorizedIfNullExpr::execute_column_impl(VExprContext* context, const Block* block,
495
                                                 const Selector* selector, size_t count,
496
2.67k
                                                 ColumnPtr& result_column) const {
497
2.67k
    DCHECK(_open_finished || block == nullptr) << debug_string();
498
2.67k
    DCHECK_EQ(_children.size(), 2) << "IFNULL expr must have two children";
499
500
2.67k
    ColumnPtr first_column;
501
2.67k
    RETURN_IF_ERROR(_children[0]->execute_column(context, block, selector, count, first_column));
502
2.67k
    first_column = first_column->convert_to_full_column_if_const();
503
504
2.67k
    if (!is_column_nullable(*first_column)) {
505
0
        result_column = first_column;
506
0
        DCHECK(_data_type->is_nullable() == false);
507
0
        return Status::OK();
508
0
    }
509
510
2.67k
    if (first_column->only_null()) {
511
231
        RETURN_IF_ERROR(
512
231
                _children[1]->execute_column(context, block, selector, count, result_column));
513
231
        return Status::OK();
514
231
    }
515
516
2.44k
    ColumnPtr second_column;
517
2.44k
    RETURN_IF_ERROR(_children[1]->execute_column(context, block, selector, count, second_column));
518
519
2.44k
    const auto& nullable_first_column = assert_cast<const ColumnNullable&>(*first_column);
520
521
2.44k
    ColumnPtr cond_column = nullable_first_column.get_null_map_column_ptr();
522
523
2.44k
    ColumnPtr then_column = second_column;
524
525
2.44k
    ColumnPtr else_column;
526
2.44k
    DataTypePtr else_type;
527
528
2.44k
    if (_data_type->is_nullable()) {
529
16
        else_column = first_column;
530
16
        else_type = _children[0]->execute_type(block);
531
2.42k
    } else {
532
2.42k
        else_column = nullable_first_column.get_nested_column_ptr();
533
2.42k
        else_type = remove_nullable(_children[0]->execute_type(block));
534
2.42k
    }
535
536
2.44k
    Block temp_block;
537
2.44k
    temp_block.insert({cond_column, std::make_shared<DataTypeUInt8>(), "cond column"});
538
2.44k
    temp_block.insert({then_column, _children[1]->execute_type(block), _children[1]->expr_name()});
539
2.44k
    temp_block.insert({else_column, else_type, _children[0]->expr_name()});
540
541
    // prepare a column to save result
542
2.44k
    temp_block.insert({nullptr, _data_type, IF_NULL_NAME});
543
2.44k
    RETURN_IF_ERROR(_execute_impl_internal(temp_block, {0, 1, 2}, 3, temp_block.rows()));
544
2.44k
    result_column = temp_block.get_by_position(3).column;
545
2.44k
    DCHECK_EQ(result_column->size(), count);
546
2.44k
    return Status::OK();
547
2.44k
}
548
549
template <typename ColumnType>
550
void insert_result_data(MutableColumnPtr& result_column, ColumnPtr& argument_column,
551
                        const UInt8* __restrict null_map_data, UInt8* __restrict filled_flag,
552
102
                        const size_t input_rows_count) {
553
102
    if (result_column->size() == 0 && input_rows_count) {
554
54
        result_column->resize(input_rows_count);
555
54
        auto* __restrict result_raw_data =
556
54
                assert_cast<ColumnType*>(result_column.get())->get_data().data();
557
175
        for (int i = 0; i < input_rows_count; i++) {
558
121
            result_raw_data[i] = {};
559
121
        }
560
54
    }
561
102
    auto* __restrict result_raw_data =
562
102
            assert_cast<ColumnType*>(result_column.get())->get_data().data();
563
102
    auto* __restrict column_raw_data =
564
102
            assert_cast<const ColumnType*>(argument_column.get())->get_data().data();
565
566
    // Here it's SIMD thought the compiler automatically also
567
    // true: null_map_data[row]==0 && filled_idx[row]==0
568
    // if true, could filled current row data into result column
569
360
    for (size_t row = 0; row < input_rows_count; ++row) {
570
258
        if constexpr (std::is_same_v<ColumnType, ColumnDateV2>) {
571
14
            result_raw_data[row] = binary_cast<uint32_t, DateV2Value<DateV2ValueType>>(
572
14
                    result_raw_data[row].to_date_int_val() +
573
14
                    column_raw_data[row].to_date_int_val() *
574
14
                            uint32_t(!(null_map_data[row] | filled_flag[row])));
575
14
        } else if constexpr (std::is_same_v<ColumnType, ColumnDateTimeV2>) {
576
8
            result_raw_data[row] = binary_cast<uint64_t, DateV2Value<DateTimeV2ValueType>>(
577
8
                    result_raw_data[row].to_date_int_val() +
578
8
                    column_raw_data[row].to_date_int_val() *
579
8
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
580
8
        } else if constexpr (std::is_same_v<ColumnType, ColumnTimeStampTz>) {
581
0
            result_raw_data[row] = binary_cast<uint64_t, TimestampTzValue>(
582
0
                    result_raw_data[row].to_date_int_val() +
583
0
                    column_raw_data[row].to_date_int_val() *
584
0
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
585
        } else if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
586
0
                             std::is_same_v<ColumnType, ColumnDateTime>) {
587
0
            result_raw_data[row] = binary_cast<int64_t, VecDateTimeValue>(
588
0
                    binary_cast<VecDateTimeValue, int64_t>(result_raw_data[row]) +
589
0
                    binary_cast<VecDateTimeValue, int64_t>(column_raw_data[row]) *
590
0
                            int64_t(!(null_map_data[row] | filled_flag[row])));
591
        } else if constexpr (std::is_same_v<ColumnType, ColumnFloat32> ||
592
55
                             std::is_same_v<ColumnType, ColumnFloat64>) {
593
55
            auto flag = (!(null_map_data[row] | filled_flag[row]));
594
55
            result_raw_data[row] += std::isfinite(column_raw_data[row])
595
55
                                            ? column_raw_data[row] * flag
596
55
                                            : (flag ? column_raw_data[row] : 0);
597
181
        } else {
598
181
            result_raw_data[row] +=
599
181
                    column_raw_data[row] *
600
181
                    typename ColumnType::value_type(!(null_map_data[row] | filled_flag[row]));
601
181
        }
602
603
258
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
604
258
    }
605
102
}
Unexecuted instantiation: _ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE2EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
_ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE3EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Line
Count
Source
552
12
                        const size_t input_rows_count) {
553
12
    if (result_column->size() == 0 && input_rows_count) {
554
6
        result_column->resize(input_rows_count);
555
6
        auto* __restrict result_raw_data =
556
6
                assert_cast<ColumnType*>(result_column.get())->get_data().data();
557
26
        for (int i = 0; i < input_rows_count; i++) {
558
20
            result_raw_data[i] = {};
559
20
        }
560
6
    }
561
12
    auto* __restrict result_raw_data =
562
12
            assert_cast<ColumnType*>(result_column.get())->get_data().data();
563
12
    auto* __restrict column_raw_data =
564
12
            assert_cast<const ColumnType*>(argument_column.get())->get_data().data();
565
566
    // Here it's SIMD thought the compiler automatically also
567
    // true: null_map_data[row]==0 && filled_idx[row]==0
568
    // if true, could filled current row data into result column
569
52
    for (size_t row = 0; row < input_rows_count; ++row) {
570
        if constexpr (std::is_same_v<ColumnType, ColumnDateV2>) {
571
            result_raw_data[row] = binary_cast<uint32_t, DateV2Value<DateV2ValueType>>(
572
                    result_raw_data[row].to_date_int_val() +
573
                    column_raw_data[row].to_date_int_val() *
574
                            uint32_t(!(null_map_data[row] | filled_flag[row])));
575
        } else if constexpr (std::is_same_v<ColumnType, ColumnDateTimeV2>) {
576
            result_raw_data[row] = binary_cast<uint64_t, DateV2Value<DateTimeV2ValueType>>(
577
                    result_raw_data[row].to_date_int_val() +
578
                    column_raw_data[row].to_date_int_val() *
579
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
580
        } else if constexpr (std::is_same_v<ColumnType, ColumnTimeStampTz>) {
581
            result_raw_data[row] = binary_cast<uint64_t, TimestampTzValue>(
582
                    result_raw_data[row].to_date_int_val() +
583
                    column_raw_data[row].to_date_int_val() *
584
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
585
        } else if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
586
                             std::is_same_v<ColumnType, ColumnDateTime>) {
587
            result_raw_data[row] = binary_cast<int64_t, VecDateTimeValue>(
588
                    binary_cast<VecDateTimeValue, int64_t>(result_raw_data[row]) +
589
                    binary_cast<VecDateTimeValue, int64_t>(column_raw_data[row]) *
590
                            int64_t(!(null_map_data[row] | filled_flag[row])));
591
        } else if constexpr (std::is_same_v<ColumnType, ColumnFloat32> ||
592
                             std::is_same_v<ColumnType, ColumnFloat64>) {
593
            auto flag = (!(null_map_data[row] | filled_flag[row]));
594
            result_raw_data[row] += std::isfinite(column_raw_data[row])
595
                                            ? column_raw_data[row] * flag
596
                                            : (flag ? column_raw_data[row] : 0);
597
40
        } else {
598
40
            result_raw_data[row] +=
599
40
                    column_raw_data[row] *
600
40
                    typename ColumnType::value_type(!(null_map_data[row] | filled_flag[row]));
601
40
        }
602
603
40
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
604
40
    }
605
12
}
_ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE4EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Line
Count
Source
552
4
                        const size_t input_rows_count) {
553
4
    if (result_column->size() == 0 && input_rows_count) {
554
2
        result_column->resize(input_rows_count);
555
2
        auto* __restrict result_raw_data =
556
2
                assert_cast<ColumnType*>(result_column.get())->get_data().data();
557
4
        for (int i = 0; i < input_rows_count; i++) {
558
2
            result_raw_data[i] = {};
559
2
        }
560
2
    }
561
4
    auto* __restrict result_raw_data =
562
4
            assert_cast<ColumnType*>(result_column.get())->get_data().data();
563
4
    auto* __restrict column_raw_data =
564
4
            assert_cast<const ColumnType*>(argument_column.get())->get_data().data();
565
566
    // Here it's SIMD thought the compiler automatically also
567
    // true: null_map_data[row]==0 && filled_idx[row]==0
568
    // if true, could filled current row data into result column
569
8
    for (size_t row = 0; row < input_rows_count; ++row) {
570
        if constexpr (std::is_same_v<ColumnType, ColumnDateV2>) {
571
            result_raw_data[row] = binary_cast<uint32_t, DateV2Value<DateV2ValueType>>(
572
                    result_raw_data[row].to_date_int_val() +
573
                    column_raw_data[row].to_date_int_val() *
574
                            uint32_t(!(null_map_data[row] | filled_flag[row])));
575
        } else if constexpr (std::is_same_v<ColumnType, ColumnDateTimeV2>) {
576
            result_raw_data[row] = binary_cast<uint64_t, DateV2Value<DateTimeV2ValueType>>(
577
                    result_raw_data[row].to_date_int_val() +
578
                    column_raw_data[row].to_date_int_val() *
579
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
580
        } else if constexpr (std::is_same_v<ColumnType, ColumnTimeStampTz>) {
581
            result_raw_data[row] = binary_cast<uint64_t, TimestampTzValue>(
582
                    result_raw_data[row].to_date_int_val() +
583
                    column_raw_data[row].to_date_int_val() *
584
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
585
        } else if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
586
                             std::is_same_v<ColumnType, ColumnDateTime>) {
587
            result_raw_data[row] = binary_cast<int64_t, VecDateTimeValue>(
588
                    binary_cast<VecDateTimeValue, int64_t>(result_raw_data[row]) +
589
                    binary_cast<VecDateTimeValue, int64_t>(column_raw_data[row]) *
590
                            int64_t(!(null_map_data[row] | filled_flag[row])));
591
        } else if constexpr (std::is_same_v<ColumnType, ColumnFloat32> ||
592
                             std::is_same_v<ColumnType, ColumnFloat64>) {
593
            auto flag = (!(null_map_data[row] | filled_flag[row]));
594
            result_raw_data[row] += std::isfinite(column_raw_data[row])
595
                                            ? column_raw_data[row] * flag
596
                                            : (flag ? column_raw_data[row] : 0);
597
4
        } else {
598
4
            result_raw_data[row] +=
599
4
                    column_raw_data[row] *
600
4
                    typename ColumnType::value_type(!(null_map_data[row] | filled_flag[row]));
601
4
        }
602
603
4
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
604
4
    }
605
4
}
_ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE5EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Line
Count
Source
552
40
                        const size_t input_rows_count) {
553
40
    if (result_column->size() == 0 && input_rows_count) {
554
20
        result_column->resize(input_rows_count);
555
20
        auto* __restrict result_raw_data =
556
20
                assert_cast<ColumnType*>(result_column.get())->get_data().data();
557
72
        for (int i = 0; i < input_rows_count; i++) {
558
52
            result_raw_data[i] = {};
559
52
        }
560
20
    }
561
40
    auto* __restrict result_raw_data =
562
40
            assert_cast<ColumnType*>(result_column.get())->get_data().data();
563
40
    auto* __restrict column_raw_data =
564
40
            assert_cast<const ColumnType*>(argument_column.get())->get_data().data();
565
566
    // Here it's SIMD thought the compiler automatically also
567
    // true: null_map_data[row]==0 && filled_idx[row]==0
568
    // if true, could filled current row data into result column
569
160
    for (size_t row = 0; row < input_rows_count; ++row) {
570
        if constexpr (std::is_same_v<ColumnType, ColumnDateV2>) {
571
            result_raw_data[row] = binary_cast<uint32_t, DateV2Value<DateV2ValueType>>(
572
                    result_raw_data[row].to_date_int_val() +
573
                    column_raw_data[row].to_date_int_val() *
574
                            uint32_t(!(null_map_data[row] | filled_flag[row])));
575
        } else if constexpr (std::is_same_v<ColumnType, ColumnDateTimeV2>) {
576
            result_raw_data[row] = binary_cast<uint64_t, DateV2Value<DateTimeV2ValueType>>(
577
                    result_raw_data[row].to_date_int_val() +
578
                    column_raw_data[row].to_date_int_val() *
579
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
580
        } else if constexpr (std::is_same_v<ColumnType, ColumnTimeStampTz>) {
581
            result_raw_data[row] = binary_cast<uint64_t, TimestampTzValue>(
582
                    result_raw_data[row].to_date_int_val() +
583
                    column_raw_data[row].to_date_int_val() *
584
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
585
        } else if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
586
                             std::is_same_v<ColumnType, ColumnDateTime>) {
587
            result_raw_data[row] = binary_cast<int64_t, VecDateTimeValue>(
588
                    binary_cast<VecDateTimeValue, int64_t>(result_raw_data[row]) +
589
                    binary_cast<VecDateTimeValue, int64_t>(column_raw_data[row]) *
590
                            int64_t(!(null_map_data[row] | filled_flag[row])));
591
        } else if constexpr (std::is_same_v<ColumnType, ColumnFloat32> ||
592
                             std::is_same_v<ColumnType, ColumnFloat64>) {
593
            auto flag = (!(null_map_data[row] | filled_flag[row]));
594
            result_raw_data[row] += std::isfinite(column_raw_data[row])
595
                                            ? column_raw_data[row] * flag
596
                                            : (flag ? column_raw_data[row] : 0);
597
120
        } else {
598
120
            result_raw_data[row] +=
599
120
                    column_raw_data[row] *
600
120
                    typename ColumnType::value_type(!(null_map_data[row] | filled_flag[row]));
601
120
        }
602
603
120
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
604
120
    }
605
40
}
_ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Line
Count
Source
552
5
                        const size_t input_rows_count) {
553
5
    if (result_column->size() == 0 && input_rows_count) {
554
4
        result_column->resize(input_rows_count);
555
4
        auto* __restrict result_raw_data =
556
4
                assert_cast<ColumnType*>(result_column.get())->get_data().data();
557
8
        for (int i = 0; i < input_rows_count; i++) {
558
4
            result_raw_data[i] = {};
559
4
        }
560
4
    }
561
5
    auto* __restrict result_raw_data =
562
5
            assert_cast<ColumnType*>(result_column.get())->get_data().data();
563
5
    auto* __restrict column_raw_data =
564
5
            assert_cast<const ColumnType*>(argument_column.get())->get_data().data();
565
566
    // Here it's SIMD thought the compiler automatically also
567
    // true: null_map_data[row]==0 && filled_idx[row]==0
568
    // if true, could filled current row data into result column
569
10
    for (size_t row = 0; row < input_rows_count; ++row) {
570
        if constexpr (std::is_same_v<ColumnType, ColumnDateV2>) {
571
            result_raw_data[row] = binary_cast<uint32_t, DateV2Value<DateV2ValueType>>(
572
                    result_raw_data[row].to_date_int_val() +
573
                    column_raw_data[row].to_date_int_val() *
574
                            uint32_t(!(null_map_data[row] | filled_flag[row])));
575
        } else if constexpr (std::is_same_v<ColumnType, ColumnDateTimeV2>) {
576
            result_raw_data[row] = binary_cast<uint64_t, DateV2Value<DateTimeV2ValueType>>(
577
                    result_raw_data[row].to_date_int_val() +
578
                    column_raw_data[row].to_date_int_val() *
579
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
580
        } else if constexpr (std::is_same_v<ColumnType, ColumnTimeStampTz>) {
581
            result_raw_data[row] = binary_cast<uint64_t, TimestampTzValue>(
582
                    result_raw_data[row].to_date_int_val() +
583
                    column_raw_data[row].to_date_int_val() *
584
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
585
        } else if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
586
                             std::is_same_v<ColumnType, ColumnDateTime>) {
587
            result_raw_data[row] = binary_cast<int64_t, VecDateTimeValue>(
588
                    binary_cast<VecDateTimeValue, int64_t>(result_raw_data[row]) +
589
                    binary_cast<VecDateTimeValue, int64_t>(column_raw_data[row]) *
590
                            int64_t(!(null_map_data[row] | filled_flag[row])));
591
        } else if constexpr (std::is_same_v<ColumnType, ColumnFloat32> ||
592
                             std::is_same_v<ColumnType, ColumnFloat64>) {
593
            auto flag = (!(null_map_data[row] | filled_flag[row]));
594
            result_raw_data[row] += std::isfinite(column_raw_data[row])
595
                                            ? column_raw_data[row] * flag
596
                                            : (flag ? column_raw_data[row] : 0);
597
5
        } else {
598
5
            result_raw_data[row] +=
599
5
                    column_raw_data[row] *
600
5
                    typename ColumnType::value_type(!(null_map_data[row] | filled_flag[row]));
601
5
        }
602
603
5
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
604
5
    }
605
5
}
Unexecuted instantiation: _ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE7EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
_ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE8EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Line
Count
Source
552
4
                        const size_t input_rows_count) {
553
4
    if (result_column->size() == 0 && input_rows_count) {
554
2
        result_column->resize(input_rows_count);
555
2
        auto* __restrict result_raw_data =
556
2
                assert_cast<ColumnType*>(result_column.get())->get_data().data();
557
5
        for (int i = 0; i < input_rows_count; i++) {
558
3
            result_raw_data[i] = {};
559
3
        }
560
2
    }
561
4
    auto* __restrict result_raw_data =
562
4
            assert_cast<ColumnType*>(result_column.get())->get_data().data();
563
4
    auto* __restrict column_raw_data =
564
4
            assert_cast<const ColumnType*>(argument_column.get())->get_data().data();
565
566
    // Here it's SIMD thought the compiler automatically also
567
    // true: null_map_data[row]==0 && filled_idx[row]==0
568
    // if true, could filled current row data into result column
569
10
    for (size_t row = 0; row < input_rows_count; ++row) {
570
        if constexpr (std::is_same_v<ColumnType, ColumnDateV2>) {
571
            result_raw_data[row] = binary_cast<uint32_t, DateV2Value<DateV2ValueType>>(
572
                    result_raw_data[row].to_date_int_val() +
573
                    column_raw_data[row].to_date_int_val() *
574
                            uint32_t(!(null_map_data[row] | filled_flag[row])));
575
        } else if constexpr (std::is_same_v<ColumnType, ColumnDateTimeV2>) {
576
            result_raw_data[row] = binary_cast<uint64_t, DateV2Value<DateTimeV2ValueType>>(
577
                    result_raw_data[row].to_date_int_val() +
578
                    column_raw_data[row].to_date_int_val() *
579
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
580
        } else if constexpr (std::is_same_v<ColumnType, ColumnTimeStampTz>) {
581
            result_raw_data[row] = binary_cast<uint64_t, TimestampTzValue>(
582
                    result_raw_data[row].to_date_int_val() +
583
                    column_raw_data[row].to_date_int_val() *
584
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
585
        } else if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
586
                             std::is_same_v<ColumnType, ColumnDateTime>) {
587
            result_raw_data[row] = binary_cast<int64_t, VecDateTimeValue>(
588
                    binary_cast<VecDateTimeValue, int64_t>(result_raw_data[row]) +
589
                    binary_cast<VecDateTimeValue, int64_t>(column_raw_data[row]) *
590
                            int64_t(!(null_map_data[row] | filled_flag[row])));
591
        } else if constexpr (std::is_same_v<ColumnType, ColumnFloat32> ||
592
6
                             std::is_same_v<ColumnType, ColumnFloat64>) {
593
6
            auto flag = (!(null_map_data[row] | filled_flag[row]));
594
6
            result_raw_data[row] += std::isfinite(column_raw_data[row])
595
6
                                            ? column_raw_data[row] * flag
596
6
                                            : (flag ? column_raw_data[row] : 0);
597
        } else {
598
            result_raw_data[row] +=
599
                    column_raw_data[row] *
600
                    typename ColumnType::value_type(!(null_map_data[row] | filled_flag[row]));
601
        }
602
603
6
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
604
6
    }
605
4
}
_ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE9EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Line
Count
Source
552
21
                        const size_t input_rows_count) {
553
21
    if (result_column->size() == 0 && input_rows_count) {
554
12
        result_column->resize(input_rows_count);
555
12
        auto* __restrict result_raw_data =
556
12
                assert_cast<ColumnType*>(result_column.get())->get_data().data();
557
35
        for (int i = 0; i < input_rows_count; i++) {
558
23
            result_raw_data[i] = {};
559
23
        }
560
12
    }
561
21
    auto* __restrict result_raw_data =
562
21
            assert_cast<ColumnType*>(result_column.get())->get_data().data();
563
21
    auto* __restrict column_raw_data =
564
21
            assert_cast<const ColumnType*>(argument_column.get())->get_data().data();
565
566
    // Here it's SIMD thought the compiler automatically also
567
    // true: null_map_data[row]==0 && filled_idx[row]==0
568
    // if true, could filled current row data into result column
569
70
    for (size_t row = 0; row < input_rows_count; ++row) {
570
        if constexpr (std::is_same_v<ColumnType, ColumnDateV2>) {
571
            result_raw_data[row] = binary_cast<uint32_t, DateV2Value<DateV2ValueType>>(
572
                    result_raw_data[row].to_date_int_val() +
573
                    column_raw_data[row].to_date_int_val() *
574
                            uint32_t(!(null_map_data[row] | filled_flag[row])));
575
        } else if constexpr (std::is_same_v<ColumnType, ColumnDateTimeV2>) {
576
            result_raw_data[row] = binary_cast<uint64_t, DateV2Value<DateTimeV2ValueType>>(
577
                    result_raw_data[row].to_date_int_val() +
578
                    column_raw_data[row].to_date_int_val() *
579
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
580
        } else if constexpr (std::is_same_v<ColumnType, ColumnTimeStampTz>) {
581
            result_raw_data[row] = binary_cast<uint64_t, TimestampTzValue>(
582
                    result_raw_data[row].to_date_int_val() +
583
                    column_raw_data[row].to_date_int_val() *
584
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
585
        } else if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
586
                             std::is_same_v<ColumnType, ColumnDateTime>) {
587
            result_raw_data[row] = binary_cast<int64_t, VecDateTimeValue>(
588
                    binary_cast<VecDateTimeValue, int64_t>(result_raw_data[row]) +
589
                    binary_cast<VecDateTimeValue, int64_t>(column_raw_data[row]) *
590
                            int64_t(!(null_map_data[row] | filled_flag[row])));
591
        } else if constexpr (std::is_same_v<ColumnType, ColumnFloat32> ||
592
49
                             std::is_same_v<ColumnType, ColumnFloat64>) {
593
49
            auto flag = (!(null_map_data[row] | filled_flag[row]));
594
49
            result_raw_data[row] += std::isfinite(column_raw_data[row])
595
49
                                            ? column_raw_data[row] * flag
596
49
                                            : (flag ? column_raw_data[row] : 0);
597
        } else {
598
            result_raw_data[row] +=
599
                    column_raw_data[row] *
600
                    typename ColumnType::value_type(!(null_map_data[row] | filled_flag[row]));
601
        }
602
603
49
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
604
49
    }
605
21
}
_ZN5doris18insert_result_dataINS_13ColumnDecimalILNS_13PrimitiveTypeE28EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Line
Count
Source
552
2
                        const size_t input_rows_count) {
553
2
    if (result_column->size() == 0 && input_rows_count) {
554
1
        result_column->resize(input_rows_count);
555
1
        auto* __restrict result_raw_data =
556
1
                assert_cast<ColumnType*>(result_column.get())->get_data().data();
557
2
        for (int i = 0; i < input_rows_count; i++) {
558
1
            result_raw_data[i] = {};
559
1
        }
560
1
    }
561
2
    auto* __restrict result_raw_data =
562
2
            assert_cast<ColumnType*>(result_column.get())->get_data().data();
563
2
    auto* __restrict column_raw_data =
564
2
            assert_cast<const ColumnType*>(argument_column.get())->get_data().data();
565
566
    // Here it's SIMD thought the compiler automatically also
567
    // true: null_map_data[row]==0 && filled_idx[row]==0
568
    // if true, could filled current row data into result column
569
4
    for (size_t row = 0; row < input_rows_count; ++row) {
570
        if constexpr (std::is_same_v<ColumnType, ColumnDateV2>) {
571
            result_raw_data[row] = binary_cast<uint32_t, DateV2Value<DateV2ValueType>>(
572
                    result_raw_data[row].to_date_int_val() +
573
                    column_raw_data[row].to_date_int_val() *
574
                            uint32_t(!(null_map_data[row] | filled_flag[row])));
575
        } else if constexpr (std::is_same_v<ColumnType, ColumnDateTimeV2>) {
576
            result_raw_data[row] = binary_cast<uint64_t, DateV2Value<DateTimeV2ValueType>>(
577
                    result_raw_data[row].to_date_int_val() +
578
                    column_raw_data[row].to_date_int_val() *
579
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
580
        } else if constexpr (std::is_same_v<ColumnType, ColumnTimeStampTz>) {
581
            result_raw_data[row] = binary_cast<uint64_t, TimestampTzValue>(
582
                    result_raw_data[row].to_date_int_val() +
583
                    column_raw_data[row].to_date_int_val() *
584
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
585
        } else if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
586
                             std::is_same_v<ColumnType, ColumnDateTime>) {
587
            result_raw_data[row] = binary_cast<int64_t, VecDateTimeValue>(
588
                    binary_cast<VecDateTimeValue, int64_t>(result_raw_data[row]) +
589
                    binary_cast<VecDateTimeValue, int64_t>(column_raw_data[row]) *
590
                            int64_t(!(null_map_data[row] | filled_flag[row])));
591
        } else if constexpr (std::is_same_v<ColumnType, ColumnFloat32> ||
592
                             std::is_same_v<ColumnType, ColumnFloat64>) {
593
            auto flag = (!(null_map_data[row] | filled_flag[row]));
594
            result_raw_data[row] += std::isfinite(column_raw_data[row])
595
                                            ? column_raw_data[row] * flag
596
                                            : (flag ? column_raw_data[row] : 0);
597
2
        } else {
598
2
            result_raw_data[row] +=
599
2
                    column_raw_data[row] *
600
2
                    typename ColumnType::value_type(!(null_map_data[row] | filled_flag[row]));
601
2
        }
602
603
2
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
604
2
    }
605
2
}
Unexecuted instantiation: _ZN5doris18insert_result_dataINS_13ColumnDecimalILNS_13PrimitiveTypeE29EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Unexecuted instantiation: _ZN5doris18insert_result_dataINS_13ColumnDecimalILNS_13PrimitiveTypeE20EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
_ZN5doris18insert_result_dataINS_13ColumnDecimalILNS_13PrimitiveTypeE30EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Line
Count
Source
552
2
                        const size_t input_rows_count) {
553
2
    if (result_column->size() == 0 && input_rows_count) {
554
1
        result_column->resize(input_rows_count);
555
1
        auto* __restrict result_raw_data =
556
1
                assert_cast<ColumnType*>(result_column.get())->get_data().data();
557
3
        for (int i = 0; i < input_rows_count; i++) {
558
2
            result_raw_data[i] = {};
559
2
        }
560
1
    }
561
2
    auto* __restrict result_raw_data =
562
2
            assert_cast<ColumnType*>(result_column.get())->get_data().data();
563
2
    auto* __restrict column_raw_data =
564
2
            assert_cast<const ColumnType*>(argument_column.get())->get_data().data();
565
566
    // Here it's SIMD thought the compiler automatically also
567
    // true: null_map_data[row]==0 && filled_idx[row]==0
568
    // if true, could filled current row data into result column
569
6
    for (size_t row = 0; row < input_rows_count; ++row) {
570
        if constexpr (std::is_same_v<ColumnType, ColumnDateV2>) {
571
            result_raw_data[row] = binary_cast<uint32_t, DateV2Value<DateV2ValueType>>(
572
                    result_raw_data[row].to_date_int_val() +
573
                    column_raw_data[row].to_date_int_val() *
574
                            uint32_t(!(null_map_data[row] | filled_flag[row])));
575
        } else if constexpr (std::is_same_v<ColumnType, ColumnDateTimeV2>) {
576
            result_raw_data[row] = binary_cast<uint64_t, DateV2Value<DateTimeV2ValueType>>(
577
                    result_raw_data[row].to_date_int_val() +
578
                    column_raw_data[row].to_date_int_val() *
579
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
580
        } else if constexpr (std::is_same_v<ColumnType, ColumnTimeStampTz>) {
581
            result_raw_data[row] = binary_cast<uint64_t, TimestampTzValue>(
582
                    result_raw_data[row].to_date_int_val() +
583
                    column_raw_data[row].to_date_int_val() *
584
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
585
        } else if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
586
                             std::is_same_v<ColumnType, ColumnDateTime>) {
587
            result_raw_data[row] = binary_cast<int64_t, VecDateTimeValue>(
588
                    binary_cast<VecDateTimeValue, int64_t>(result_raw_data[row]) +
589
                    binary_cast<VecDateTimeValue, int64_t>(column_raw_data[row]) *
590
                            int64_t(!(null_map_data[row] | filled_flag[row])));
591
        } else if constexpr (std::is_same_v<ColumnType, ColumnFloat32> ||
592
                             std::is_same_v<ColumnType, ColumnFloat64>) {
593
            auto flag = (!(null_map_data[row] | filled_flag[row]));
594
            result_raw_data[row] += std::isfinite(column_raw_data[row])
595
                                            ? column_raw_data[row] * flag
596
                                            : (flag ? column_raw_data[row] : 0);
597
4
        } else {
598
4
            result_raw_data[row] +=
599
4
                    column_raw_data[row] *
600
4
                    typename ColumnType::value_type(!(null_map_data[row] | filled_flag[row]));
601
4
        }
602
603
4
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
604
4
    }
605
2
}
_ZN5doris18insert_result_dataINS_13ColumnDecimalILNS_13PrimitiveTypeE35EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Line
Count
Source
552
2
                        const size_t input_rows_count) {
553
2
    if (result_column->size() == 0 && input_rows_count) {
554
1
        result_column->resize(input_rows_count);
555
1
        auto* __restrict result_raw_data =
556
1
                assert_cast<ColumnType*>(result_column.get())->get_data().data();
557
4
        for (int i = 0; i < input_rows_count; i++) {
558
3
            result_raw_data[i] = {};
559
3
        }
560
1
    }
561
2
    auto* __restrict result_raw_data =
562
2
            assert_cast<ColumnType*>(result_column.get())->get_data().data();
563
2
    auto* __restrict column_raw_data =
564
2
            assert_cast<const ColumnType*>(argument_column.get())->get_data().data();
565
566
    // Here it's SIMD thought the compiler automatically also
567
    // true: null_map_data[row]==0 && filled_idx[row]==0
568
    // if true, could filled current row data into result column
569
8
    for (size_t row = 0; row < input_rows_count; ++row) {
570
        if constexpr (std::is_same_v<ColumnType, ColumnDateV2>) {
571
            result_raw_data[row] = binary_cast<uint32_t, DateV2Value<DateV2ValueType>>(
572
                    result_raw_data[row].to_date_int_val() +
573
                    column_raw_data[row].to_date_int_val() *
574
                            uint32_t(!(null_map_data[row] | filled_flag[row])));
575
        } else if constexpr (std::is_same_v<ColumnType, ColumnDateTimeV2>) {
576
            result_raw_data[row] = binary_cast<uint64_t, DateV2Value<DateTimeV2ValueType>>(
577
                    result_raw_data[row].to_date_int_val() +
578
                    column_raw_data[row].to_date_int_val() *
579
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
580
        } else if constexpr (std::is_same_v<ColumnType, ColumnTimeStampTz>) {
581
            result_raw_data[row] = binary_cast<uint64_t, TimestampTzValue>(
582
                    result_raw_data[row].to_date_int_val() +
583
                    column_raw_data[row].to_date_int_val() *
584
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
585
        } else if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
586
                             std::is_same_v<ColumnType, ColumnDateTime>) {
587
            result_raw_data[row] = binary_cast<int64_t, VecDateTimeValue>(
588
                    binary_cast<VecDateTimeValue, int64_t>(result_raw_data[row]) +
589
                    binary_cast<VecDateTimeValue, int64_t>(column_raw_data[row]) *
590
                            int64_t(!(null_map_data[row] | filled_flag[row])));
591
        } else if constexpr (std::is_same_v<ColumnType, ColumnFloat32> ||
592
                             std::is_same_v<ColumnType, ColumnFloat64>) {
593
            auto flag = (!(null_map_data[row] | filled_flag[row]));
594
            result_raw_data[row] += std::isfinite(column_raw_data[row])
595
                                            ? column_raw_data[row] * flag
596
                                            : (flag ? column_raw_data[row] : 0);
597
6
        } else {
598
6
            result_raw_data[row] +=
599
6
                    column_raw_data[row] *
600
6
                    typename ColumnType::value_type(!(null_map_data[row] | filled_flag[row]));
601
6
        }
602
603
6
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
604
6
    }
605
2
}
Unexecuted instantiation: _ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE11EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
_ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE25EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Line
Count
Source
552
6
                        const size_t input_rows_count) {
553
6
    if (result_column->size() == 0 && input_rows_count) {
554
3
        result_column->resize(input_rows_count);
555
3
        auto* __restrict result_raw_data =
556
3
                assert_cast<ColumnType*>(result_column.get())->get_data().data();
557
10
        for (int i = 0; i < input_rows_count; i++) {
558
7
            result_raw_data[i] = {};
559
7
        }
560
3
    }
561
6
    auto* __restrict result_raw_data =
562
6
            assert_cast<ColumnType*>(result_column.get())->get_data().data();
563
6
    auto* __restrict column_raw_data =
564
6
            assert_cast<const ColumnType*>(argument_column.get())->get_data().data();
565
566
    // Here it's SIMD thought the compiler automatically also
567
    // true: null_map_data[row]==0 && filled_idx[row]==0
568
    // if true, could filled current row data into result column
569
20
    for (size_t row = 0; row < input_rows_count; ++row) {
570
14
        if constexpr (std::is_same_v<ColumnType, ColumnDateV2>) {
571
14
            result_raw_data[row] = binary_cast<uint32_t, DateV2Value<DateV2ValueType>>(
572
14
                    result_raw_data[row].to_date_int_val() +
573
14
                    column_raw_data[row].to_date_int_val() *
574
14
                            uint32_t(!(null_map_data[row] | filled_flag[row])));
575
        } else if constexpr (std::is_same_v<ColumnType, ColumnDateTimeV2>) {
576
            result_raw_data[row] = binary_cast<uint64_t, DateV2Value<DateTimeV2ValueType>>(
577
                    result_raw_data[row].to_date_int_val() +
578
                    column_raw_data[row].to_date_int_val() *
579
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
580
        } else if constexpr (std::is_same_v<ColumnType, ColumnTimeStampTz>) {
581
            result_raw_data[row] = binary_cast<uint64_t, TimestampTzValue>(
582
                    result_raw_data[row].to_date_int_val() +
583
                    column_raw_data[row].to_date_int_val() *
584
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
585
        } else if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
586
                             std::is_same_v<ColumnType, ColumnDateTime>) {
587
            result_raw_data[row] = binary_cast<int64_t, VecDateTimeValue>(
588
                    binary_cast<VecDateTimeValue, int64_t>(result_raw_data[row]) +
589
                    binary_cast<VecDateTimeValue, int64_t>(column_raw_data[row]) *
590
                            int64_t(!(null_map_data[row] | filled_flag[row])));
591
        } else if constexpr (std::is_same_v<ColumnType, ColumnFloat32> ||
592
                             std::is_same_v<ColumnType, ColumnFloat64>) {
593
            auto flag = (!(null_map_data[row] | filled_flag[row]));
594
            result_raw_data[row] += std::isfinite(column_raw_data[row])
595
                                            ? column_raw_data[row] * flag
596
                                            : (flag ? column_raw_data[row] : 0);
597
        } else {
598
            result_raw_data[row] +=
599
                    column_raw_data[row] *
600
                    typename ColumnType::value_type(!(null_map_data[row] | filled_flag[row]));
601
        }
602
603
14
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
604
14
    }
605
6
}
_ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE26EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Line
Count
Source
552
4
                        const size_t input_rows_count) {
553
4
    if (result_column->size() == 0 && input_rows_count) {
554
2
        result_column->resize(input_rows_count);
555
2
        auto* __restrict result_raw_data =
556
2
                assert_cast<ColumnType*>(result_column.get())->get_data().data();
557
6
        for (int i = 0; i < input_rows_count; i++) {
558
4
            result_raw_data[i] = {};
559
4
        }
560
2
    }
561
4
    auto* __restrict result_raw_data =
562
4
            assert_cast<ColumnType*>(result_column.get())->get_data().data();
563
4
    auto* __restrict column_raw_data =
564
4
            assert_cast<const ColumnType*>(argument_column.get())->get_data().data();
565
566
    // Here it's SIMD thought the compiler automatically also
567
    // true: null_map_data[row]==0 && filled_idx[row]==0
568
    // if true, could filled current row data into result column
569
12
    for (size_t row = 0; row < input_rows_count; ++row) {
570
        if constexpr (std::is_same_v<ColumnType, ColumnDateV2>) {
571
            result_raw_data[row] = binary_cast<uint32_t, DateV2Value<DateV2ValueType>>(
572
                    result_raw_data[row].to_date_int_val() +
573
                    column_raw_data[row].to_date_int_val() *
574
                            uint32_t(!(null_map_data[row] | filled_flag[row])));
575
8
        } else if constexpr (std::is_same_v<ColumnType, ColumnDateTimeV2>) {
576
8
            result_raw_data[row] = binary_cast<uint64_t, DateV2Value<DateTimeV2ValueType>>(
577
8
                    result_raw_data[row].to_date_int_val() +
578
8
                    column_raw_data[row].to_date_int_val() *
579
8
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
580
        } else if constexpr (std::is_same_v<ColumnType, ColumnTimeStampTz>) {
581
            result_raw_data[row] = binary_cast<uint64_t, TimestampTzValue>(
582
                    result_raw_data[row].to_date_int_val() +
583
                    column_raw_data[row].to_date_int_val() *
584
                            uint64_t(!(null_map_data[row] | filled_flag[row])));
585
        } else if constexpr (std::is_same_v<ColumnType, ColumnDate> ||
586
                             std::is_same_v<ColumnType, ColumnDateTime>) {
587
            result_raw_data[row] = binary_cast<int64_t, VecDateTimeValue>(
588
                    binary_cast<VecDateTimeValue, int64_t>(result_raw_data[row]) +
589
                    binary_cast<VecDateTimeValue, int64_t>(column_raw_data[row]) *
590
                            int64_t(!(null_map_data[row] | filled_flag[row])));
591
        } else if constexpr (std::is_same_v<ColumnType, ColumnFloat32> ||
592
                             std::is_same_v<ColumnType, ColumnFloat64>) {
593
            auto flag = (!(null_map_data[row] | filled_flag[row]));
594
            result_raw_data[row] += std::isfinite(column_raw_data[row])
595
                                            ? column_raw_data[row] * flag
596
                                            : (flag ? column_raw_data[row] : 0);
597
        } else {
598
            result_raw_data[row] +=
599
                    column_raw_data[row] *
600
                    typename ColumnType::value_type(!(null_map_data[row] | filled_flag[row]));
601
        }
602
603
8
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
604
8
    }
605
4
}
Unexecuted instantiation: _ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE12EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Unexecuted instantiation: _ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE27EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Unexecuted instantiation: _ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE42EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Unexecuted instantiation: _ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE36EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
Unexecuted instantiation: _ZN5doris18insert_result_dataINS_12ColumnVectorILNS_13PrimitiveTypeE37EEEEEvRNS_3COWINS_7IColumnEE11mutable_ptrIS5_EERNS6_13immutable_ptrIS5_EEPKhPhm
606
607
Status insert_result_data_bitmap(MutableColumnPtr& result_column, ColumnPtr& argument_column,
608
                                 const UInt8* __restrict null_map_data,
609
3
                                 UInt8* __restrict filled_flag, const size_t input_rows_count) {
610
3
    if (result_column->size() == 0 && input_rows_count) {
611
2
        result_column->resize(input_rows_count);
612
2
    }
613
614
3
    auto* __restrict result_raw_data =
615
3
            reinterpret_cast<ColumnBitmap*>(result_column.get())->get_data().data();
616
3
    auto* __restrict column_raw_data =
617
3
            reinterpret_cast<const ColumnBitmap*>(argument_column.get())->get_data().data();
618
619
    // Here it's SIMD thought the compiler automatically also
620
    // true: null_map_data[row]==0 && filled_idx[row]==0
621
    // if true, could filled current row data into result column
622
8
    for (size_t row = 0; row < input_rows_count; ++row) {
623
5
        if (!(null_map_data[row] | filled_flag[row])) {
624
2
            result_raw_data[row] = column_raw_data[row];
625
2
        }
626
5
        filled_flag[row] += (!(null_map_data[row] | filled_flag[row]));
627
5
    }
628
3
    return Status::OK();
629
3
}
630
631
Status filled_result_column(const DataTypePtr& data_type, MutableColumnPtr& result_column,
632
                            ColumnPtr& argument_column, UInt8* __restrict null_map_data,
633
105
                            UInt8* __restrict filled_flag, const size_t input_rows_count) {
634
105
    if (data_type->get_primitive_type() == TYPE_BITMAP) {
635
3
        return insert_result_data_bitmap(result_column, argument_column, null_map_data, filled_flag,
636
3
                                         input_rows_count);
637
3
    }
638
639
102
    auto call = [&](const auto& type) -> bool {
640
102
        using DispatchType = std::decay_t<decltype(type)>;
641
102
        insert_result_data<typename DispatchType::ColumnType>(
642
102
                result_column, argument_column, null_map_data, filled_flag, input_rows_count);
643
102
        return true;
644
102
    };
Unexecuted instantiation: vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE2EEEEEbRKT_
vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE3EEEEEbRKT_
Line
Count
Source
639
12
    auto call = [&](const auto& type) -> bool {
640
12
        using DispatchType = std::decay_t<decltype(type)>;
641
12
        insert_result_data<typename DispatchType::ColumnType>(
642
12
                result_column, argument_column, null_map_data, filled_flag, input_rows_count);
643
12
        return true;
644
12
    };
vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE4EEEEEbRKT_
Line
Count
Source
639
4
    auto call = [&](const auto& type) -> bool {
640
4
        using DispatchType = std::decay_t<decltype(type)>;
641
4
        insert_result_data<typename DispatchType::ColumnType>(
642
4
                result_column, argument_column, null_map_data, filled_flag, input_rows_count);
643
4
        return true;
644
4
    };
vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE5EEEEEbRKT_
Line
Count
Source
639
40
    auto call = [&](const auto& type) -> bool {
640
40
        using DispatchType = std::decay_t<decltype(type)>;
641
40
        insert_result_data<typename DispatchType::ColumnType>(
642
40
                result_column, argument_column, null_map_data, filled_flag, input_rows_count);
643
40
        return true;
644
40
    };
vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE6EEEEEbRKT_
Line
Count
Source
639
5
    auto call = [&](const auto& type) -> bool {
640
5
        using DispatchType = std::decay_t<decltype(type)>;
641
5
        insert_result_data<typename DispatchType::ColumnType>(
642
5
                result_column, argument_column, null_map_data, filled_flag, input_rows_count);
643
5
        return true;
644
5
    };
Unexecuted instantiation: vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE7EEEEEbRKT_
vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE8EEEEEbRKT_
Line
Count
Source
639
4
    auto call = [&](const auto& type) -> bool {
640
4
        using DispatchType = std::decay_t<decltype(type)>;
641
4
        insert_result_data<typename DispatchType::ColumnType>(
642
4
                result_column, argument_column, null_map_data, filled_flag, input_rows_count);
643
4
        return true;
644
4
    };
vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE9EEEEEbRKT_
Line
Count
Source
639
21
    auto call = [&](const auto& type) -> bool {
640
21
        using DispatchType = std::decay_t<decltype(type)>;
641
21
        insert_result_data<typename DispatchType::ColumnType>(
642
21
                result_column, argument_column, null_map_data, filled_flag, input_rows_count);
643
21
        return true;
644
21
    };
vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE28EEEEEbRKT_
Line
Count
Source
639
2
    auto call = [&](const auto& type) -> bool {
640
2
        using DispatchType = std::decay_t<decltype(type)>;
641
2
        insert_result_data<typename DispatchType::ColumnType>(
642
2
                result_column, argument_column, null_map_data, filled_flag, input_rows_count);
643
2
        return true;
644
2
    };
Unexecuted instantiation: vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE29EEEEEbRKT_
Unexecuted instantiation: vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE20EEEEEbRKT_
vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE30EEEEEbRKT_
Line
Count
Source
639
2
    auto call = [&](const auto& type) -> bool {
640
2
        using DispatchType = std::decay_t<decltype(type)>;
641
2
        insert_result_data<typename DispatchType::ColumnType>(
642
2
                result_column, argument_column, null_map_data, filled_flag, input_rows_count);
643
2
        return true;
644
2
    };
vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE35EEEEEbRKT_
Line
Count
Source
639
2
    auto call = [&](const auto& type) -> bool {
640
2
        using DispatchType = std::decay_t<decltype(type)>;
641
2
        insert_result_data<typename DispatchType::ColumnType>(
642
2
                result_column, argument_column, null_map_data, filled_flag, input_rows_count);
643
2
        return true;
644
2
    };
Unexecuted instantiation: vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE11EEEEEbRKT_
vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE25EEEEEbRKT_
Line
Count
Source
639
6
    auto call = [&](const auto& type) -> bool {
640
6
        using DispatchType = std::decay_t<decltype(type)>;
641
6
        insert_result_data<typename DispatchType::ColumnType>(
642
6
                result_column, argument_column, null_map_data, filled_flag, input_rows_count);
643
6
        return true;
644
6
    };
vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE26EEEEEbRKT_
Line
Count
Source
639
4
    auto call = [&](const auto& type) -> bool {
640
4
        using DispatchType = std::decay_t<decltype(type)>;
641
4
        insert_result_data<typename DispatchType::ColumnType>(
642
4
                result_column, argument_column, null_map_data, filled_flag, input_rows_count);
643
4
        return true;
644
4
    };
Unexecuted instantiation: vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE12EEEEEbRKT_
Unexecuted instantiation: vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE27EEEEEbRKT_
Unexecuted instantiation: vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE42EEEEEbRKT_
Unexecuted instantiation: vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE36EEEEEbRKT_
Unexecuted instantiation: vcondition_expr.cpp:_ZZN5doris20filled_result_columnERKSt10shared_ptrIKNS_9IDataTypeEERNS_3COWINS_7IColumnEE11mutable_ptrIS7_EERNS8_13immutable_ptrIS7_EEPhSF_mENK3$_0clINS_16DispatchDataTypeILNS_13PrimitiveTypeE37EEEEEbRKT_
645
646
102
    if (!dispatch_switch_scalar(data_type->get_primitive_type(), call)) {
647
0
        return Status::InternalError("not support type {} in coalesce", data_type->get_name());
648
0
    }
649
102
    return Status::OK();
650
102
}
651
652
Status VectorizedCoalesceExpr::execute_column_impl(VExprContext* context, const Block* block,
653
                                                   const Selector* selector, size_t count,
654
247
                                                   ColumnPtr& return_column) const {
655
247
    DataTypePtr result_type = _data_type;
656
247
    const auto input_rows_count = count;
657
658
247
    size_t remaining_rows = input_rows_count;
659
247
    std::vector<uint32_t> record_idx(
660
247
            input_rows_count,
661
247
            0); //used to save column idx, record the result data of each row from which column
662
247
    std::vector<uint8_t> filled_flags(
663
247
            input_rows_count,
664
247
            0); //used to save filled flag, in order to check current row whether have filled data
665
666
247
    MutableColumnPtr result_column;
667
247
    if (!result_type->is_nullable()) {
668
141
        result_column = result_type->create_column();
669
141
    } else {
670
106
        result_column = remove_nullable(result_type)->create_column();
671
106
    }
672
673
    // because now follow below types does not support random position writing,
674
    // so insert into result data have two methods, one is for these types, one is for others type remaining
675
247
    bool cannot_random_write = result_column->is_column_string() ||
676
247
                               result_type->get_primitive_type() == PrimitiveType::TYPE_MAP ||
677
247
                               result_type->get_primitive_type() == PrimitiveType::TYPE_STRUCT ||
678
247
                               result_type->get_primitive_type() == PrimitiveType::TYPE_ARRAY ||
679
247
                               result_type->get_primitive_type() == PrimitiveType::TYPE_JSONB;
680
247
    if (cannot_random_write) {
681
76
        result_column->reserve(input_rows_count);
682
76
    }
683
684
247
    auto return_type = std::make_shared<DataTypeUInt8>();
685
247
    auto null_map = ColumnUInt8::create(input_rows_count,
686
247
                                        1); //if null_map_data==1, the current row should be null
687
247
    auto* __restrict null_map_data = null_map->get_data().data();
688
689
348
    auto is_not_null = [](const ColumnPtr& column, size_t size) -> ColumnUInt8::MutablePtr {
690
348
        if (const auto* nullable = check_and_get_column<ColumnNullable>(*column)) {
691
            /// Return the negated null map.
692
269
            auto res_column = ColumnUInt8::create(size);
693
269
            const auto* __restrict src_data = nullable->get_null_map_data().data();
694
269
            auto* __restrict res_data = res_column->get_data().data();
695
696
917
            for (size_t i = 0; i < size; ++i) {
697
648
                res_data[i] = !src_data[i];
698
648
            }
699
269
            return res_column;
700
269
        } else {
701
            /// Since no element is nullable, return a constant one.
702
79
            return ColumnUInt8::create(size, 1);
703
79
        }
704
348
    };
705
706
247
    std::vector<ColumnPtr> original_columns(_children.size());
707
247
    std::vector<ColumnPtr> argument_not_null_columns(_children.size());
708
709
415
    for (size_t i = 0; i < _children.size() && remaining_rows; ++i) {
710
        // Execute child expression to get the argument column.
711
348
        RETURN_IF_ERROR(
712
348
                _children[i]->execute_column(context, block, selector, count, original_columns[i]));
713
348
        original_columns[i] = original_columns[i]->convert_to_full_column_if_const();
714
348
        argument_not_null_columns[i] = original_columns[i];
715
348
        if (const auto* nullable =
716
348
                    check_and_get_column<const ColumnNullable>(*argument_not_null_columns[i])) {
717
269
            argument_not_null_columns[i] = nullable->get_nested_column_ptr();
718
269
        }
719
720
348
        auto res_column = is_not_null(original_columns[i], input_rows_count);
721
722
348
        auto& res_map = res_column->get_data();
723
348
        auto* __restrict res = res_map.data();
724
725
        // Here it's SIMD thought the compiler automatically
726
        // true: res[j]==1 && null_map_data[j]==1, false: others
727
        // if true: remaining_rows--; record_idx[j]=column_idx; null_map_data[j]=0, so the current row could fill result
728
1.17k
        for (size_t j = 0; j < input_rows_count; ++j) {
729
827
            remaining_rows -= (res[j] & null_map_data[j]);
730
827
            record_idx[j] += (res[j] & null_map_data[j]) * i;
731
827
            null_map_data[j] -= (res[j] & null_map_data[j]);
732
827
        }
733
734
348
        if (remaining_rows == 0) {
735
            //check whether all result data from the same column
736
233
            size_t is_same_column_count = 0;
737
233
            const auto data = record_idx[0];
738
778
            for (size_t row = 0; row < input_rows_count; ++row) {
739
545
                is_same_column_count += (record_idx[row] == data);
740
545
            }
741
742
233
            if (is_same_column_count == input_rows_count) {
743
180
                if (result_type->is_nullable()) {
744
80
                    return_column = make_nullable(argument_not_null_columns[i]);
745
100
                } else {
746
100
                    return_column = argument_not_null_columns[i];
747
100
                }
748
180
                return Status::OK();
749
180
            }
750
233
        }
751
752
168
        if (!cannot_random_write) {
753
            //if not string type, could check one column firstly,
754
            //and then fill the not null value in result column,
755
            //this method may result in higher CPU cache
756
105
            RETURN_IF_ERROR(filled_result_column(result_type, result_column,
757
105
                                                 argument_not_null_columns[i], null_map_data,
758
105
                                                 filled_flags.data(), input_rows_count));
759
105
        }
760
168
    }
761
762
67
    if (cannot_random_write) {
763
        //if string type,  should according to the record results, fill in result one by one,
764
115
        for (size_t row = 0; row < input_rows_count; ++row) {
765
89
            if (null_map_data[row]) { //should be null
766
3
                result_column->insert_default();
767
86
            } else {
768
86
                result_column->insert_from(*argument_not_null_columns[record_idx[row]].get(), row);
769
86
            }
770
89
        }
771
26
    }
772
773
67
    if (result_type->is_nullable()) {
774
26
        return_column = ColumnNullable::create(std::move(result_column), std::move(null_map));
775
41
    } else {
776
41
        return_column = std::move(result_column);
777
41
    }
778
779
    DCHECK_EQ(return_column->size(), count);
780
67
    return Status::OK();
781
247
}
782
783
} // namespace doris