提交 83ceeca1 编写于 作者: Z zhang2014

ISSUES-2906 support join for table function

上级 5637b305
...@@ -623,14 +623,15 @@ void ExpressionAnalyzer::findExternalTables(ASTPtr & ast) ...@@ -623,14 +623,15 @@ void ExpressionAnalyzer::findExternalTables(ASTPtr & ast)
} }
static std::shared_ptr<InterpreterSelectWithUnionQuery> interpretSubquery( static std::shared_ptr<InterpreterSelectWithUnionQuery> interpretSubquery(
const ASTPtr & subquery_or_table_name, const Context & context, size_t subquery_depth, const Names & required_source_columns) const ASTPtr & table_expression, const Context & context, size_t subquery_depth, const Names & required_source_columns)
{ {
/// Subquery or table name. The name of the table is similar to the subquery `SELECT * FROM t`. /// Subquery or table name. The name of the table is similar to the subquery `SELECT * FROM t`.
const ASTSubquery * subquery = typeid_cast<const ASTSubquery *>(subquery_or_table_name.get()); const ASTSubquery * subquery = typeid_cast<const ASTSubquery *>(table_expression.get());
const ASTIdentifier * table = typeid_cast<const ASTIdentifier *>(subquery_or_table_name.get()); const ASTFunction * function = typeid_cast<const ASTFunction *>(table_expression.get());
const ASTIdentifier * table = typeid_cast<const ASTIdentifier *>(table_expression.get());
if (!subquery && !table) if (!subquery && !table && !function)
throw Exception("IN/JOIN supports only SELECT subqueries.", ErrorCodes::BAD_ARGUMENTS); throw Exception("Table expression is undefined, Method: ExpressionAnalyzer::interpretSubquery." , ErrorCodes::LOGICAL_ERROR);
/** The subquery in the IN / JOIN section does not have any restrictions on the maximum size of the result. /** The subquery in the IN / JOIN section does not have any restrictions on the maximum size of the result.
* Because the result of this query is not the result of the entire query. * Because the result of this query is not the result of the entire query.
...@@ -648,7 +649,7 @@ static std::shared_ptr<InterpreterSelectWithUnionQuery> interpretSubquery( ...@@ -648,7 +649,7 @@ static std::shared_ptr<InterpreterSelectWithUnionQuery> interpretSubquery(
subquery_context.setSettings(subquery_settings); subquery_context.setSettings(subquery_settings);
ASTPtr query; ASTPtr query;
if (table) if (table || function)
{ {
/// create ASTSelectQuery for "SELECT * FROM table" as if written by hand /// create ASTSelectQuery for "SELECT * FROM table" as if written by hand
const auto select_with_union_query = std::make_shared<ASTSelectWithUnionQuery>(); const auto select_with_union_query = std::make_shared<ASTSelectWithUnionQuery>();
...@@ -663,17 +664,27 @@ static std::shared_ptr<InterpreterSelectWithUnionQuery> interpretSubquery( ...@@ -663,17 +664,27 @@ static std::shared_ptr<InterpreterSelectWithUnionQuery> interpretSubquery(
select_query->select_expression_list = select_expression_list; select_query->select_expression_list = select_expression_list;
select_query->children.emplace_back(select_query->select_expression_list); select_query->children.emplace_back(select_query->select_expression_list);
NamesAndTypesList columns;
/// get columns list for target table /// get columns list for target table
auto database_table = getDatabaseAndTableNameFromIdentifier(*table); if (function)
const auto & storage = context.getTable(database_table.first, database_table.second); {
const auto & columns = storage->getColumns().ordinary; const auto & storage = const_cast<Context *>(&context)->executeTableFunction(table_expression);
select_expression_list->children.reserve(columns.size()); columns = storage->getColumns().ordinary;
select_query->addTableFunction(*const_cast<ASTPtr *>(&table_expression));
}
else
{
auto database_table = getDatabaseAndTableNameFromIdentifier(*table);
const auto & storage = context.getTable(database_table.first, database_table.second);
columns = storage->getColumns().ordinary;
select_query->replaceDatabaseAndTable(database_table.first, database_table.second);
}
select_expression_list->children.reserve(columns.size());
/// manually substitute column names in place of asterisk /// manually substitute column names in place of asterisk
for (const auto & column : columns) for (const auto & column : columns)
select_expression_list->children.emplace_back(std::make_shared<ASTIdentifier>(column.name)); select_expression_list->children.emplace_back(std::make_shared<ASTIdentifier>(column.name));
select_query->replaceDatabaseAndTable(database_table.first, database_table.second);
} }
else else
{ {
...@@ -2453,6 +2464,12 @@ NamesAndTypesList ExpressionAnalyzer::AnalyzedJoin::getColumnsFromJoinedTable(co ...@@ -2453,6 +2464,12 @@ NamesAndTypesList ExpressionAnalyzer::AnalyzedJoin::getColumnsFromJoinedTable(co
const auto & subquery = table_expression.subquery->children.at(0); const auto & subquery = table_expression.subquery->children.at(0);
nested_result_sample = InterpreterSelectWithUnionQuery::getSampleBlock(subquery, context); nested_result_sample = InterpreterSelectWithUnionQuery::getSampleBlock(subquery, context);
} }
else if (table_expression.table_function)
{
const auto table_function = table_expression.table_function;
const auto join_storage = const_cast<Context *>(&context.getQueryContext())->executeTableFunction(table_function);
nested_result_sample = join_storage->getSampleBlockNonMaterialized();
}
else if (table_expression.database_and_table_name) else if (table_expression.database_and_table_name)
{ {
const auto & identifier = static_cast<const ASTIdentifier &>(*table_expression.database_and_table_name); const auto & identifier = static_cast<const ASTIdentifier &>(*table_expression.database_and_table_name);
...@@ -2529,10 +2546,12 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty ...@@ -2529,10 +2546,12 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty
{ {
ASTPtr table; ASTPtr table;
if (table_to_join.database_and_table_name) if (table_to_join.subquery)
table = table_to_join.database_and_table_name;
else
table = table_to_join.subquery; table = table_to_join.subquery;
else if (table_to_join.table_function)
table = table_to_join.table_function;
else if (table_to_join.database_and_table_name)
table = table_to_join.database_and_table_name;
auto interpreter = interpretSubquery(table, context, subquery_depth, analyzed_join.required_columns_from_joined_table); auto interpreter = interpretSubquery(table, context, subquery_depth, analyzed_join.required_columns_from_joined_table);
subquery_for_set.source = std::make_shared<LazyBlockInputStream>( subquery_for_set.source = std::make_shared<LazyBlockInputStream>(
......
SELECT * FROM numbers(3) AS a ANY LEFT JOIN numbers(3) AS b ON a.number = b.number
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册