| 1 | #pragma once |
| 2 | |
| 3 | #include "DatabaseAndTableWithAlias.h" |
| 4 | #include <Parsers/ASTSelectQuery.h> |
| 5 | #include <map> |
| 6 | |
| 7 | namespace DB |
| 8 | { |
| 9 | |
| 10 | class ASTIdentifier; |
| 11 | class ASTSubquery; |
| 12 | class Context; |
| 13 | |
| 14 | /** This class provides functions for Push-Down predicate expressions |
| 15 | * |
| 16 | * The Example: |
| 17 | * - Query before optimization : |
| 18 | * SELECT id_1, name_1 FROM (SELECT id_1, name_1 FROM table_a UNION ALL SELECT id_2, name_2 FROM table_b) |
| 19 | * WHERE id_1 = 1 |
| 20 | * - Query after optimization : |
| 21 | * SELECT id_1, name_1 FROM (SELECT id_1, name_1 FROM table_a WHERE id_1 = 1 UNION ALL SELECT id_2, name_2 FROM table_b WHERE id_2 = 1) |
| 22 | * WHERE id_1 = 1 |
| 23 | * For more details : https://github.com/ClickHouse/ClickHouse/pull/2015#issuecomment-374283452 |
| 24 | */ |
| 25 | class PredicateExpressionsOptimizer |
| 26 | { |
| 27 | using ProjectionWithAlias = std::pair<ASTPtr, String>; |
| 28 | using SubqueriesProjectionColumns = std::map<ASTSelectQuery *, std::vector<ProjectionWithAlias>>; |
| 29 | using IdentifierWithQualifier = std::pair<ASTIdentifier *, String>; |
| 30 | |
| 31 | /// Extracts settings, mostly to show which are used and which are not. |
| 32 | struct |
| 33 | { |
| 34 | /// QueryNormalizer settings |
| 35 | const UInt64 ; |
| 36 | const UInt64 max_expanded_ast_elements; |
| 37 | const String ; |
| 38 | |
| 39 | /// for PredicateExpressionsOptimizer |
| 40 | const bool ; |
| 41 | const bool ; |
| 42 | const bool ; |
| 43 | |
| 44 | template<typename T> |
| 45 | (const T & settings_) |
| 46 | : max_ast_depth(settings_.max_ast_depth), |
| 47 | max_expanded_ast_elements(settings_.max_expanded_ast_elements), |
| 48 | count_distinct_implementation(settings_.count_distinct_implementation), |
| 49 | enable_optimize_predicate_expression(settings_.enable_optimize_predicate_expression), |
| 50 | enable_optimize_predicate_expression_to_final_subquery(settings_.enable_optimize_predicate_expression_to_final_subquery), |
| 51 | join_use_nulls(settings_.join_use_nulls) |
| 52 | {} |
| 53 | }; |
| 54 | |
| 55 | public: |
| 56 | (ASTSelectQuery * ast_select_, ExtractedSettings && settings_, const Context & context_); |
| 57 | |
| 58 | bool optimize(); |
| 59 | |
| 60 | private: |
| 61 | ASTSelectQuery * ast_select; |
| 62 | const ExtractedSettings settings; |
| 63 | const Context & context; |
| 64 | |
| 65 | enum OptimizeKind |
| 66 | { |
| 67 | NONE, |
| 68 | PUSH_TO_PREWHERE, |
| 69 | PUSH_TO_WHERE, |
| 70 | PUSH_TO_HAVING, |
| 71 | }; |
| 72 | |
| 73 | bool isArrayJoinFunction(const ASTPtr & node); |
| 74 | |
| 75 | std::vector<ASTPtr> splitConjunctionPredicate(const ASTPtr & predicate_expression); |
| 76 | |
| 77 | std::vector<IdentifierWithQualifier> getDependenciesAndQualifiers(ASTPtr & expression, |
| 78 | std::vector<TableWithColumnNames> & tables_with_aliases); |
| 79 | |
| 80 | bool optimizeExpression(const ASTPtr & outer_expression, ASTSelectQuery * subquery, ASTSelectQuery::Expression expr); |
| 81 | |
| 82 | bool optimizeImpl(const ASTPtr & outer_expression, const SubqueriesProjectionColumns & subqueries_projection_columns, OptimizeKind optimize_kind); |
| 83 | |
| 84 | bool allowPushDown( |
| 85 | const ASTSelectQuery * subquery, |
| 86 | const ASTPtr & outer_predicate, |
| 87 | const std::vector<ProjectionWithAlias> & subquery_projection_columns, |
| 88 | const std::vector<IdentifierWithQualifier> & outer_predicate_dependencies, |
| 89 | OptimizeKind & optimize_kind); |
| 90 | |
| 91 | bool checkDependencies( |
| 92 | const std::vector<ProjectionWithAlias> & projection_columns, |
| 93 | const std::vector<IdentifierWithQualifier> & dependencies, |
| 94 | OptimizeKind & optimize_kind); |
| 95 | |
| 96 | void setNewAliasesForInnerPredicate(const std::vector<ProjectionWithAlias> & projection_columns, |
| 97 | const std::vector<IdentifierWithQualifier> & inner_predicate_dependencies); |
| 98 | |
| 99 | SubqueriesProjectionColumns getAllSubqueryProjectionColumns(); |
| 100 | |
| 101 | void getSubqueryProjectionColumns(const ASTPtr & subquery, SubqueriesProjectionColumns & all_subquery_projection_columns); |
| 102 | |
| 103 | ASTs getSelectQueryProjectionColumns(ASTPtr & ast); |
| 104 | |
| 105 | ASTs evaluateAsterisk(ASTSelectQuery * select_query, const ASTPtr & asterisk); |
| 106 | |
| 107 | void cleanExpressionAlias(ASTPtr & expression); |
| 108 | }; |
| 109 | |
| 110 | } |
| 111 | |