| 80 | } |
| 81 | |
| 82 | NamesAndTypes UnionNode::computeProjectionColumns() const |
| 83 | { |
| 84 | if (recursive_cte_table) |
| 85 | return recursive_cte_table->columns; |
| 86 | |
| 87 | std::vector<NamesAndTypes> projections; |
| 88 | |
| 89 | NamesAndTypes query_node_projection; |
| 90 | |
| 91 | const auto & query_nodes = getQueries().getNodes(); |
| 92 | projections.reserve(query_nodes.size()); |
| 93 | |
| 94 | for (const auto & query_node : query_nodes) |
| 95 | { |
| 96 | if (auto * query_node_typed = query_node->as<QueryNode>()) |
| 97 | query_node_projection = query_node_typed->getProjectionColumns(); |
| 98 | else if (auto * union_node_typed = query_node->as<UnionNode>()) |
| 99 | query_node_projection = union_node_typed->computeProjectionColumns(); |
| 100 | |
| 101 | projections.push_back(query_node_projection); |
| 102 | |
| 103 | if (query_node_projection.size() != projections.front().size()) |
| 104 | throw Exception(ErrorCodes::TYPE_MISMATCH, "UNION different number of columns in queries"); |
| 105 | } |
| 106 | |
| 107 | NamesAndTypes result_columns; |
| 108 | |
| 109 | size_t projections_size = projections.size(); |
| 110 | DataTypes projection_column_types; |
| 111 | projection_column_types.resize(projections_size); |
| 112 | |
| 113 | size_t columns_size = query_node_projection.size(); |
| 114 | for (size_t column_index = 0; column_index < columns_size; ++column_index) |
| 115 | { |
| 116 | for (size_t projection_index = 0; projection_index < projections_size; ++projection_index) |
| 117 | projection_column_types[projection_index] = projections[projection_index][column_index].type; |
| 118 | |
| 119 | auto result_type = getContext()->getSettingsRef()[Setting::use_variant_as_common_type] |
| 120 | ? getLeastSupertypeOrVariant(projection_column_types) |
| 121 | : getLeastSupertype(projection_column_types); |
| 122 | result_columns.emplace_back(projections.front()[column_index].name, std::move(result_type)); |
| 123 | } |
| 124 | |
| 125 | return result_columns; |
| 126 | } |
| 127 | |
| 128 | void UnionNode::removeUnusedProjectionColumns(const std::unordered_set<size_t> & used_projection_columns_indexes) |
| 129 | { |
no test coverage detected