From 7969288677c69a9271300dc107ebf8651e6bedb5 Mon Sep 17 00:00:00 2001 From: Vyacheslav Alipov Date: Fri, 26 Jul 2013 16:11:31 +0000 Subject: [PATCH] reorganized adding of MULTIPLE_ARRAY_JOIN action [#CONV-7967] --- .../DB/Interpreters/ExpressionAnalyzer.h | 4 +- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 53 ++++++++++++------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/dbms/include/DB/Interpreters/ExpressionAnalyzer.h b/dbms/include/DB/Interpreters/ExpressionAnalyzer.h index 93f3cae0e8f..71ace3471ee 100644 --- a/dbms/include/DB/Interpreters/ExpressionAnalyzer.h +++ b/dbms/include/DB/Interpreters/ExpressionAnalyzer.h @@ -233,7 +233,9 @@ private: /// Превратить перечисление значений или подзапрос в ASTSet. node - функция in или notIn. void makeSet(ASTFunction * node, const Block & sample_block); - void getActionsImpl(ASTPtr ast, bool no_subqueries, bool only_consts, ScopeStack & actions_stack, NameSet & array_joined_columns); + void getArrayJoinedColumnsImpl(ASTPtr ast, NameSet & array_joined_columns); + + void getActionsImpl(ASTPtr ast, bool no_subqueries, bool only_consts, ScopeStack & actions_stack); void getRootActionsImpl(ASTPtr ast, bool no_subqueries, bool only_consts, ExpressionActions & actions); diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index e95494390c3..a6dc062f128 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -521,16 +521,40 @@ static std::string getUniqueName(const Block & block, const std::string & prefix void ExpressionAnalyzer::getRootActionsImpl(ASTPtr ast, bool no_subqueries, bool only_consts, ExpressionActions & actions) { ScopeStack scopes(actions, settings); + NameSet array_joined_columns; - getActionsImpl(ast, no_subqueries, only_consts, scopes, array_joined_columns); + getArrayJoinedColumnsImpl(ast, array_joined_columns); if (!array_joined_columns.empty() && !only_consts) scopes.addAction(ExpressionActions::Action::multipleArrayJoin(array_joined_columns)); + + getActionsImpl(ast, no_subqueries, only_consts, scopes); + actions = *scopes.popLevel(); } -void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool only_consts, - ScopeStack & actions_stack, NameSet & array_joined_columns) +void ExpressionAnalyzer::getArrayJoinedColumnsImpl(ASTPtr ast, NameSet & array_joined_columns) +{ + if (ASTIdentifier * node = dynamic_cast(&*ast)) + { + if (select_query && + select_query->array_join_identifier && + node->kind == ASTIdentifier::Column && + (node->name == select_query->array_join_identifier->getColumnName() + || DataTypeNested::extractNestedTableName(node->name) == select_query->array_join_identifier->getColumnName())) + { + array_joined_columns.insert(node->name); + } + } + else + { + for (ASTs::iterator it = ast->children.begin(); it != ast->children.end(); ++it) + getArrayJoinedColumnsImpl(*it, array_joined_columns); + } +} + + +void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool only_consts, ScopeStack & actions_stack) { /// Если результат вычисления уже есть в блоке. if ((dynamic_cast(&*ast) || dynamic_cast(&*ast)) @@ -547,7 +571,7 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl if (node->arguments->children.size() != 1) throw Exception("arrayJoin requires exactly 1 argument", ErrorCodes::TYPE_MISMATCH); ASTPtr arg = node->arguments->children[0]; - getActionsImpl(arg, no_subqueries, only_consts, actions_stack, array_joined_columns); + getActionsImpl(arg, no_subqueries, only_consts, actions_stack); if (!only_consts) actions_stack.addAction(ExpressionActions::Action::arrayJoin(arg->getColumnName(), node->getColumnName())); @@ -561,7 +585,7 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl if (!no_subqueries) { /// Найдем тип первого аргумента (потом getActionsImpl вызовется для него снова и ни на что не повлияет). - getActionsImpl(node->arguments->children[0], no_subqueries, only_consts, actions_stack, array_joined_columns); + getActionsImpl(node->arguments->children[0], no_subqueries, only_consts, actions_stack); /// Превратим tuple или подзапрос в множество. makeSet(node, actions_stack.getSampleBlock()); } @@ -574,7 +598,7 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl fake_column.type = new DataTypeUInt8; fake_column.column = new ColumnConstUInt8(1, 0); actions_stack.addAction(ExpressionActions::Action::addColumn(fake_column)); - getActionsImpl(node->arguments, no_subqueries, only_consts, actions_stack, array_joined_columns); + getActionsImpl(node->arguments, no_subqueries, only_consts, actions_stack); return; } } @@ -627,7 +651,7 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl else { /// Если аргумент не лямбда-выражение, вызовемся рекурсивно и узнаем его тип. - getActionsImpl(child, no_subqueries, only_consts, actions_stack, array_joined_columns); + getActionsImpl(child, no_subqueries, only_consts, actions_stack); std::string name = child->getColumnName(); if (actions_stack.getSampleBlock().has(name)) { @@ -683,7 +707,7 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl } actions_stack.pushLevel(lambda_arguments); - getActionsImpl(lambda->arguments->children[1], no_subqueries, only_consts, actions_stack, array_joined_columns); + getActionsImpl(lambda->arguments->children[1], no_subqueries, only_consts, actions_stack); ExpressionActionsPtr lambda_actions = actions_stack.popLevel(); String result_name = lambda->arguments->children[1]->getColumnName(); @@ -738,21 +762,10 @@ void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool onl actions_stack.addAction(ExpressionActions::Action::addColumn(column)); } - else if (ASTIdentifier * node = dynamic_cast(&*ast)) - { - if (select_query && - select_query->array_join_identifier && - node->kind == ASTIdentifier::Column && - (node->name == select_query->array_join_identifier->getColumnName() - || DataTypeNested::extractNestedTableName(node->name) == select_query->array_join_identifier->getColumnName())) - { - array_joined_columns.insert(node->name); - } - } else { for (ASTs::iterator it = ast->children.begin(); it != ast->children.end(); ++it) - getActionsImpl(*it, no_subqueries, only_consts, actions_stack, array_joined_columns); + getActionsImpl(*it, no_subqueries, only_consts, actions_stack); } }