Coverage Report

Created: 2026-07-17 11:15

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
4
inline bool has_null_literal_leaf(const DataTypePtr& type) {
24
4
    const auto type_without_nullable = remove_nullable(type);
25
4
    if (const auto* array_type =
26
4
                check_and_get_data_type<DataTypeArray>(type_without_nullable.get())) {
27
1
        return has_null_literal_leaf(array_type->get_nested_type());
28
1
    }
29
3
    return type_without_nullable->is_null_literal();
30
4
}
31
32
WrapperType create_array_wrapper(FunctionContext* context, const DataTypePtr& from_type_untyped,
33
1.46k
                                 const DataTypeArray& to_type) {
34
    /// Conversion from String through parsing.
35
1.46k
    if (check_and_get_data_type<DataTypeString>(from_type_untyped.get())) {
36
4
        if (context->enable_strict_mode()) {
37
0
            return cast_from_string_to_complex_type_strict_mode;
38
4
        } else {
39
4
            return cast_from_string_to_complex_type;
40
4
        }
41
4
    }
42
43
1.45k
    const auto* from_type = check_and_get_data_type<DataTypeArray>(from_type_untyped.get());
44
45
1.45k
    if (!from_type) {
46
1
        return CastWrapper::create_unsupport_wrapper(
47
1
                "CAST AS Array can only be performed between same-dimensional Array, String "
48
1
                "types");
49
1
    }
50
51
1.45k
    DataTypePtr from_nested_type = from_type->get_nested_type();
52
53
1.45k
    if (from_type->get_number_of_dimensions() != to_type.get_number_of_dimensions() &&
54
1.45k
        !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
1.45k
    DataTypePtr to_nested_type = to_type.get_nested_type();
60
61
    /// Prepare nested type conversion
62
1.45k
    const auto nested_function =
63
1.45k
            prepare_unpack_dictionaries(context, from_nested_type, to_nested_type);
64
65
1.45k
    return [nested_function, from_nested_type, to_nested_type](
66
1.45k
                   FunctionContext* context, Block& block, const ColumnNumbers& arguments,
67
1.45k
                   uint32_t result, size_t /*input_rows_count*/,
68
1.45k
                   const NullMap::value_type* null_map = nullptr) -> Status {
69
1.45k
        ColumnPtr from_column = block.get_by_position(arguments.front()).column;
70
71
1.45k
        const auto* from_col_array = check_and_get_column<ColumnArray>(from_column.get());
72
73
1.45k
        if (from_col_array) {
74
            /// create columns for converting nested column containing original and result columns
75
1.45k
            ColumnWithTypeAndName from_nested_column {from_col_array->get_data_ptr(),
76
1.45k
                                                      from_nested_type, ""};
77
78
            /// convert nested column
79
1.45k
            ColumnNumbers new_arguments {block.columns()};
80
1.45k
            block.insert(from_nested_column);
81
82
1.45k
            uint32_t nested_result = block.columns();
83
1.45k
            block.insert({to_nested_type, ""});
84
1.45k
            RETURN_IF_ERROR(nested_function(context, block, new_arguments, nested_result,
85
1.45k
                                            from_col_array->get_data_ptr()->size(), null_map));
86
1.45k
            auto nested_result_column = block.get_by_position(nested_result).column;
87
88
            /// set converted nested column to result
89
1.45k
            block.get_by_position(result).column =
90
1.45k
                    ColumnArray::create(nested_result_column, from_col_array->get_offsets_ptr());
91
1.45k
        } else {
92
0
            return Status::RuntimeError("Illegal column {} for function CAST AS Array",
93
0
                                        from_column->get_name());
94
0
        }
95
1.45k
        return Status::OK();
96
1.45k
    };
97
1.45k
}
98
} // namespace doris::CastWrapper