提交 9f9bf0cb 编写于 作者: C chertus

ArrayJoinedColumnsVisitor via InDepthNodeVisitor

上级 49d80bf8
......@@ -9,42 +9,55 @@
#include <Parsers/ASTIdentifier.h>
#include <DataTypes/NestedUtils.h>
#include <Interpreters/InDepthNodeVisitor.h>
namespace DB
{
/// Visitors consist of functions with unified interface 'void visit(Casted & x, ASTPtr & y)', there x is y, successfully casted to Casted.
/// Both types and fuction could have const specifiers. The second argument is used by visitor to replaces AST node (y) if needed.
/// Fills the array_join_result_to_source: on which columns-arrays to replicate, and how to call them after that.
class ArrayJoinedColumnsVisitor
class ArrayJoinedColumnsMatcher
{
public:
ArrayJoinedColumnsVisitor(NameToNameMap & array_join_name_to_alias_,
NameToNameMap & array_join_alias_to_name_,
NameToNameMap & array_join_result_to_source_)
: array_join_name_to_alias(array_join_name_to_alias_),
array_join_alias_to_name(array_join_alias_to_name_),
array_join_result_to_source(array_join_result_to_source_)
{}
void visit(ASTPtr & ast) const
struct Data
{
if (!tryVisit<ASTTablesInSelectQuery>(ast) &&
!tryVisit<ASTIdentifier>(ast))
visitChildren(ast);
}
NameToNameMap & array_join_name_to_alias;
NameToNameMap & array_join_alias_to_name;
NameToNameMap & array_join_result_to_source;
};
private:
NameToNameMap & array_join_name_to_alias;
NameToNameMap & array_join_alias_to_name;
NameToNameMap & array_join_result_to_source;
static constexpr const char * label = "ArrayJoinedColumns";
static bool needChildVisit(ASTPtr & node, const ASTPtr & child)
{
/// Processed
if (typeid_cast<ASTIdentifier *>(node.get()))
return false;
if (typeid_cast<ASTTablesInSelectQuery *>(node.get()))
return false;
void visit(const ASTTablesInSelectQuery &, ASTPtr &) const
{}
if (typeid_cast<ASTSubquery *>(child.get()) ||
typeid_cast<ASTSelectQuery *>(child.get()))
return false;
void visit(const ASTIdentifier & node, ASTPtr &) const
return true;
}
static std::vector<ASTPtr *> visit(ASTPtr & ast, Data & data)
{
if (auto * t = typeid_cast<ASTIdentifier *>(ast.get()))
visit(*t, ast, data);
return {};
}
private:
static void visit(const ASTIdentifier & node, ASTPtr &, Data & data)
{
NameToNameMap & array_join_name_to_alias = data.array_join_name_to_alias;
NameToNameMap & array_join_alias_to_name = data.array_join_alias_to_name;
NameToNameMap & array_join_result_to_source = data.array_join_result_to_source;
if (!node.general())
return;
......@@ -74,34 +87,11 @@ private:
/** Example: SELECT ParsedParams.Key1 FROM ... ARRAY JOIN ParsedParams AS PP.
*/
array_join_result_to_source[ /// PP.Key1 -> ParsedParams.Key1
Nested::concatenateName(array_join_name_to_alias[splitted.first], splitted.second)] = node.name;
}
}
void visit(const ASTSubquery &, ASTPtr &) const
{}
void visit(const ASTSelectQuery &, ASTPtr &) const
{}
void visitChildren(ASTPtr & ast) const
{
for (auto & child : ast->children)
if (!tryVisit<ASTSubquery>(child) &&
!tryVisit<ASTSelectQuery>(child))
visit(child);
}
template <typename T>
bool tryVisit(ASTPtr & ast) const
{
if (const T * t = typeid_cast<const T *>(ast.get()))
{
visit(*t, ast);
return true;
Nested::concatenateName(array_join_name_to_alias[splitted.first], splitted.second)] = node.name;
}
return false;
}
};
using ArrayJoinedColumnsVisitor = InDepthNodeVisitor<ArrayJoinedColumnsMatcher, true>;
}
......@@ -6,7 +6,7 @@
namespace DB
{
/// Visits AST tree in depth, call fucntions for nodes according to Matcher type data.
/// Visits AST tree in depth, call functions for nodes according to Matcher type data.
/// You need to define Data, label, visit() and needChildVisit() in Matcher class.
template <typename Matcher, bool _topToBottom>
class InDepthNodeVisitor
......
......@@ -697,10 +697,10 @@ void getArrayJoinedColumns(ASTPtr & query, SyntaxAnalyzerResult & result, const
}
{
ArrayJoinedColumnsVisitor visitor(result.array_join_name_to_alias,
result.array_join_alias_to_name,
result.array_join_result_to_source);
visitor.visit(query);
ArrayJoinedColumnsVisitor::Data visitor_data{result.array_join_name_to_alias,
result.array_join_alias_to_name,
result.array_join_result_to_source};
ArrayJoinedColumnsVisitor(visitor_data).visit(query);
}
/// If the result of ARRAY JOIN is not used, it is necessary to ARRAY-JOIN any column,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册