Rewrite original query removing joined tables from it
| 49 | |
| 50 | /// Rewrite original query removing joined tables from it |
| 51 | bool removeJoin(ASTSelectQuery & select, TreeRewriterResult & rewriter_result, ContextPtr context) |
| 52 | { |
| 53 | if (!hasJoin(select)) |
| 54 | return false; |
| 55 | |
| 56 | select.tables()->children.resize(1); |
| 57 | |
| 58 | /// Also remove GROUP BY cause ExpressionAnalyzer would check if it has all aggregate columns but joined columns would be missed. |
| 59 | select.setExpression(ASTSelectQuery::Expression::GROUP_BY, {}); |
| 60 | rewriter_result.aggregates.clear(); |
| 61 | |
| 62 | /// Replace select list to remove joined columns |
| 63 | auto select_list = make_intrusive<ASTExpressionList>(); |
| 64 | for (const auto & column : rewriter_result.required_source_columns) |
| 65 | select_list->children.emplace_back(make_intrusive<ASTIdentifier>(column.name)); |
| 66 | |
| 67 | select.setExpression(ASTSelectQuery::Expression::SELECT, select_list); |
| 68 | |
| 69 | const DB::IdentifierMembershipCollector membership_collector{select, context}; |
| 70 | |
| 71 | /// Remove unknown identifiers from where, leave only ones from left table |
| 72 | auto replace_where = [&membership_collector](ASTSelectQuery & query, ASTSelectQuery::Expression expr) |
| 73 | { |
| 74 | auto where = query.getExpression(expr, false); |
| 75 | if (!where) |
| 76 | return; |
| 77 | |
| 78 | const size_t left_table_pos = 0; |
| 79 | /// Test each argument of `and` function and select ones related to only left table |
| 80 | boost::intrusive_ptr<ASTFunction> new_conj = makeASTOperator("and"); |
| 81 | for (auto && node : splitConjunctionsAst(where)) |
| 82 | { |
| 83 | if (membership_collector.getIdentsMembership(node) == left_table_pos) |
| 84 | new_conj->arguments->children.push_back(std::move(node)); |
| 85 | } |
| 86 | |
| 87 | if (new_conj->arguments->children.empty()) |
| 88 | /// No identifiers from left table |
| 89 | query.setExpression(expr, {}); |
| 90 | else if (new_conj->arguments->children.size() == 1) |
| 91 | /// Only one expression, lift from `and` |
| 92 | query.setExpression(expr, std::move(new_conj->arguments->children[0])); |
| 93 | else |
| 94 | /// Set new expression |
| 95 | query.setExpression(expr, std::move(new_conj)); |
| 96 | }; |
| 97 | replace_where(select, ASTSelectQuery::Expression::WHERE); |
| 98 | replace_where(select, ASTSelectQuery::Expression::PREWHERE); |
| 99 | select.setExpression(ASTSelectQuery::Expression::HAVING, {}); |
| 100 | select.setExpression(ASTSelectQuery::Expression::ORDER_BY, {}); |
| 101 | |
| 102 | return true; |
| 103 | } |
| 104 | |
| 105 | SharedHeader getHeaderForProcessingStage( |
| 106 | const Names & column_names, |
no test coverage detected