| 1153 | } |
| 1154 | |
| 1155 | static std::unique_ptr<QueryPlan> buildJoinedPlan( |
| 1156 | ContextPtr context, |
| 1157 | PreparedSetsPtr prepared_sets, |
| 1158 | const ASTTablesInSelectQueryElement & join_element, |
| 1159 | TableJoin & analyzed_join, |
| 1160 | SelectQueryOptions query_options) |
| 1161 | { |
| 1162 | /// Actions which need to be calculated on joined block. |
| 1163 | auto joined_block_actions = analyzed_join.createJoinedBlockActions(context, std::move(prepared_sets)); |
| 1164 | NamesWithAliases required_columns_with_aliases = analyzed_join.getRequiredColumns( |
| 1165 | Block(joined_block_actions.getResultColumns()), joined_block_actions.getRequiredColumns().getNames()); |
| 1166 | |
| 1167 | Names original_right_column_names; |
| 1168 | for (auto & pr : required_columns_with_aliases) |
| 1169 | original_right_column_names.push_back(pr.first); |
| 1170 | |
| 1171 | /** For GLOBAL JOINs (in the case, for example, of the push method for executing GLOBAL subqueries), the following occurs |
| 1172 | * - in the addExternalStorage function, the JOIN (SELECT ...) subquery is replaced with JOIN _data1, |
| 1173 | * in the subquery_for_set object this subquery is exposed as source and the temporary table _data1 as the `table`. |
| 1174 | * - this function shows the expression JOIN _data1. |
| 1175 | * - JOIN tables will need aliases to correctly resolve USING clause. |
| 1176 | */ |
| 1177 | auto interpreter = interpretSubquery( |
| 1178 | join_element.table_expression, |
| 1179 | context, |
| 1180 | original_right_column_names, |
| 1181 | query_options.copy().setWithAllColumns().ignoreAlias(false)); |
| 1182 | auto joined_plan = std::make_unique<QueryPlan>(); |
| 1183 | interpreter->buildQueryPlan(*joined_plan); |
| 1184 | { |
| 1185 | auto original_right_columns = interpreter->getSampleBlock(); |
| 1186 | ActionsDAG rename_dag(original_right_columns->getColumnsWithTypeAndName()); |
| 1187 | for (const auto & name_with_alias : required_columns_with_aliases) |
| 1188 | { |
| 1189 | if (name_with_alias.first != name_with_alias.second && original_right_columns->has(name_with_alias.first)) |
| 1190 | { |
| 1191 | auto pos = original_right_columns->getPositionByName(name_with_alias.first); |
| 1192 | const auto & alias = rename_dag.addAlias(*rename_dag.getInputs()[pos], name_with_alias.second); |
| 1193 | rename_dag.getOutputs()[pos] = &alias; |
| 1194 | } |
| 1195 | } |
| 1196 | rename_dag.appendInputsForUnusedColumns(*joined_plan->getCurrentHeader()); |
| 1197 | auto rename_step = std::make_unique<ExpressionStep>(joined_plan->getCurrentHeader(), std::move(rename_dag)); |
| 1198 | rename_step->setStepDescription("Rename joined columns"); |
| 1199 | joined_plan->addStep(std::move(rename_step)); |
| 1200 | } |
| 1201 | |
| 1202 | auto joined_actions_step = std::make_unique<ExpressionStep>(joined_plan->getCurrentHeader(), std::move(joined_block_actions)); |
| 1203 | joined_actions_step->setStepDescription("Joined actions"); |
| 1204 | joined_plan->addStep(std::move(joined_actions_step)); |
| 1205 | |
| 1206 | return joined_plan; |
| 1207 | } |
| 1208 | |
| 1209 | std::shared_ptr<DirectKeyValueJoin> tryKeyValueJoin(std::shared_ptr<TableJoin> analyzed_join, const Block & right_sample_block) |
| 1210 | { |
no test coverage detected