fix lost AST chenges in InDepthNodeVisitor

This commit is contained in:
chertus 2018-12-07 17:24:47 +03:00
parent 75af882cf3
commit e26c3327cf
6 changed files with 31 additions and 33 deletions

View File

@ -28,10 +28,12 @@ public:
if constexpr (!_topToBottom) if constexpr (!_topToBottom)
visitChildren(ast); visitChildren(ast);
auto additional_nodes = Matcher::visit(ast, data); /// It operates with ASTPtr * cause we may want to rewrite ASTPtr in visit().
std::vector<ASTPtr *> additional_nodes = Matcher::visit(ast, data);
/// visit additional nodes (ex. only part of children) /// visit additional nodes (ex. only part of children)
for (ASTPtr & node : additional_nodes) for (ASTPtr * node : additional_nodes)
visit(node); visit(*node);
if constexpr (_topToBottom) if constexpr (_topToBottom)
visitChildren(ast); visitChildren(ast);

View File

@ -39,7 +39,7 @@ bool QueryAliasesMatcher::needChildVisit(ASTPtr & node, const ASTPtr &)
return true; return true;
} }
std::vector<ASTPtr> QueryAliasesMatcher::visit(ASTPtr & ast, Data & data) std::vector<ASTPtr *> QueryAliasesMatcher::visit(ASTPtr & ast, Data & data)
{ {
if (auto * t = typeid_cast<ASTSubquery *>(ast.get())) if (auto * t = typeid_cast<ASTSubquery *>(ast.get()))
return visit(*t, ast, data); return visit(*t, ast, data);
@ -52,24 +52,24 @@ std::vector<ASTPtr> QueryAliasesMatcher::visit(ASTPtr & ast, Data & data)
/// The top-level aliases in the ARRAY JOIN section have a special meaning, we will not add them /// The top-level aliases in the ARRAY JOIN section have a special meaning, we will not add them
/// (skip the expression list itself and its children). /// (skip the expression list itself and its children).
std::vector<ASTPtr> QueryAliasesMatcher::visit(const ASTArrayJoin &, const ASTPtr & ast, Data & data) std::vector<ASTPtr *> QueryAliasesMatcher::visit(const ASTArrayJoin &, const ASTPtr & ast, Data & data)
{ {
visitOther(ast, data); visitOther(ast, data);
/// @warning It breaks botom-to-top order (childs processed after node here), could lead to some effects. /// @warning It breaks botom-to-top order (childs processed after node here), could lead to some effects.
/// It's possible to add ast back to result vec to save order. It will need two phase ASTArrayJoin visit (setting phase in data). /// It's possible to add ast back to result vec to save order. It will need two phase ASTArrayJoin visit (setting phase in data).
std::vector<ASTPtr> out; std::vector<ASTPtr *> out;
for (auto & child1 : ast->children) for (auto & child1 : ast->children)
for (auto & child2 : child1->children) for (auto & child2 : child1->children)
for (auto & child3 : child2->children) for (auto & child3 : child2->children)
out.push_back(child3); out.push_back(&child3);
return out; return out;
} }
/// set unique aliases for all subqueries. this is needed, because: /// set unique aliases for all subqueries. this is needed, because:
/// 1) content of subqueries could change after recursive analysis, and auto-generated column names could become incorrect /// 1) content of subqueries could change after recursive analysis, and auto-generated column names could become incorrect
/// 2) result of different scalar subqueries can be cached inside expressions compilation cache and must have different names /// 2) result of different scalar subqueries can be cached inside expressions compilation cache and must have different names
std::vector<ASTPtr> QueryAliasesMatcher::visit(ASTSubquery & subquery, const ASTPtr & ast, Data & data) std::vector<ASTPtr *> QueryAliasesMatcher::visit(ASTSubquery & subquery, const ASTPtr & ast, Data & data)
{ {
Aliases & aliases = data.aliases; Aliases & aliases = data.aliases;

View File

@ -24,12 +24,12 @@ public:
static constexpr const char * label = "QueryAliases"; static constexpr const char * label = "QueryAliases";
static std::vector<ASTPtr> visit(ASTPtr & ast, Data & data); static std::vector<ASTPtr *> visit(ASTPtr & ast, Data & data);
static bool needChildVisit(ASTPtr & node, const ASTPtr & child); static bool needChildVisit(ASTPtr & node, const ASTPtr & child);
private: private:
static std::vector<ASTPtr> visit(ASTSubquery & subquery, const ASTPtr & ast, Data & data); static std::vector<ASTPtr *> visit(ASTSubquery & subquery, const ASTPtr & ast, Data & data);
static std::vector<ASTPtr> visit(const ASTArrayJoin &, const ASTPtr & ast, Data & data); static std::vector<ASTPtr *> visit(const ASTArrayJoin &, const ASTPtr & ast, Data & data);
static void visitOther(const ASTPtr & ast, Data & data); static void visitOther(const ASTPtr & ast, Data & data);
}; };

View File

@ -37,7 +37,7 @@ bool TranslateQualifiedNamesMatcher::needChildVisit(ASTPtr & node, const ASTPtr
return true; return true;
} }
std::vector<ASTPtr> TranslateQualifiedNamesMatcher::visit(ASTPtr & ast, Data & data) std::vector<ASTPtr *> TranslateQualifiedNamesMatcher::visit(ASTPtr & ast, Data & data)
{ {
if (auto * t = typeid_cast<ASTIdentifier *>(ast.get())) if (auto * t = typeid_cast<ASTIdentifier *>(ast.get()))
return visit(*t, ast, data); return visit(*t, ast, data);
@ -50,7 +50,7 @@ std::vector<ASTPtr> TranslateQualifiedNamesMatcher::visit(ASTPtr & ast, Data & d
return {}; return {};
} }
std::vector<ASTPtr> TranslateQualifiedNamesMatcher::visit(const ASTIdentifier & identifier, ASTPtr & ast, Data & data) std::vector<ASTPtr *> TranslateQualifiedNamesMatcher::visit(const ASTIdentifier & identifier, ASTPtr & ast, Data & data)
{ {
const NameSet & source_columns = data.source_columns; const NameSet & source_columns = data.source_columns;
const std::vector<DatabaseAndTableWithAlias> & tables = data.tables; const std::vector<DatabaseAndTableWithAlias> & tables = data.tables;
@ -87,7 +87,7 @@ std::vector<ASTPtr> TranslateQualifiedNamesMatcher::visit(const ASTIdentifier &
return {}; return {};
} }
std::vector<ASTPtr> TranslateQualifiedNamesMatcher::visit(const ASTQualifiedAsterisk & , const ASTPtr & ast, Data & data) std::vector<ASTPtr *> TranslateQualifiedNamesMatcher::visit(const ASTQualifiedAsterisk & , const ASTPtr & ast, Data & data)
{ {
const std::vector<DatabaseAndTableWithAlias> & tables = data.tables; const std::vector<DatabaseAndTableWithAlias> & tables = data.tables;
@ -125,26 +125,26 @@ std::vector<ASTPtr> TranslateQualifiedNamesMatcher::visit(const ASTQualifiedAste
throw Exception("Unknown qualified identifier: " + ident->getAliasOrColumnName(), ErrorCodes::UNKNOWN_IDENTIFIER); throw Exception("Unknown qualified identifier: " + ident->getAliasOrColumnName(), ErrorCodes::UNKNOWN_IDENTIFIER);
} }
std::vector<ASTPtr> TranslateQualifiedNamesMatcher::visit(const ASTTableJoin & join, const ASTPtr & , Data &) std::vector<ASTPtr *> TranslateQualifiedNamesMatcher::visit(ASTTableJoin & join, const ASTPtr & , Data &)
{ {
/// Don't translate on_expression here in order to resolve equation parts later. /// Don't translate on_expression here in order to resolve equation parts later.
std::vector<ASTPtr> out; std::vector<ASTPtr *> out;
if (join.using_expression_list) if (join.using_expression_list)
out.push_back(join.using_expression_list); out.push_back(&join.using_expression_list);
return out; return out;
} }
std::vector<ASTPtr> TranslateQualifiedNamesMatcher::visit(const ASTSelectQuery & select, const ASTPtr & , Data &) std::vector<ASTPtr *> TranslateQualifiedNamesMatcher::visit(ASTSelectQuery & select, const ASTPtr & , Data &)
{ {
/// If the WHERE clause or HAVING consists of a single quailified column, the reference must be translated not only in children, /// If the WHERE clause or HAVING consists of a single quailified column, the reference must be translated not only in children,
/// but also in where_expression and having_expression. /// but also in where_expression and having_expression.
std::vector<ASTPtr> out; std::vector<ASTPtr *> out;
if (select.prewhere_expression) if (select.prewhere_expression)
out.push_back(select.prewhere_expression); out.push_back(&select.prewhere_expression);
if (select.where_expression) if (select.where_expression)
out.push_back(select.where_expression); out.push_back(&select.where_expression);
if (select.having_expression) if (select.having_expression)
out.push_back(select.having_expression); out.push_back(&select.having_expression);
return out; return out;
} }

View File

@ -25,14 +25,14 @@ public:
static constexpr const char * label = "TranslateQualifiedNames"; static constexpr const char * label = "TranslateQualifiedNames";
static std::vector<ASTPtr> visit(ASTPtr & ast, Data & data); static std::vector<ASTPtr *> visit(ASTPtr & ast, Data & data);
static bool needChildVisit(ASTPtr & node, const ASTPtr & child); static bool needChildVisit(ASTPtr & node, const ASTPtr & child);
private: private:
static std::vector<ASTPtr> visit(const ASTIdentifier & node, ASTPtr & ast, Data &); static std::vector<ASTPtr *> visit(const ASTIdentifier & node, ASTPtr & ast, Data &);
static std::vector<ASTPtr> visit(const ASTQualifiedAsterisk & node, const ASTPtr & ast, Data &); static std::vector<ASTPtr *> visit(const ASTQualifiedAsterisk & node, const ASTPtr & ast, Data &);
static std::vector<ASTPtr> visit(const ASTTableJoin & node, const ASTPtr & ast, Data &); static std::vector<ASTPtr *> visit(ASTTableJoin & node, const ASTPtr & ast, Data &);
static std::vector<ASTPtr> visit(const ASTSelectQuery & node, const ASTPtr & ast, Data &); static std::vector<ASTPtr *> visit(ASTSelectQuery & node, const ASTPtr & ast, Data &);
}; };
/// Visits AST for names qualification. /// Visits AST for names qualification.

View File

@ -62,11 +62,7 @@ private:
size_t & visit_depth; /// shared with children size_t & visit_depth; /// shared with children
const char * label; const char * label;
String nodeId() const String nodeId() const { return ast.getID(' '); }
{
String id = ast.getID(' ');
return id;
}
void printNode() const void printNode() const
{ {
@ -77,7 +73,7 @@ private:
print("alias", aslias, " "); print("alias", aslias, " ");
if (!ast.children.empty()) if (!ast.children.empty())
print("/", ast.children.size(), " "); /// slash is just a short name for 'children' here print("children", ast.children.size(), " ");
} }
}; };