| 117 | } |
| 118 | |
| 119 | void ArrayJoinAction::execute(Block & block) |
| 120 | { |
| 121 | if (columns.empty()) |
| 122 | throw Exception("No arrays to join", ErrorCodes::LOGICAL_ERROR); |
| 123 | |
| 124 | ColumnPtr any_array_map_ptr = block.getByName(*columns.begin()).column->convertToFullColumnIfConst(); |
| 125 | const auto * any_array = getArrayJoinColumnRawPtr(any_array_map_ptr); |
| 126 | if (!any_array) |
| 127 | throw Exception("ARRAY JOIN of not array: " + *columns.begin(), ErrorCodes::TYPE_MISMATCH); |
| 128 | |
| 129 | /// If LEFT ARRAY JOIN, then we create columns in which empty arrays are replaced by arrays with one element - the default value. |
| 130 | std::map<String, ColumnPtr> non_empty_array_columns; |
| 131 | |
| 132 | if (is_unaligned) |
| 133 | { |
| 134 | /// Resize all array joined columns to the longest one, (at least 1 if LEFT ARRAY JOIN), padded with default values. |
| 135 | auto rows = block.rows(); |
| 136 | auto uint64 = std::make_shared<DataTypeUInt64>(); |
| 137 | ColumnWithTypeAndName column_of_max_length{{}, uint64, {}}; |
| 138 | if (is_left) |
| 139 | column_of_max_length = ColumnWithTypeAndName(uint64->createColumnConst(rows, 1u), uint64, {}); |
| 140 | else |
| 141 | column_of_max_length = ColumnWithTypeAndName(uint64->createColumnConst(rows, 0u), uint64, {}); |
| 142 | |
| 143 | for (const auto & name : columns) |
| 144 | { |
| 145 | auto & src_col = block.getByName(name); |
| 146 | |
| 147 | ColumnsWithTypeAndName tmp_block{convertArrayJoinColumn(src_col)}; |
| 148 | auto len_col = function_length->build(tmp_block)->execute(tmp_block, uint64, rows); |
| 149 | |
| 150 | ColumnsWithTypeAndName tmp_block2{column_of_max_length, {len_col, uint64, {}}}; |
| 151 | column_of_max_length.column = function_greatest->build(tmp_block2)->execute(tmp_block2, uint64, rows); |
| 152 | } |
| 153 | |
| 154 | for (const auto & name : columns) |
| 155 | { |
| 156 | auto & src_col = block.getByName(name); |
| 157 | |
| 158 | ColumnWithTypeAndName array_col = convertArrayJoinColumn(src_col); |
| 159 | ColumnsWithTypeAndName tmp_block{array_col, column_of_max_length}; |
| 160 | array_col.column = function_array_resize->build(tmp_block)->execute(tmp_block, array_col.type, rows); |
| 161 | |
| 162 | src_col = std::move(array_col); |
| 163 | any_array_map_ptr = src_col.column->convertToFullColumnIfConst(); |
| 164 | } |
| 165 | |
| 166 | any_array = getArrayJoinColumnRawPtr(any_array_map_ptr); |
| 167 | if (!any_array) |
| 168 | throw Exception(ErrorCodes::TYPE_MISMATCH, "ARRAY JOIN requires array or map argument"); |
| 169 | } |
| 170 | else if (is_left) |
| 171 | { |
| 172 | for (const auto & name : columns) |
| 173 | { |
| 174 | auto src_col = block.getByName(name); |
| 175 | ColumnWithTypeAndName array_col = convertArrayJoinColumn(src_col); |
| 176 | ColumnsWithTypeAndName tmp_block{array_col}; |
nothing calls this directly
no test coverage detected