提交 9236e94e 编写于 作者: C chertus

ExecuteScalarSubqueriesVisitor via InDepthNodeVisitor

上级 66d73025
......@@ -35,17 +35,17 @@ static ASTPtr addTypeConversion(std::unique_ptr<ASTLiteral> && ast, const String
return res;
}
void ExecuteScalarSubqueriesVisitor::visit(const ASTSubquery & subquery, ASTPtr & ast) const
void ExecuteScalarSubqueriesMatcher::visit(const ASTSubquery & subquery, ASTPtr & ast, Data & data)
{
Context subquery_context = context;
Settings subquery_settings = context.getSettings();
Context subquery_context = data.context;
Settings subquery_settings = data.context.getSettings();
subquery_settings.max_result_rows = 1;
subquery_settings.extremes = 0;
subquery_context.setSettings(subquery_settings);
ASTPtr subquery_select = subquery.children.at(0);
BlockIO res = InterpreterSelectWithUnionQuery(
subquery_select, subquery_context, {}, QueryProcessingStage::Complete, subquery_depth + 1).execute();
subquery_select, subquery_context, {}, QueryProcessingStage::Complete, data.subquery_depth + 1).execute();
Block block;
try
......@@ -100,31 +100,29 @@ void ExecuteScalarSubqueriesVisitor::visit(const ASTSubquery & subquery, ASTPtr
}
}
void ExecuteScalarSubqueriesVisitor::visit(const ASTTableExpression &, ASTPtr &) const
{
/// Don't descend into subqueries in FROM section.
}
void ExecuteScalarSubqueriesVisitor::visit(const ASTFunction & func, ASTPtr & ast) const
std::vector<ASTPtr *> ExecuteScalarSubqueriesMatcher::visit(const ASTFunction & func, ASTPtr & ast, Data &)
{
/// Don't descend into subqueries in arguments of IN operator.
/// But if an argument is not subquery, than deeper may be scalar subqueries and we need to descend in them.
std::vector<ASTPtr *> out;
if (functionIsInOrGlobalInOperator(func.name))
{
for (auto & child : ast->children)
{
if (child != func.arguments)
visit(child);
out.push_back(&child);
else
for (size_t i = 0, size = func.arguments->children.size(); i < size; ++i)
if (i != 1 || !typeid_cast<ASTSubquery *>(func.arguments->children[i].get()))
visit(func.arguments->children[i]);
out.push_back(&func.arguments->children[i]);
}
}
else
visitChildren(ast);
for (auto & child : ast->children)
out.push_back(&child);
return out;
}
}
......@@ -2,10 +2,10 @@
#include <Common/typeid_cast.h>
#include <Interpreters/Context.h>
#include <Parsers/DumpASTNode.h>
#include <Parsers/ASTSubquery.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Parsers/ASTFunction.h>
#include <Interpreters/InDepthNodeVisitor.h>
namespace DB
{
......@@ -29,51 +29,45 @@ namespace DB
* Scalar subqueries are executed on the request-initializer server.
* The request is sent to remote servers with already substituted constants.
*/
class ExecuteScalarSubqueriesVisitor
class ExecuteScalarSubqueriesMatcher
{
public:
ExecuteScalarSubqueriesVisitor(const Context & context_, size_t subquery_depth_, std::ostream * ostr_ = nullptr)
: context(context_),
subquery_depth(subquery_depth_),
visit_depth(0),
ostr(ostr_)
{}
void visit(ASTPtr & ast) const
struct Data
{
if (!tryVisit<ASTSubquery>(ast) &&
!tryVisit<ASTTableExpression>(ast) &&
!tryVisit<ASTFunction>(ast))
visitChildren(ast);
}
const Context & context;
size_t subquery_depth;
};
private:
const Context & context;
size_t subquery_depth;
mutable size_t visit_depth;
std::ostream * ostr;
static constexpr const char * label = "ExecuteScalarSubqueries";
void visit(const ASTSubquery & subquery, ASTPtr & ast) const;
void visit(const ASTFunction & func, ASTPtr & ast) const;
void visit(const ASTTableExpression &, ASTPtr &) const;
void visitChildren(ASTPtr & ast) const
static bool needChildVisit(ASTPtr & node, const ASTPtr &)
{
for (auto & child : ast->children)
visit(child);
/// Processed
if (typeid_cast<ASTSubquery *>(node.get()) ||
typeid_cast<ASTFunction *>(node.get()))
return false;
/// Don't descend into subqueries in FROM section
if (typeid_cast<ASTTableExpression *>(node.get()))
return false;
return true;
}
template <typename T>
bool tryVisit(ASTPtr & ast) const
static std::vector<ASTPtr *> visit(ASTPtr & ast, Data & data)
{
if (const T * t = typeid_cast<const T *>(ast.get()))
{
DumpASTNode dump(*ast, ostr, visit_depth, "executeScalarSubqueries");
visit(*t, ast);
return true;
}
return false;
if (auto * t = typeid_cast<ASTSubquery *>(ast.get()))
visit(*t, ast, data);
if (auto * t = typeid_cast<ASTFunction *>(ast.get()))
return visit(*t, ast, data);
return {};
}
private:
static void visit(const ASTSubquery & subquery, ASTPtr & ast, Data & data);
static std::vector<ASTPtr *> visit(const ASTFunction & func, ASTPtr & ast, Data & data);
};
using ExecuteScalarSubqueriesVisitor = InDepthNodeVisitor<ExecuteScalarSubqueriesMatcher, true>;
}
......@@ -242,12 +242,12 @@ void ExpressionAnalyzer::analyzeAggregation()
void ExpressionAnalyzer::initGlobalSubqueriesAndExternalTables()
{
/// Adds existing external tables (not subqueries) to the external_tables dictionary.
ExternalTablesMatcher::Data tables_data{context, external_tables};
ExternalTablesVisitor::Data tables_data{context, external_tables};
ExternalTablesVisitor(tables_data).visit(query);
if (do_global)
{
GlobalSubqueriesMatcher::Data subqueries_data(context, subquery_depth, isRemoteStorage(),
GlobalSubqueriesVisitor::Data subqueries_data(context, subquery_depth, isRemoteStorage(),
external_tables, subqueries_for_sets, has_global_subqueries);
GlobalSubqueriesVisitor(subqueries_data).visit(query);
}
......@@ -1027,7 +1027,7 @@ void ExpressionAnalyzer::collectUsedColumns()
{
/// Nothing needs to be ignored for expressions in ARRAY JOIN.
NameSet empty;
RequiredSourceColumnsMatcher::Data visitor_data{available_columns, required, empty, empty, empty};
RequiredSourceColumnsVisitor::Data visitor_data{available_columns, required, empty, empty, empty};
RequiredSourceColumnsVisitor(visitor_data).visit(expressions[i]);
}
......@@ -1047,12 +1047,12 @@ void ExpressionAnalyzer::collectUsedColumns()
for (const auto & left_key_ast : syntax->analyzed_join.key_asts_left)
{
NameSet empty;
RequiredSourceColumnsMatcher::Data columns_data{available_columns, required, ignored, empty, required_joined_columns};
RequiredSourceColumnsVisitor::Data columns_data{available_columns, required, ignored, empty, required_joined_columns};
ASTPtr tmp = left_key_ast;
RequiredSourceColumnsVisitor(columns_data).visit(tmp);
}
RequiredSourceColumnsMatcher::Data columns_visitor_data{available_columns, required, ignored,
RequiredSourceColumnsVisitor::Data columns_visitor_data{available_columns, required, ignored,
available_joined_columns, required_joined_columns};
RequiredSourceColumnsVisitor(columns_visitor_data).visit(query);
......
......@@ -311,9 +311,9 @@ ASTs PredicateExpressionsOptimizer::getSelectQueryProjectionColumns(ASTPtr & ast
std::unordered_map<String, ASTPtr> aliases;
std::vector<DatabaseAndTableWithAlias> tables = getDatabaseAndTables(*select_query, context.getCurrentDatabase());
TranslateQualifiedNamesMatcher::Data qn_visitor_data{{}, tables};
TranslateQualifiedNamesVisitor::Data qn_visitor_data{{}, tables};
TranslateQualifiedNamesVisitor(qn_visitor_data).visit(ast);
QueryAliasesMatcher::Data query_aliases_data{aliases};
QueryAliasesVisitor::Data query_aliases_data{aliases};
QueryAliasesVisitor(query_aliases_data).visit(ast);
QueryNormalizer(ast, aliases, settings, {}, {}).perform();
......
......@@ -134,7 +134,7 @@ SyntaxAnalyzerResultPtr SyntaxAnalyzer::analyze(
/// Creates a dictionary `aliases`: alias -> ASTPtr
{
LogAST log;
QueryAliasesMatcher::Data query_aliases_data{result.aliases};
QueryAliasesVisitor::Data query_aliases_data{result.aliases};
QueryAliasesVisitor(query_aliases_data, log.stream()).visit(query);
}
......@@ -228,7 +228,7 @@ void translateQualifiedNames(ASTPtr & query, ASTSelectQuery * select_query,
std::vector<DatabaseAndTableWithAlias> tables = getDatabaseAndTables(*select_query, context.getCurrentDatabase());
LogAST log;
TranslateQualifiedNamesMatcher::Data visitor_data{source_columns, tables};
TranslateQualifiedNamesVisitor::Data visitor_data{source_columns, tables};
TranslateQualifiedNamesVisitor visitor(visitor_data, log.stream());
visitor.visit(query);
}
......@@ -342,8 +342,8 @@ void executeScalarSubqueries(ASTPtr & query, const ASTSelectQuery * select_query
if (!select_query)
{
ExecuteScalarSubqueriesVisitor visitor(context, subquery_depth, log.stream());
visitor.visit(query);
ExecuteScalarSubqueriesVisitor::Data visitor_data{context, subquery_depth};
ExecuteScalarSubqueriesVisitor(visitor_data, log.stream()).visit(query);
}
else
{
......@@ -353,8 +353,8 @@ void executeScalarSubqueries(ASTPtr & query, const ASTSelectQuery * select_query
if (!typeid_cast<const ASTTableExpression *>(child.get())
&& !typeid_cast<const ASTSelectQuery *>(child.get()))
{
ExecuteScalarSubqueriesVisitor visitor(context, subquery_depth, log.stream());
visitor.visit(child);
ExecuteScalarSubqueriesVisitor::Data visitor_data{context, subquery_depth};
ExecuteScalarSubqueriesVisitor(visitor_data, log.stream()).visit(child);
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册