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 | |