reorganized adding of MULTIPLE_ARRAY_JOIN action [#CONV-7967]

This commit is contained in:
Vyacheslav Alipov 2013-07-26 16:11:31 +00:00
parent b1a45aed3e
commit 7969288677
2 changed files with 36 additions and 21 deletions

View File

@ -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);

View File

@ -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<ASTIdentifier *>(&*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<ASTFunction *>(&*ast) || dynamic_cast<ASTLiteral *>(&*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<ASTIdentifier *>(&*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);
}
}