Coverage Report

Created: 2026-07-27 20:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/cast/cast_to_array.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "core/column/column_array.h"
19
#include "core/data_type/data_type_array.h"
20
#include "exprs/function/cast/cast_base.h"
21
22
namespace doris::CastWrapper {
23
8
inline bool has_null_literal_leaf(const DataTypePtr& type) {
24
8
    const auto type_without_nullable = remove_nullable(type);
25
8
    if (const auto* array_type =
26
8
                check_and_get_data_type<DataTypeArray>(type_without_nullable.get())) {
27
2
        return has_null_literal_leaf(array_type->get_nested_type());
28
2
    }
29
6
    return type_without_nullable->is_null_literal();
30
8
}
31
32
WrapperType create_array_wrapper(FunctionContext* context, const DataTypePtr& from_type_untyped,
33
3.01k
                                 const DataTypeArray& to_type) {
34
    /// Conversion from String through parsing.
35
3.01k
    if (check_and_get_data_type<DataTypeString>(from_type_untyped.get())) {
36
8
        if (context->enable_strict_mode()) {
37
0
            return cast_from_string_to_complex_type_strict_mode;
38
8
        } else {
39
8
            return cast_from_string_to_complex_type;
40
8
        }
41
8
    }
42
43
3.00k
    const auto* from_type = check_and_get_data_type<DataTypeArray>(from_type_untyped.get());
44
45
3.00k
    if (!from_type) {
46
2
        return CastWrapper::create_unsupport_wrapper(
47
2
                "CAST AS Array can only be performed between same-dimensional Array, String "
48
2
                "types");
49
2
    }
50
51
3.00k
    DataTypePtr from_nested_type = from_type->get_nested_type();
52
53
3.00k
    if (from_type->get_number_of_dimensions() != to_type.get_number_of_dimensions() &&
54
3.00k
        !has_null_literal_leaf(from_nested_type)) {
55
0
        return CastWrapper::create_unsupport_wrapper(
56
0
                "CAST AS Array can only be performed between same-dimensional array types");
57
0
    }
58
59
3.00k
    DataTypePtr to_nested_type = to_type.get_nested_type();
60
61
    /// Prepare nested type conversion
62
3.00k
    const auto nested_function =
63
3.00k
            prepare_unpack_dictionaries(context, from_nested_type, to_nested_type);
64
65
3.00k
    return [nested_function, from_nested_type, to_nested_type](
66
3.00k
                   FunctionContext* context, Block& block, const ColumnNumbers& arguments,
67
3.00k
                   uint32_t result, size_t /*input_rows_count*/,
68
3.00k
                   const NullMap::value_type* null_map = nullptr) -> Status {
69
3.00k
        ColumnPtr from_column = block.get_by_position(arguments.front()).column;
70
71
3.00k
        const auto* from_col_array = check_and_get_column<ColumnArray>(from_column.get());
72
73
3.00k
        if (from_col_array) {
74
            /// create columns for converting nested column containing original and result columns
75
3.00k
            ColumnWithTypeAndName from_nested_column {from_col_array->get_data_ptr(),
76
3.00k
                                                      from_nested_type, ""};
77
78
            /// convert nested column
79
3.00k
            ColumnNumbers new_arguments {block.columns()};
80
3.00k
            block.insert(from_nested_column);
81
82
3.00k
            uint32_t nested_result = block.columns();
83
3.00k
            block.insert({to_nested_type, ""});
84
3.00k
            RETURN_IF_ERROR(nested_function(context, block, new_arguments, nested_result,
85
3.00k
                                            from_col_array->get_data_ptr()->size(), null_map));
86
3.00k
            auto nested_result_column = block.get_by_position(nested_result).column;
87
88
            /// set converted nested column to result
89
3.00k
            block.get_by_position(result).column =
90
3.00k
                    ColumnArray::create(nested_result_column, from_col_array->get_offsets_ptr());
91
3.00k
        } else {
92
0
            return Status::RuntimeError("Illegal column {} for function CAST AS Array",
93
0
                                        from_column->get_name());
94
0
        }
95
3.00k
        return Status::OK();
96
3.00k
    };
97
3.00k
}
98
} // namespace doris::CastWrapper