From e53a50e01a455096547c1e8dd8defccf9b4a0086 Mon Sep 17 00:00:00 2001 From: chertus Date: Tue, 9 Apr 2019 19:49:52 +0300 Subject: [PATCH] fix pushdown & build --- .../PredicateExpressionsOptimizer.cpp | 36 +++++++++---------- .../PredicateExpressionsOptimizer.h | 8 ++--- .../tests/logical_expressions_optimizer.cpp | 6 ++-- dbms/src/Parsers/ASTSelectQuery.h | 16 ++++----- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp index 3bdd4ab84d3..8340312f89d 100644 --- a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp +++ b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp @@ -56,15 +56,15 @@ bool PredicateExpressionsOptimizer::optimize() bool is_rewrite_subqueries = false; if (!all_subquery_projection_columns.empty()) { - is_rewrite_subqueries |= optimizeImpl(ast_select->refWhere(), all_subquery_projection_columns, OptimizeKind::PUSH_TO_WHERE); - is_rewrite_subqueries |= optimizeImpl(ast_select->refPrewhere(), all_subquery_projection_columns, OptimizeKind::PUSH_TO_PREWHERE); + is_rewrite_subqueries |= optimizeImpl(ast_select->where(), all_subquery_projection_columns, OptimizeKind::PUSH_TO_WHERE); + is_rewrite_subqueries |= optimizeImpl(ast_select->prewhere(), all_subquery_projection_columns, OptimizeKind::PUSH_TO_PREWHERE); } return is_rewrite_subqueries; } bool PredicateExpressionsOptimizer::optimizeImpl( - ASTPtr & outer_expression, const SubqueriesProjectionColumns & subqueries_projection_columns, OptimizeKind expression_kind) + const ASTPtr & outer_expression, const SubqueriesProjectionColumns & subqueries_projection_columns, OptimizeKind expression_kind) { /// split predicate with `and` std::vector outer_predicate_expressions = splitConjunctionPredicate(outer_expression); @@ -99,9 +99,15 @@ bool PredicateExpressionsOptimizer::optimizeImpl( switch (optimize_kind) { case OptimizeKind::NONE: continue; - case OptimizeKind::PUSH_TO_WHERE: is_rewrite_subquery |= optimizeExpression(inner_predicate, subquery->refWhere(), subquery); continue; - case OptimizeKind::PUSH_TO_HAVING: is_rewrite_subquery |= optimizeExpression(inner_predicate, subquery->refHaving(), subquery); continue; - case OptimizeKind::PUSH_TO_PREWHERE: is_rewrite_subquery |= optimizeExpression(inner_predicate, subquery->refPrewhere(), subquery); continue; + case OptimizeKind::PUSH_TO_WHERE: + is_rewrite_subquery |= optimizeExpression(inner_predicate, subquery, ASTSelectQuery::Expression::WHERE); + continue; + case OptimizeKind::PUSH_TO_HAVING: + is_rewrite_subquery |= optimizeExpression(inner_predicate, subquery, ASTSelectQuery::Expression::HAVING); + continue; + case OptimizeKind::PUSH_TO_PREWHERE: + is_rewrite_subquery |= optimizeExpression(inner_predicate, subquery, ASTSelectQuery::Expression::PREWHERE); + continue; } } } @@ -132,7 +138,7 @@ bool PredicateExpressionsOptimizer::allowPushDown(const ASTSelectQuery * subquer return false; } -std::vector PredicateExpressionsOptimizer::splitConjunctionPredicate(ASTPtr & predicate_expression) +std::vector PredicateExpressionsOptimizer::splitConjunctionPredicate(const ASTPtr & predicate_expression) { std::vector predicate_expressions; @@ -273,19 +279,13 @@ bool PredicateExpressionsOptimizer::isArrayJoinFunction(const ASTPtr & node) return false; } -bool PredicateExpressionsOptimizer::optimizeExpression(const ASTPtr & outer_expression, ASTPtr & subquery_expression, ASTSelectQuery * subquery) +bool PredicateExpressionsOptimizer::optimizeExpression(const ASTPtr & outer_expression, ASTSelectQuery * subquery, + ASTSelectQuery::Expression expr) { - ASTPtr new_subquery_expression = subquery_expression; - new_subquery_expression = new_subquery_expression ? makeASTFunction(and_function_name, outer_expression, subquery_expression) : outer_expression; + ASTPtr subquery_expression = subquery->getExpression(expr, false); + subquery_expression = subquery_expression ? makeASTFunction(and_function_name, outer_expression, subquery_expression) : outer_expression; - if (!subquery_expression) - subquery->children.emplace_back(new_subquery_expression); - else - for (auto & child : subquery->children) - if (child == subquery_expression) - child = new_subquery_expression; - - subquery_expression = std::move(new_subquery_expression); + subquery->setExpression(expr, std::move(subquery_expression)); return true; } diff --git a/dbms/src/Interpreters/PredicateExpressionsOptimizer.h b/dbms/src/Interpreters/PredicateExpressionsOptimizer.h index 0492600ca85..d2d91af6ff8 100644 --- a/dbms/src/Interpreters/PredicateExpressionsOptimizer.h +++ b/dbms/src/Interpreters/PredicateExpressionsOptimizer.h @@ -2,13 +2,13 @@ #include "DatabaseAndTableWithAlias.h" #include "ExpressionAnalyzer.h" +#include #include namespace DB { class ASTIdentifier; -class ASTSelectQuery; class ASTSubquery; class Context; @@ -69,14 +69,14 @@ private: bool isArrayJoinFunction(const ASTPtr & node); - std::vector splitConjunctionPredicate(ASTPtr & predicate_expression); + std::vector splitConjunctionPredicate(const ASTPtr & predicate_expression); std::vector getDependenciesAndQualifiers(ASTPtr & expression, std::vector & tables_with_aliases); - bool optimizeExpression(const ASTPtr & outer_expression, ASTPtr & subquery_expression, ASTSelectQuery * subquery); + bool optimizeExpression(const ASTPtr & outer_expression, ASTSelectQuery * subquery, ASTSelectQuery::Expression expr); - bool optimizeImpl(ASTPtr & outer_expression, const SubqueriesProjectionColumns & subqueries_projection_columns, OptimizeKind optimize_kind); + bool optimizeImpl(const ASTPtr & outer_expression, const SubqueriesProjectionColumns & subqueries_projection_columns, OptimizeKind optimize_kind); bool allowPushDown(const ASTSelectQuery * subquery); diff --git a/dbms/src/Interpreters/tests/logical_expressions_optimizer.cpp b/dbms/src/Interpreters/tests/logical_expressions_optimizer.cpp index aa033d33e55..c21c4dda299 100644 --- a/dbms/src/Interpreters/tests/logical_expressions_optimizer.cpp +++ b/dbms/src/Interpreters/tests/logical_expressions_optimizer.cpp @@ -281,9 +281,9 @@ void reorder(DB::IAST * ast) if (select_query == nullptr) return; - reorderImpl(select_query->where_expression.get()); - reorderImpl(select_query->prewhere_expression.get()); - reorderImpl(select_query->having_expression.get()); + reorderImpl(select_query->where().get()); + reorderImpl(select_query->prewhere().get()); + reorderImpl(select_query->having().get()); } } diff --git a/dbms/src/Parsers/ASTSelectQuery.h b/dbms/src/Parsers/ASTSelectQuery.h index b8c08752fd9..374933a1d57 100644 --- a/dbms/src/Parsers/ASTSelectQuery.h +++ b/dbms/src/Parsers/ASTSelectQuery.h @@ -65,6 +65,14 @@ public: /// Set/Reset/Remove expression. void setExpression(Expression expr, ASTPtr && ast); + ASTPtr getExpression(Expression expr, bool clone = false) const + { + auto it = positions.find(expr); + if (it != positions.end()) + return clone ? children[it->second]->clone() : children[it->second]; + return {}; + } + /// Compatibility with old parser of tables list. TODO remove ASTPtr sample_size() const; ASTPtr sample_offset() const; @@ -82,14 +90,6 @@ private: std::unordered_map positions; ASTPtr & getExpression(Expression expr); - - ASTPtr getExpression(Expression expr, bool clone = false) const - { - auto it = positions.find(expr); - if (it != positions.end()) - return clone ? children[it->second]->clone() : children[it->second]; - return {}; - } }; }