be/src/exprs/function/array/function_array_element.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 | | // This file is copied from |
18 | | // https://github.com/ClickHouse/ClickHouse/blob/master/src/Functions/array/arrayElement.cpp |
19 | | // and modified by Doris |
20 | | |
21 | | #pragma once |
22 | | |
23 | | #include <glog/logging.h> |
24 | | #include <string.h> |
25 | | |
26 | | #include <algorithm> |
27 | | #include <boost/iterator/iterator_facade.hpp> |
28 | | #include <memory> |
29 | | #include <ostream> |
30 | | #include <string> |
31 | | #include <utility> |
32 | | |
33 | | #include "common/status.h" |
34 | | #include "core/assert_cast.h" |
35 | | #include "core/block/block.h" |
36 | | #include "core/block/column_numbers.h" |
37 | | #include "core/block/column_with_type_and_name.h" |
38 | | #include "core/block/columns_with_type_and_name.h" |
39 | | #include "core/call_on_type_index.h" |
40 | | #include "core/column/column.h" |
41 | | #include "core/column/column_array.h" |
42 | | #include "core/column/column_decimal.h" |
43 | | #include "core/column/column_map.h" |
44 | | #include "core/column/column_nullable.h" |
45 | | #include "core/column/column_string.h" |
46 | | #include "core/column/column_struct.h" |
47 | | #include "core/column/column_vector.h" |
48 | | #include "core/data_type/data_type.h" |
49 | | #include "core/data_type/data_type_array.h" |
50 | | #include "core/data_type/data_type_map.h" |
51 | | #include "core/data_type/data_type_nullable.h" |
52 | | #include "core/data_type/data_type_number.h" |
53 | | #include "core/data_type/primitive_type.h" |
54 | | #include "core/types.h" |
55 | | #include "exprs/function/function.h" |
56 | | #include "exprs/function/function_helpers.h" |
57 | | |
58 | | namespace doris { |
59 | | class FunctionContext; |
60 | | } // namespace doris |
61 | | |
62 | | namespace doris { |
63 | | #include "common/compile_check_begin.h" |
64 | | |
65 | | class FunctionArrayElement : public IFunction { |
66 | | public: |
67 | | /// The count of items in the map may exceed 128(Int8). |
68 | | using MapIndiceDataType = DataTypeInt16; |
69 | | |
70 | | static constexpr auto name = "element_at"; |
71 | 8 | static FunctionPtr create() { return std::make_shared<FunctionArrayElement>(); } |
72 | | |
73 | | /// Get function name. |
74 | 1 | String get_name() const override { return name; } |
75 | | |
76 | 7 | bool is_variadic() const override { return false; } |
77 | | |
78 | 12 | bool use_default_implementation_for_nulls() const override { return false; } |
79 | | |
80 | 6 | size_t get_number_of_arguments() const override { return 2; } |
81 | | |
82 | 6 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
83 | 6 | DataTypePtr arg_0 = remove_nullable(arguments[0]); |
84 | 6 | DCHECK(arg_0->get_primitive_type() == TYPE_ARRAY || arg_0->get_primitive_type() == TYPE_MAP) |
85 | 0 | << "first argument for function: " << name |
86 | 0 | << " should be DataTypeArray or DataTypeMap, but it is " << arg_0->get_name(); |
87 | 6 | if (arg_0->get_primitive_type() == TYPE_ARRAY) { |
88 | 6 | DCHECK(is_int_or_bool(arguments[1]->get_primitive_type())) |
89 | 0 | << "second argument for function: " << name |
90 | 0 | << " should be Integer for array element"; |
91 | 6 | return make_nullable( |
92 | 6 | check_and_get_data_type<DataTypeArray>(arg_0.get())->get_nested_type()); |
93 | 6 | } else if (arg_0->get_primitive_type() == TYPE_MAP) { |
94 | 0 | return make_nullable( |
95 | 0 | check_and_get_data_type<DataTypeMap>(arg_0.get())->get_value_type()); |
96 | 0 | } else { |
97 | 0 | throw doris::Exception( |
98 | 0 | ErrorCode::INVALID_ARGUMENT, |
99 | 0 | fmt::format("element_at only support array and map so far, but got {}", |
100 | 0 | arg_0->get_name())); |
101 | 0 | } |
102 | 6 | } |
103 | | |
104 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
105 | 6 | uint32_t result, size_t input_rows_count) const override { |
106 | 6 | auto dst_null_column = ColumnUInt8::create(input_rows_count, 0); |
107 | 6 | UInt8* dst_null_map = dst_null_column->get_data().data(); |
108 | 6 | const UInt8* src_null_map = nullptr; |
109 | 6 | ColumnsWithTypeAndName args; |
110 | 6 | block.replace_by_position( |
111 | 6 | arguments[0], |
112 | 6 | block.get_by_position(arguments[0]).column->convert_to_full_column_if_const()); |
113 | 6 | auto col_left = block.get_by_position(arguments[0]); |
114 | 6 | if (col_left.column->is_nullable()) { |
115 | 6 | auto null_col = check_and_get_column<ColumnNullable>(*col_left.column); |
116 | 6 | src_null_map = null_col->get_null_map_column().get_data().data(); |
117 | 6 | args = {{null_col->get_nested_column_ptr(), remove_nullable(col_left.type), |
118 | 6 | col_left.name}, |
119 | 6 | block.get_by_position(arguments[1])}; |
120 | 6 | } else { |
121 | 0 | args = {col_left, block.get_by_position(arguments[1])}; |
122 | 0 | } |
123 | 6 | ColumnPtr res_column = nullptr; |
124 | 6 | if (is_column<ColumnMap>(args[0].column.get()) || |
125 | 6 | check_column_const<ColumnMap>(args[0].column.get())) { |
126 | 0 | res_column = _execute_map(args, input_rows_count, src_null_map, dst_null_map); |
127 | 6 | } else { |
128 | 6 | res_column = _execute_nullable(args, input_rows_count, src_null_map, dst_null_map); |
129 | 6 | } |
130 | 6 | if (!res_column) { |
131 | 0 | return Status::RuntimeError("unsupported types for function {}({}, {})", get_name(), |
132 | 0 | block.get_by_position(arguments[0]).type->get_name(), |
133 | 0 | block.get_by_position(arguments[1]).type->get_name()); |
134 | 0 | } |
135 | 6 | block.replace_by_position(result, |
136 | 6 | ColumnNullable::create(res_column, std::move(dst_null_column))); |
137 | 6 | return Status::OK(); |
138 | 6 | } |
139 | | |
140 | | private: |
141 | | //=========================== map element===========================// |
142 | | ColumnPtr _get_mapped_idx(const ColumnArray& column, |
143 | 0 | const ColumnWithTypeAndName& argument) const { |
144 | 0 | auto right_column = make_nullable(argument.column->convert_to_full_column_if_const()); |
145 | 0 | const ColumnArray::Offsets64& offsets = column.get_offsets(); |
146 | 0 | ColumnPtr nested_ptr = make_nullable(column.get_data_ptr()); |
147 | 0 | size_t rows = offsets.size(); |
148 | | // prepare return data |
149 | 0 | auto matched_indices = ColumnVector<MapIndiceDataType::PType>::create(); |
150 | 0 | matched_indices->reserve(rows); |
151 | |
|
152 | 0 | for (size_t i = 0; i < rows; i++) { |
153 | 0 | bool matched = false; |
154 | 0 | size_t begin = offsets[i - 1]; |
155 | 0 | size_t end = offsets[i]; |
156 | 0 | for (size_t j = begin; j < end; j++) { |
157 | 0 | if (nested_ptr->compare_at(j, i, *right_column, -1) == 0) { |
158 | 0 | matched_indices->insert_value( |
159 | 0 | cast_set<MapIndiceDataType::FieldType, size_t, false>(j - begin + 1)); |
160 | 0 | matched = true; |
161 | 0 | break; |
162 | 0 | } |
163 | 0 | } |
164 | |
|
165 | 0 | if (!matched) { |
166 | 0 | matched_indices->insert_value(cast_set<MapIndiceDataType::FieldType, size_t, false>( |
167 | 0 | end - begin + 1)); // make indices for null |
168 | 0 | } |
169 | 0 | } |
170 | |
|
171 | 0 | return matched_indices; |
172 | 0 | } |
173 | | |
174 | | template <typename ColumnType> |
175 | | ColumnPtr _execute_number(const ColumnArray::Offsets64& offsets, const IColumn& nested_column, |
176 | | const UInt8* arr_null_map, const IColumn& indices, |
177 | 5 | const UInt8* nested_null_map, UInt8* dst_null_map) const { |
178 | 5 | const auto& nested_data = reinterpret_cast<const ColumnType&>(nested_column).get_data(); |
179 | | |
180 | 5 | auto dst_column = nested_column.clone_empty(); |
181 | 5 | auto& dst_data = reinterpret_cast<ColumnType&>(*dst_column).get_data(); |
182 | 5 | dst_data.resize(offsets.size()); |
183 | | |
184 | | // process |
185 | 50 | for (size_t row = 0; row < offsets.size(); ++row) { |
186 | 45 | size_t off = offsets[row - 1]; |
187 | 45 | size_t len = offsets[row] - off; |
188 | 45 | auto index = indices.get_int(row); |
189 | | // array is nullable |
190 | 45 | bool null_flag = bool(arr_null_map && arr_null_map[row]); |
191 | | // calc index in nested column |
192 | 45 | if (!null_flag && index > 0 && index <= len) { |
193 | 5 | index += off - 1; |
194 | 40 | } else if (!null_flag && index < 0 && -index <= len) { |
195 | 10 | index += off + len; |
196 | 30 | } else { |
197 | 30 | null_flag = true; |
198 | 30 | } |
199 | | // nested column nullable check |
200 | 45 | if (!null_flag && nested_null_map && nested_null_map[index]) { |
201 | 0 | null_flag = true; |
202 | 0 | } |
203 | | // actual data copy |
204 | 45 | if (null_flag) { |
205 | 30 | dst_null_map[row] = true; |
206 | 30 | dst_data[row] = typename ColumnType::value_type(); |
207 | 30 | } else { |
208 | 15 | DCHECK(index >= 0 && index < nested_data.size()); |
209 | 15 | dst_null_map[row] = false; |
210 | 15 | dst_data[row] = nested_data[index]; |
211 | 15 | } |
212 | 45 | } |
213 | 5 | return dst_column; |
214 | 5 | } Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE2EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE3EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Line | Count | Source | 177 | 1 | const UInt8* nested_null_map, UInt8* dst_null_map) const { | 178 | 1 | const auto& nested_data = reinterpret_cast<const ColumnType&>(nested_column).get_data(); | 179 | | | 180 | 1 | auto dst_column = nested_column.clone_empty(); | 181 | 1 | auto& dst_data = reinterpret_cast<ColumnType&>(*dst_column).get_data(); | 182 | 1 | dst_data.resize(offsets.size()); | 183 | | | 184 | | // process | 185 | 10 | for (size_t row = 0; row < offsets.size(); ++row) { | 186 | 9 | size_t off = offsets[row - 1]; | 187 | 9 | size_t len = offsets[row] - off; | 188 | 9 | auto index = indices.get_int(row); | 189 | | // array is nullable | 190 | 9 | bool null_flag = bool(arr_null_map && arr_null_map[row]); | 191 | | // calc index in nested column | 192 | 9 | if (!null_flag && index > 0 && index <= len) { | 193 | 1 | index += off - 1; | 194 | 8 | } else if (!null_flag && index < 0 && -index <= len) { | 195 | 2 | index += off + len; | 196 | 6 | } else { | 197 | 6 | null_flag = true; | 198 | 6 | } | 199 | | // nested column nullable check | 200 | 9 | if (!null_flag && nested_null_map && nested_null_map[index]) { | 201 | 0 | null_flag = true; | 202 | 0 | } | 203 | | // actual data copy | 204 | 9 | if (null_flag) { | 205 | 6 | dst_null_map[row] = true; | 206 | 6 | dst_data[row] = typename ColumnType::value_type(); | 207 | 6 | } else { | 208 | | DCHECK(index >= 0 && index < nested_data.size()); | 209 | 3 | dst_null_map[row] = false; | 210 | 3 | dst_data[row] = nested_data[index]; | 211 | 3 | } | 212 | 9 | } | 213 | 1 | return dst_column; | 214 | 1 | } |
Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE4EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE5EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Line | Count | Source | 177 | 1 | const UInt8* nested_null_map, UInt8* dst_null_map) const { | 178 | 1 | const auto& nested_data = reinterpret_cast<const ColumnType&>(nested_column).get_data(); | 179 | | | 180 | 1 | auto dst_column = nested_column.clone_empty(); | 181 | 1 | auto& dst_data = reinterpret_cast<ColumnType&>(*dst_column).get_data(); | 182 | 1 | dst_data.resize(offsets.size()); | 183 | | | 184 | | // process | 185 | 10 | for (size_t row = 0; row < offsets.size(); ++row) { | 186 | 9 | size_t off = offsets[row - 1]; | 187 | 9 | size_t len = offsets[row] - off; | 188 | 9 | auto index = indices.get_int(row); | 189 | | // array is nullable | 190 | 9 | bool null_flag = bool(arr_null_map && arr_null_map[row]); | 191 | | // calc index in nested column | 192 | 9 | if (!null_flag && index > 0 && index <= len) { | 193 | 1 | index += off - 1; | 194 | 8 | } else if (!null_flag && index < 0 && -index <= len) { | 195 | 2 | index += off + len; | 196 | 6 | } else { | 197 | 6 | null_flag = true; | 198 | 6 | } | 199 | | // nested column nullable check | 200 | 9 | if (!null_flag && nested_null_map && nested_null_map[index]) { | 201 | 0 | null_flag = true; | 202 | 0 | } | 203 | | // actual data copy | 204 | 9 | if (null_flag) { | 205 | 6 | dst_null_map[row] = true; | 206 | 6 | dst_data[row] = typename ColumnType::value_type(); | 207 | 6 | } else { | 208 | | DCHECK(index >= 0 && index < nested_data.size()); | 209 | 3 | dst_null_map[row] = false; | 210 | 3 | dst_data[row] = nested_data[index]; | 211 | 3 | } | 212 | 9 | } | 213 | 1 | return dst_column; | 214 | 1 | } |
Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE7EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Line | Count | Source | 177 | 1 | const UInt8* nested_null_map, UInt8* dst_null_map) const { | 178 | 1 | const auto& nested_data = reinterpret_cast<const ColumnType&>(nested_column).get_data(); | 179 | | | 180 | 1 | auto dst_column = nested_column.clone_empty(); | 181 | 1 | auto& dst_data = reinterpret_cast<ColumnType&>(*dst_column).get_data(); | 182 | 1 | dst_data.resize(offsets.size()); | 183 | | | 184 | | // process | 185 | 10 | for (size_t row = 0; row < offsets.size(); ++row) { | 186 | 9 | size_t off = offsets[row - 1]; | 187 | 9 | size_t len = offsets[row] - off; | 188 | 9 | auto index = indices.get_int(row); | 189 | | // array is nullable | 190 | 9 | bool null_flag = bool(arr_null_map && arr_null_map[row]); | 191 | | // calc index in nested column | 192 | 9 | if (!null_flag && index > 0 && index <= len) { | 193 | 1 | index += off - 1; | 194 | 8 | } else if (!null_flag && index < 0 && -index <= len) { | 195 | 2 | index += off + len; | 196 | 6 | } else { | 197 | 6 | null_flag = true; | 198 | 6 | } | 199 | | // nested column nullable check | 200 | 9 | if (!null_flag && nested_null_map && nested_null_map[index]) { | 201 | 0 | null_flag = true; | 202 | 0 | } | 203 | | // actual data copy | 204 | 9 | if (null_flag) { | 205 | 6 | dst_null_map[row] = true; | 206 | 6 | dst_data[row] = typename ColumnType::value_type(); | 207 | 6 | } else { | 208 | | DCHECK(index >= 0 && index < nested_data.size()); | 209 | 3 | dst_null_map[row] = false; | 210 | 3 | dst_data[row] = nested_data[index]; | 211 | 3 | } | 212 | 9 | } | 213 | 1 | return dst_column; | 214 | 1 | } |
Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE8EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE9EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Line | Count | Source | 177 | 1 | const UInt8* nested_null_map, UInt8* dst_null_map) const { | 178 | 1 | const auto& nested_data = reinterpret_cast<const ColumnType&>(nested_column).get_data(); | 179 | | | 180 | 1 | auto dst_column = nested_column.clone_empty(); | 181 | 1 | auto& dst_data = reinterpret_cast<ColumnType&>(*dst_column).get_data(); | 182 | 1 | dst_data.resize(offsets.size()); | 183 | | | 184 | | // process | 185 | 10 | for (size_t row = 0; row < offsets.size(); ++row) { | 186 | 9 | size_t off = offsets[row - 1]; | 187 | 9 | size_t len = offsets[row] - off; | 188 | 9 | auto index = indices.get_int(row); | 189 | | // array is nullable | 190 | 9 | bool null_flag = bool(arr_null_map && arr_null_map[row]); | 191 | | // calc index in nested column | 192 | 9 | if (!null_flag && index > 0 && index <= len) { | 193 | 1 | index += off - 1; | 194 | 8 | } else if (!null_flag && index < 0 && -index <= len) { | 195 | 2 | index += off + len; | 196 | 6 | } else { | 197 | 6 | null_flag = true; | 198 | 6 | } | 199 | | // nested column nullable check | 200 | 9 | if (!null_flag && nested_null_map && nested_null_map[index]) { | 201 | 0 | null_flag = true; | 202 | 0 | } | 203 | | // actual data copy | 204 | 9 | if (null_flag) { | 205 | 6 | dst_null_map[row] = true; | 206 | 6 | dst_data[row] = typename ColumnType::value_type(); | 207 | 6 | } else { | 208 | | DCHECK(index >= 0 && index < nested_data.size()); | 209 | 3 | dst_null_map[row] = false; | 210 | 3 | dst_data[row] = nested_data[index]; | 211 | 3 | } | 212 | 9 | } | 213 | 1 | return dst_column; | 214 | 1 | } |
Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_13ColumnDecimalILNS_13PrimitiveTypeE28EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_13ColumnDecimalILNS_13PrimitiveTypeE29EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph _ZNK5doris20FunctionArrayElement15_execute_numberINS_13ColumnDecimalILNS_13PrimitiveTypeE20EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Line | Count | Source | 177 | 1 | const UInt8* nested_null_map, UInt8* dst_null_map) const { | 178 | 1 | const auto& nested_data = reinterpret_cast<const ColumnType&>(nested_column).get_data(); | 179 | | | 180 | 1 | auto dst_column = nested_column.clone_empty(); | 181 | 1 | auto& dst_data = reinterpret_cast<ColumnType&>(*dst_column).get_data(); | 182 | 1 | dst_data.resize(offsets.size()); | 183 | | | 184 | | // process | 185 | 10 | for (size_t row = 0; row < offsets.size(); ++row) { | 186 | 9 | size_t off = offsets[row - 1]; | 187 | 9 | size_t len = offsets[row] - off; | 188 | 9 | auto index = indices.get_int(row); | 189 | | // array is nullable | 190 | 9 | bool null_flag = bool(arr_null_map && arr_null_map[row]); | 191 | | // calc index in nested column | 192 | 9 | if (!null_flag && index > 0 && index <= len) { | 193 | 1 | index += off - 1; | 194 | 8 | } else if (!null_flag && index < 0 && -index <= len) { | 195 | 2 | index += off + len; | 196 | 6 | } else { | 197 | 6 | null_flag = true; | 198 | 6 | } | 199 | | // nested column nullable check | 200 | 9 | if (!null_flag && nested_null_map && nested_null_map[index]) { | 201 | 0 | null_flag = true; | 202 | 0 | } | 203 | | // actual data copy | 204 | 9 | if (null_flag) { | 205 | 6 | dst_null_map[row] = true; | 206 | 6 | dst_data[row] = typename ColumnType::value_type(); | 207 | 6 | } else { | 208 | | DCHECK(index >= 0 && index < nested_data.size()); | 209 | 3 | dst_null_map[row] = false; | 210 | 3 | dst_data[row] = nested_data[index]; | 211 | 3 | } | 212 | 9 | } | 213 | 1 | return dst_column; | 214 | 1 | } |
Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_13ColumnDecimalILNS_13PrimitiveTypeE30EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_13ColumnDecimalILNS_13PrimitiveTypeE35EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE11EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE25EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE26EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE12EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE27EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE42EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE36EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph Unexecuted instantiation: _ZNK5doris20FunctionArrayElement15_execute_numberINS_12ColumnVectorILNS_13PrimitiveTypeE37EEEEENS_3COWINS_7IColumnEE13immutable_ptrIS6_EERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKS6_PKhSI_SK_Ph |
215 | | |
216 | | ColumnPtr _execute_string(const ColumnArray::Offsets64& offsets, const IColumn& nested_column, |
217 | | const UInt8* arr_null_map, const IColumn& indices, |
218 | 1 | const UInt8* nested_null_map, UInt8* dst_null_map) const { |
219 | 1 | const auto& src_str_offs = |
220 | 1 | reinterpret_cast<const ColumnString&>(nested_column).get_offsets(); |
221 | 1 | const auto& src_str_chars = |
222 | 1 | reinterpret_cast<const ColumnString&>(nested_column).get_chars(); |
223 | | |
224 | | // prepare return data |
225 | 1 | auto dst_column = ColumnString::create(); |
226 | 1 | auto& dst_str_offs = dst_column->get_offsets(); |
227 | 1 | dst_str_offs.resize(offsets.size()); |
228 | 1 | auto& dst_str_chars = dst_column->get_chars(); |
229 | 1 | dst_str_chars.reserve(src_str_chars.size()); |
230 | | |
231 | | // process |
232 | 10 | for (size_t row = 0; row < offsets.size(); ++row) { |
233 | 9 | size_t off = offsets[row - 1]; |
234 | 9 | size_t len = offsets[row] - off; |
235 | 9 | auto index = indices.get_int(row); |
236 | | // array is nullable |
237 | 9 | bool null_flag = bool(arr_null_map && arr_null_map[row]); |
238 | | // calc index in nested column |
239 | 9 | if (!null_flag && index > 0 && index <= len) { |
240 | 2 | index += off - 1; |
241 | 7 | } else if (!null_flag && index < 0 && -index <= len) { |
242 | 1 | index += off + len; |
243 | 6 | } else { |
244 | 6 | null_flag = true; |
245 | 6 | } |
246 | | // nested column nullable check |
247 | 9 | if (!null_flag && nested_null_map && nested_null_map[index]) { |
248 | 0 | null_flag = true; |
249 | 0 | } |
250 | | // actual string copy |
251 | 9 | if (!null_flag) { |
252 | 3 | DCHECK(index >= 0 && index < src_str_offs.size()); |
253 | 3 | dst_null_map[row] = false; |
254 | 3 | auto element_size = src_str_offs[index] - src_str_offs[index - 1]; |
255 | 3 | dst_str_offs[row] = dst_str_offs[row - 1] + element_size; |
256 | 3 | auto src_string_pos = src_str_offs[index - 1]; |
257 | 3 | auto dst_string_pos = dst_str_offs[row - 1]; |
258 | 3 | dst_str_chars.resize(dst_string_pos + element_size); |
259 | 3 | memcpy(&dst_str_chars[dst_string_pos], &src_str_chars[src_string_pos], |
260 | 3 | element_size); |
261 | 6 | } else { |
262 | 6 | dst_null_map[row] = true; |
263 | 6 | dst_str_offs[row] = dst_str_offs[row - 1]; |
264 | 6 | } |
265 | 9 | } |
266 | 1 | return dst_column; |
267 | 1 | } |
268 | | |
269 | | ColumnPtr _execute_map(const ColumnsWithTypeAndName& arguments, size_t input_rows_count, |
270 | 0 | const UInt8* src_null_map, UInt8* dst_null_map) const { |
271 | 0 | auto left_column = arguments[0].column->convert_to_full_column_if_const(); |
272 | 0 | DataTypePtr val_type = |
273 | 0 | reinterpret_cast<const DataTypeMap&>(*arguments[0].type).get_value_type(); |
274 | 0 | const auto& map_column = reinterpret_cast<const ColumnMap&>(*left_column); |
275 | | |
276 | | // create column array to find keys |
277 | 0 | auto key_arr = ColumnArray::create(map_column.get_keys_ptr(), map_column.get_offsets_ptr()); |
278 | 0 | auto val_arr = |
279 | 0 | ColumnArray::create(map_column.get_values_ptr(), map_column.get_offsets_ptr()); |
280 | |
|
281 | 0 | ColumnPtr matched_indices = _get_mapped_idx(*key_arr, arguments[1]); |
282 | 0 | if (!matched_indices) { |
283 | 0 | return nullptr; |
284 | 0 | } |
285 | 0 | DataTypePtr indices_type(std::make_shared<MapIndiceDataType>()); |
286 | 0 | ColumnWithTypeAndName indices(matched_indices, indices_type, "indices"); |
287 | 0 | ColumnWithTypeAndName data(std::move(val_arr), std::make_shared<DataTypeArray>(val_type), |
288 | 0 | "value"); |
289 | 0 | ColumnsWithTypeAndName args = {data, indices}; |
290 | 0 | return _execute_nullable(args, input_rows_count, src_null_map, dst_null_map); |
291 | 0 | } |
292 | | |
293 | | ColumnPtr _execute_common(const ColumnArray::Offsets64& offsets, const IColumn& nested_column, |
294 | | const UInt8* arr_null_map, const IColumn& indices, |
295 | 0 | const UInt8* nested_null_map, UInt8* dst_null_map) const { |
296 | | // prepare return data |
297 | 0 | auto dst_column = nested_column.clone_empty(); |
298 | 0 | dst_column->reserve(offsets.size()); |
299 | | |
300 | | // process |
301 | 0 | for (size_t row = 0; row < offsets.size(); ++row) { |
302 | 0 | size_t off = offsets[row - 1]; |
303 | 0 | size_t len = offsets[row] - off; |
304 | 0 | auto index = indices.get_int(row); |
305 | | // array is nullable |
306 | 0 | bool null_flag = bool(arr_null_map && arr_null_map[row]); |
307 | | // calc index in nested column |
308 | 0 | if (!null_flag && index > 0 && index <= len) { |
309 | 0 | index += off - 1; |
310 | 0 | } else if (!null_flag && index < 0 && -index <= len) { |
311 | 0 | index += off + len; |
312 | 0 | } else { |
313 | 0 | null_flag = true; |
314 | 0 | } |
315 | | // nested column nullable check |
316 | 0 | if (!null_flag && nested_null_map && nested_null_map[index]) { |
317 | 0 | null_flag = true; |
318 | 0 | } |
319 | | // actual data copy |
320 | 0 | if (!null_flag) { |
321 | 0 | dst_null_map[row] = false; |
322 | 0 | dst_column->insert_from(nested_column, index); |
323 | 0 | } else { |
324 | 0 | dst_null_map[row] = true; |
325 | 0 | dst_column->insert_default(); |
326 | 0 | } |
327 | 0 | } |
328 | 0 | return dst_column; |
329 | 0 | } |
330 | | |
331 | | ColumnPtr _execute_nullable(const ColumnsWithTypeAndName& arguments, size_t input_rows_count, |
332 | 6 | const UInt8* src_null_map, UInt8* dst_null_map) const { |
333 | | // check array nested column type and get data |
334 | 6 | auto left_column = arguments[0].column->convert_to_full_column_if_const(); |
335 | 6 | const auto& array_column = assert_cast<const ColumnArray&>(*left_column); |
336 | 6 | const auto& offsets = array_column.get_offsets(); |
337 | 6 | DCHECK(offsets.size() == input_rows_count); |
338 | 6 | const UInt8* nested_null_map = nullptr; |
339 | 6 | ColumnPtr nested_column = nullptr; |
340 | 6 | if (is_column_nullable(array_column.get_data())) { |
341 | 6 | const auto& nested_null_column = |
342 | 6 | reinterpret_cast<const ColumnNullable&>(array_column.get_data()); |
343 | 6 | nested_null_map = nested_null_column.get_null_map_column().get_data().data(); |
344 | 6 | nested_column = nested_null_column.get_nested_column_ptr(); |
345 | 6 | } else { |
346 | 0 | nested_column = array_column.get_data_ptr(); |
347 | 0 | } |
348 | | |
349 | 6 | ColumnPtr res = nullptr; |
350 | 6 | auto left_element_type = remove_nullable( |
351 | 6 | assert_cast<const DataTypeArray&>(*remove_nullable(arguments[0].type)) |
352 | 6 | .get_nested_type()); |
353 | | // because we impl use_default_implementation_for_nulls |
354 | | // we should handle array index column by-self, and array index should not be nullable. |
355 | 6 | auto idx_col = remove_nullable(arguments[1].column); |
356 | | // we should dispatch branch according to data type rather than column type |
357 | | |
358 | 6 | auto call = [&](const auto& type) -> bool { |
359 | 5 | using DispatchType = std::decay_t<decltype(type)>; |
360 | 5 | res = _execute_number<typename DispatchType::ColumnType>( |
361 | 5 | offsets, *nested_column, src_null_map, *idx_col, nested_null_map, dst_null_map); |
362 | 5 | return true; |
363 | 5 | }; Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE2EEEEEbSC_ _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE3EEEEEbSC_ Line | Count | Source | 358 | 1 | auto call = [&](const auto& type) -> bool { | 359 | 1 | using DispatchType = std::decay_t<decltype(type)>; | 360 | 1 | res = _execute_number<typename DispatchType::ColumnType>( | 361 | 1 | offsets, *nested_column, src_null_map, *idx_col, nested_null_map, dst_null_map); | 362 | 1 | return true; | 363 | 1 | }; |
Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE4EEEEEbSC_ _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE5EEEEEbSC_ Line | Count | Source | 358 | 1 | auto call = [&](const auto& type) -> bool { | 359 | 1 | using DispatchType = std::decay_t<decltype(type)>; | 360 | 1 | res = _execute_number<typename DispatchType::ColumnType>( | 361 | 1 | offsets, *nested_column, src_null_map, *idx_col, nested_null_map, dst_null_map); | 362 | 1 | return true; | 363 | 1 | }; |
Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE6EEEEEbSC_ _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE7EEEEEbSC_ Line | Count | Source | 358 | 1 | auto call = [&](const auto& type) -> bool { | 359 | 1 | using DispatchType = std::decay_t<decltype(type)>; | 360 | 1 | res = _execute_number<typename DispatchType::ColumnType>( | 361 | 1 | offsets, *nested_column, src_null_map, *idx_col, nested_null_map, dst_null_map); | 362 | 1 | return true; | 363 | 1 | }; |
Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE8EEEEEbSC_ _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE9EEEEEbSC_ Line | Count | Source | 358 | 1 | auto call = [&](const auto& type) -> bool { | 359 | 1 | using DispatchType = std::decay_t<decltype(type)>; | 360 | 1 | res = _execute_number<typename DispatchType::ColumnType>( | 361 | 1 | offsets, *nested_column, src_null_map, *idx_col, nested_null_map, dst_null_map); | 362 | 1 | return true; | 363 | 1 | }; |
Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE28EEEEEbSC_ Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE29EEEEEbSC_ _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE20EEEEEbSC_ Line | Count | Source | 358 | 1 | auto call = [&](const auto& type) -> bool { | 359 | 1 | using DispatchType = std::decay_t<decltype(type)>; | 360 | 1 | res = _execute_number<typename DispatchType::ColumnType>( | 361 | 1 | offsets, *nested_column, src_null_map, *idx_col, nested_null_map, dst_null_map); | 362 | 1 | return true; | 363 | 1 | }; |
Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE30EEEEEbSC_ Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE35EEEEEbSC_ Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE11EEEEEbSC_ Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE25EEEEEbSC_ Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE26EEEEEbSC_ Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE12EEEEEbSC_ Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE27EEEEEbSC_ Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE42EEEEEbSC_ Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE36EEEEEbSC_ Unexecuted instantiation: _ZZNK5doris20FunctionArrayElement17_execute_nullableERKSt6vectorINS_21ColumnWithTypeAndNameESaIS2_EEmPKhPhENKUlRKT_E_clINS_16DispatchDataTypeILNS_13PrimitiveTypeE37EEEEEbSC_ |
364 | | |
365 | 6 | if (is_string_type(left_element_type->get_primitive_type())) { |
366 | 1 | res = _execute_string(offsets, *nested_column, src_null_map, *idx_col, nested_null_map, |
367 | 1 | dst_null_map); |
368 | 5 | } else if (!dispatch_switch_scalar(left_element_type->get_primitive_type(), call)) { |
369 | 0 | res = _execute_common(offsets, *nested_column, src_null_map, *idx_col, nested_null_map, |
370 | 0 | dst_null_map); |
371 | 0 | } |
372 | 6 | return res; |
373 | 6 | } |
374 | | }; |
375 | | |
376 | | #include "common/compile_check_end.h" |
377 | | } // namespace doris |