From 9e2aa474785557f1a1b74f102b60631ef41c9edd Mon Sep 17 00:00:00 2001 From: chertus Date: Fri, 22 Feb 2019 16:33:56 +0300 Subject: [PATCH] simplify InDepthNodeVisitor --- .../Interpreters/ArrayJoinedColumnsVisitor.h | 16 ++++----- .../Interpreters/CrossToInnerJoinVisitor.cpp | 3 +- .../Interpreters/CrossToInnerJoinVisitor.h | 4 +-- .../ExecuteScalarSubqueriesVisitor.cpp | 10 +++--- .../ExecuteScalarSubqueriesVisitor.h | 6 ++-- dbms/src/Interpreters/ExternalTablesVisitor.h | 10 ++---- .../Interpreters/GlobalSubqueriesVisitor.h | 5 +-- dbms/src/Interpreters/InDepthNodeVisitor.h | 22 ++++-------- .../JoinToSubqueryTransformVisitor.cpp | 8 ++--- .../JoinToSubqueryTransformVisitor.h | 4 +-- dbms/src/Interpreters/QueryAliasesVisitor.cpp | 28 +++++++-------- dbms/src/Interpreters/QueryAliasesVisitor.h | 13 +++---- .../RequiredSourceColumnsVisitor.cpp | 36 ++++++++++--------- .../RequiredSourceColumnsVisitor.h | 13 ++++--- .../TranslateQualifiedNamesVisitor.cpp | 29 +++++++-------- .../TranslateQualifiedNamesVisitor.h | 16 ++++----- 16 files changed, 100 insertions(+), 123 deletions(-) diff --git a/dbms/src/Interpreters/ArrayJoinedColumnsVisitor.h b/dbms/src/Interpreters/ArrayJoinedColumnsVisitor.h index 6aed743657..fc603ea313 100644 --- a/dbms/src/Interpreters/ArrayJoinedColumnsVisitor.h +++ b/dbms/src/Interpreters/ArrayJoinedColumnsVisitor.h @@ -28,6 +28,8 @@ namespace ErrorCodes class ArrayJoinedColumnsMatcher { public: + using Visitor = InDepthNodeVisitor; + struct Data { const Aliases & aliases; @@ -36,8 +38,6 @@ public: NameToNameMap & array_join_result_to_source; }; - static constexpr const char * label = "ArrayJoinedColumns"; - static bool needChildVisit(ASTPtr & node, const ASTPtr & child) { if (typeid_cast(node.get())) @@ -50,17 +50,16 @@ public: return true; } - static std::vector visit(ASTPtr & ast, Data & data) + static void visit(ASTPtr & ast, Data & data) { if (auto * t = typeid_cast(ast.get())) visit(*t, ast, data); if (auto * t = typeid_cast(ast.get())) - return visit(*t, ast, data); - return {}; + visit(*t, ast, data); } private: - static std::vector visit(const ASTSelectQuery & node, ASTPtr &, Data & data) + static void visit(const ASTSelectQuery & node, ASTPtr &, Data & data) { ASTPtr array_join_expression_list = node.array_join_expression_list(); if (!array_join_expression_list) @@ -87,7 +86,8 @@ private: out.emplace_back(&child2); } - return out; + for (ASTPtr * add_node : out) + Visitor(data).visit(*add_node); } static void visit(const ASTIdentifier & node, ASTPtr &, Data & data) @@ -130,6 +130,6 @@ private: } }; -using ArrayJoinedColumnsVisitor = InDepthNodeVisitor; +using ArrayJoinedColumnsVisitor = ArrayJoinedColumnsMatcher::Visitor; } diff --git a/dbms/src/Interpreters/CrossToInnerJoinVisitor.cpp b/dbms/src/Interpreters/CrossToInnerJoinVisitor.cpp index d455e30477..43f29046e9 100644 --- a/dbms/src/Interpreters/CrossToInnerJoinVisitor.cpp +++ b/dbms/src/Interpreters/CrossToInnerJoinVisitor.cpp @@ -181,11 +181,10 @@ static ASTPtr getCrossJoin(ASTSelectQuery & select, std::vector CrossToInnerJoinMatcher::visit(ASTPtr & ast, Data & data) +void CrossToInnerJoinMatcher::visit(ASTPtr & ast, Data & data) { if (auto * t = typeid_cast(ast.get())) visit(*t, ast, data); - return {}; } void CrossToInnerJoinMatcher::visit(ASTSelectQuery & select, ASTPtr & ast, Data & data) diff --git a/dbms/src/Interpreters/CrossToInnerJoinVisitor.h b/dbms/src/Interpreters/CrossToInnerJoinVisitor.h index c284e25d5c..522d368e3f 100644 --- a/dbms/src/Interpreters/CrossToInnerJoinVisitor.h +++ b/dbms/src/Interpreters/CrossToInnerJoinVisitor.h @@ -16,10 +16,8 @@ public: bool done = false; }; - static constexpr const char * label = "JoinToSubqueryTransform"; - static bool needChildVisit(ASTPtr &, const ASTPtr &) { return true; } - static std::vector visit(ASTPtr & ast, Data & data); + static void visit(ASTPtr & ast, Data & data); private: static void visit(ASTSelectQuery & select, ASTPtr & ast, Data & data); diff --git a/dbms/src/Interpreters/ExecuteScalarSubqueriesVisitor.cpp b/dbms/src/Interpreters/ExecuteScalarSubqueriesVisitor.cpp index cec1fa9096..09791e9b90 100644 --- a/dbms/src/Interpreters/ExecuteScalarSubqueriesVisitor.cpp +++ b/dbms/src/Interpreters/ExecuteScalarSubqueriesVisitor.cpp @@ -60,13 +60,12 @@ bool ExecuteScalarSubqueriesMatcher::needChildVisit(ASTPtr & node, const ASTPtr return true; } -std::vector ExecuteScalarSubqueriesMatcher::visit(ASTPtr & ast, Data & data) +void ExecuteScalarSubqueriesMatcher::visit(ASTPtr & ast, Data & data) { if (auto * t = typeid_cast(ast.get())) visit(*t, ast, data); if (auto * t = typeid_cast(ast.get())) - return visit(*t, ast, data); - return {}; + visit(*t, ast, data); } void ExecuteScalarSubqueriesMatcher::visit(const ASTSubquery & subquery, ASTPtr & ast, Data & data) @@ -134,7 +133,7 @@ void ExecuteScalarSubqueriesMatcher::visit(const ASTSubquery & subquery, ASTPtr } } -std::vector ExecuteScalarSubqueriesMatcher::visit(const ASTFunction & func, ASTPtr & ast, Data &) +void ExecuteScalarSubqueriesMatcher::visit(const ASTFunction & func, ASTPtr & ast, Data & 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. @@ -156,7 +155,8 @@ std::vector ExecuteScalarSubqueriesMatcher::visit(const ASTFunction & for (auto & child : ast->children) out.push_back(&child); - return out; + for (ASTPtr * add_node : out) + ExecuteScalarSubqueriesVisitor(data).visit(*add_node); } } diff --git a/dbms/src/Interpreters/ExecuteScalarSubqueriesVisitor.h b/dbms/src/Interpreters/ExecuteScalarSubqueriesVisitor.h index 555b733420..6aeaa11bc1 100644 --- a/dbms/src/Interpreters/ExecuteScalarSubqueriesVisitor.h +++ b/dbms/src/Interpreters/ExecuteScalarSubqueriesVisitor.h @@ -36,14 +36,12 @@ public: size_t subquery_depth; }; - static constexpr const char * label = "ExecuteScalarSubqueries"; - static bool needChildVisit(ASTPtr & node, const ASTPtr &); - static std::vector visit(ASTPtr & ast, Data & data); + static void visit(ASTPtr & ast, Data & data); private: static void visit(const ASTSubquery & subquery, ASTPtr & ast, Data & data); - static std::vector visit(const ASTFunction & func, ASTPtr & ast, Data & data); + static void visit(const ASTFunction & func, ASTPtr & ast, Data & data); }; using ExecuteScalarSubqueriesVisitor = InDepthNodeVisitor; diff --git a/dbms/src/Interpreters/ExternalTablesVisitor.h b/dbms/src/Interpreters/ExternalTablesVisitor.h index 2f3eecd282..c792b3a185 100644 --- a/dbms/src/Interpreters/ExternalTablesVisitor.h +++ b/dbms/src/Interpreters/ExternalTablesVisitor.h @@ -20,24 +20,20 @@ public: Tables & external_tables; }; - static constexpr const char * label = "ExternalTables"; - - static std::vector visit(ASTPtr & ast, Data & data) + static void visit(ASTPtr & ast, Data & data) { if (auto * t = typeid_cast(ast.get())) - return visit(*t, ast, data); - return {}; + visit(*t, ast, data); } static bool needChildVisit(ASTPtr &, const ASTPtr &) { return true; } private: - static std::vector visit(const ASTIdentifier & node, ASTPtr &, Data & data) + static void visit(const ASTIdentifier & node, ASTPtr &, Data & data) { if (auto opt_name = IdentifierSemantic::getTableName(node)) if (StoragePtr external_storage = data.context.tryGetExternalTable(*opt_name)) data.external_tables[*opt_name] = external_storage; - return {}; } }; diff --git a/dbms/src/Interpreters/GlobalSubqueriesVisitor.h b/dbms/src/Interpreters/GlobalSubqueriesVisitor.h index 81e45d2abe..644ed7fe5d 100644 --- a/dbms/src/Interpreters/GlobalSubqueriesVisitor.h +++ b/dbms/src/Interpreters/GlobalSubqueriesVisitor.h @@ -138,15 +138,12 @@ public: } }; - static constexpr const char * label = "GlobalSubqueries"; - - static std::vector visit(ASTPtr & ast, Data & data) + static void visit(ASTPtr & ast, Data & data) { if (auto * t = typeid_cast(ast.get())) visit(*t, ast, data); if (auto * t = typeid_cast(ast.get())) visit(*t, ast, data); - return {}; } static bool needChildVisit(ASTPtr &, const ASTPtr & child) diff --git a/dbms/src/Interpreters/InDepthNodeVisitor.h b/dbms/src/Interpreters/InDepthNodeVisitor.h index be14580bbf..7706a1fdd3 100644 --- a/dbms/src/Interpreters/InDepthNodeVisitor.h +++ b/dbms/src/Interpreters/InDepthNodeVisitor.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -8,7 +9,7 @@ namespace DB { /// 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. +/// You need to define Data, visit() and needChildVisit() in Matcher class. template class InDepthNodeVisitor { @@ -23,17 +24,12 @@ public: void visit(ASTPtr & ast) { - DumpASTNode dump(*ast, ostr, visit_depth, Matcher::label); + DumpASTNode dump(*ast, ostr, visit_depth, typeid(Matcher).name()); if constexpr (!_top_to_bottom) visitChildren(ast); - /// It operates with ASTPtr * cause we may want to rewrite ASTPtr in visit(). - std::vector additional_nodes = Matcher::visit(ast, data); - - /// visit additional nodes (ex. only part of children) - for (ASTPtr * node : additional_nodes) - visit(*node); + Matcher::visit(ast, data); if constexpr (_top_to_bottom) visitChildren(ast); @@ -60,15 +56,12 @@ public: using Data = _Data; using TypeToVisit = typename Data::TypeToVisit; - static constexpr const char * label = ""; - static bool needChildVisit(ASTPtr &, const ASTPtr &) { return _visit_children; } - static std::vector visit(ASTPtr & ast, Data & data) + static void visit(ASTPtr & ast, Data & data) { if (auto * t = typeid_cast(ast.get())) data.visit(*t, ast); - return {}; } }; @@ -79,15 +72,12 @@ class LinkedMatcher public: using Data = std::pair; - static constexpr const char * label = ""; - static bool needChildVisit(ASTPtr &, const ASTPtr &) { return true; } - static std::vector visit(ASTPtr & ast, Data & data) + static void visit(ASTPtr & ast, Data & data) { First::visit(ast, data.first); Second::visit(ast, data.second); - return {}; } }; diff --git a/dbms/src/Interpreters/JoinToSubqueryTransformVisitor.cpp b/dbms/src/Interpreters/JoinToSubqueryTransformVisitor.cpp index 16c04f0673..55a036f7d7 100644 --- a/dbms/src/Interpreters/JoinToSubqueryTransformVisitor.cpp +++ b/dbms/src/Interpreters/JoinToSubqueryTransformVisitor.cpp @@ -79,8 +79,6 @@ struct ColumnAliasesMatcher } }; - static constexpr const char * label = "ColumnAliases"; - static bool needChildVisit(ASTPtr & node, const ASTPtr &) { if (typeid_cast(node.get())) @@ -88,7 +86,7 @@ struct ColumnAliasesMatcher return true; } - static std::vector visit(ASTPtr & ast, Data & data) + static void visit(ASTPtr & ast, Data & data) { if (auto * t = typeid_cast(ast.get())) visit(*t, ast, data); @@ -96,7 +94,6 @@ struct ColumnAliasesMatcher if (typeid_cast(ast.get()) || typeid_cast(ast.get())) throw Exception("Multiple JOIN do not support asterisks yet", ErrorCodes::NOT_IMPLEMENTED); - return {}; } static void visit(ASTIdentifier & node, ASTPtr &, Data & data) @@ -225,11 +222,10 @@ using AppendSemanticVisitor = InDepthNodeVisitor; } /// namelesspace -std::vector JoinToSubqueryTransformMatcher::visit(ASTPtr & ast, Data & data) +void JoinToSubqueryTransformMatcher::visit(ASTPtr & ast, Data & data) { if (auto * t = typeid_cast(ast.get())) visit(*t, ast, data); - return {}; } void JoinToSubqueryTransformMatcher::visit(ASTSelectQuery & select, ASTPtr &, Data & data) diff --git a/dbms/src/Interpreters/JoinToSubqueryTransformVisitor.h b/dbms/src/Interpreters/JoinToSubqueryTransformVisitor.h index fcf210e657..f030131497 100644 --- a/dbms/src/Interpreters/JoinToSubqueryTransformVisitor.h +++ b/dbms/src/Interpreters/JoinToSubqueryTransformVisitor.h @@ -18,10 +18,8 @@ public: bool done = false; }; - static constexpr const char * label = "JoinToSubqueryTransform"; - static bool needChildVisit(ASTPtr &, const ASTPtr &) { return true; } - static std::vector visit(ASTPtr & ast, Data & data); + static void visit(ASTPtr & ast, Data & data); private: /// - combines two source TablesInSelectQueryElement into resulting one (Subquery) diff --git a/dbms/src/Interpreters/QueryAliasesVisitor.cpp b/dbms/src/Interpreters/QueryAliasesVisitor.cpp index 3c17f9d468..53971fc54b 100644 --- a/dbms/src/Interpreters/QueryAliasesVisitor.cpp +++ b/dbms/src/Interpreters/QueryAliasesVisitor.cpp @@ -33,26 +33,25 @@ bool QueryAliasesMatcher::needChildVisit(ASTPtr & node, const ASTPtr &) { /// Don't descent into table functions and subqueries and special case for ArrayJoin. if (typeid_cast(node.get()) || - typeid_cast(node.get()) || + typeid_cast(node.get()) || typeid_cast(node.get())) return false; return true; } -std::vector QueryAliasesMatcher::visit(ASTPtr & ast, Data & data) +void QueryAliasesMatcher::visit(ASTPtr & ast, Data & data) { - if (auto * t = typeid_cast(ast.get())) - return visit(*t, ast, data); - if (auto * t = typeid_cast(ast.get())) - return visit(*t, ast, data); - - visitOther(ast, data); - return {}; + if (auto * s = typeid_cast(ast.get())) + visit(*s, ast, data); + else if (auto * aj = typeid_cast(ast.get())) + visit(*aj, ast, data); + else + visitOther(ast, data); } /// 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). -std::vector QueryAliasesMatcher::visit(const ASTArrayJoin &, const ASTPtr & ast, Data & data) +void QueryAliasesMatcher::visit(const ASTArrayJoin &, const ASTPtr & ast, Data & data) { visitOther(ast, data); @@ -64,15 +63,17 @@ std::vector QueryAliasesMatcher::visit(const ASTArrayJoin &, const AST /// create own visitor to run bottom to top for (auto & child : grand_children) - QueryAliasesVisitor(data).visit(child); - return {}; + Visitor(data).visit(child); } /// 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 /// 2) result of different scalar subqueries can be cached inside expressions compilation cache and must have different names -std::vector QueryAliasesMatcher::visit(ASTSubquery & subquery, const ASTPtr & ast, Data & data) +void QueryAliasesMatcher::visit(ASTSubquery & subquery, const ASTPtr & ast, Data & data) { + if (!data.subqueries) + return; + Aliases & aliases = data.aliases; static std::atomic_uint64_t subquery_index = 0; @@ -92,7 +93,6 @@ std::vector QueryAliasesMatcher::visit(ASTSubquery & subquery, const A } else visitOther(ast, data); - return {}; } void QueryAliasesMatcher::visitOther(const ASTPtr & ast, Data & data) diff --git a/dbms/src/Interpreters/QueryAliasesVisitor.h b/dbms/src/Interpreters/QueryAliasesVisitor.h index 5ca712a100..775f8ae413 100644 --- a/dbms/src/Interpreters/QueryAliasesVisitor.h +++ b/dbms/src/Interpreters/QueryAliasesVisitor.h @@ -15,23 +15,24 @@ struct ASTArrayJoin; class QueryAliasesMatcher { public: + using Visitor = InDepthNodeVisitor; + struct Data { Aliases & aliases; + bool subqueries = true; }; - static constexpr const char * label = "QueryAliases"; - - static std::vector visit(ASTPtr & ast, Data & data); + static void visit(ASTPtr & ast, Data & data); static bool needChildVisit(ASTPtr & node, const ASTPtr & child); private: - static std::vector visit(ASTSubquery & subquery, const ASTPtr & ast, Data & data); - static std::vector visit(const ASTArrayJoin &, const ASTPtr & ast, Data & data); + static void visit(ASTSubquery & subquery, const ASTPtr & ast, Data & data); + static void visit(const ASTArrayJoin &, const ASTPtr & ast, Data & data); static void visitOther(const ASTPtr & ast, Data & data); }; /// Visits AST nodes and collect their aliases in one map (with links to source nodes). -using QueryAliasesVisitor = InDepthNodeVisitor; +using QueryAliasesVisitor = QueryAliasesMatcher::Visitor; } diff --git a/dbms/src/Interpreters/RequiredSourceColumnsVisitor.cpp b/dbms/src/Interpreters/RequiredSourceColumnsVisitor.cpp index a3bc0233fa..94ac9302c6 100644 --- a/dbms/src/Interpreters/RequiredSourceColumnsVisitor.cpp +++ b/dbms/src/Interpreters/RequiredSourceColumnsVisitor.cpp @@ -62,20 +62,20 @@ bool RequiredSourceColumnsMatcher::needChildVisit(ASTPtr & node, const ASTPtr & return true; } -std::vector RequiredSourceColumnsMatcher::visit(ASTPtr & ast, Data & data) +void RequiredSourceColumnsMatcher::visit(ASTPtr & ast, Data & data) { /// results are columns if (auto * t = typeid_cast(ast.get())) { visit(*t, ast, data); - return {}; + return; } if (auto * t = typeid_cast(ast.get())) { data.addColumnAliasIfAny(*ast); visit(*t, ast, data); - return {}; + return; } /// results are tables @@ -83,24 +83,25 @@ std::vector RequiredSourceColumnsMatcher::visit(ASTPtr & ast, Data & d if (auto * t = typeid_cast(ast.get())) { visit(*t, ast, data); - return {}; + return; } if (auto * t = typeid_cast(ast.get())) { //data.addTableAliasIfAny(*ast); alias is attached to child visit(*t, ast, data); - return {}; + return; } if (auto * t = typeid_cast(ast.get())) { data.addTableAliasIfAny(*ast); - return visit(*t, ast, data); + visit(*t, ast, data); + return; } if (typeid_cast(ast.get())) { data.addTableAliasIfAny(*ast); - return {}; + return; } /// other @@ -108,13 +109,12 @@ std::vector RequiredSourceColumnsMatcher::visit(ASTPtr & ast, Data & d if (auto * t = typeid_cast(ast.get())) { data.has_array_join = true; - return visit(*t, ast, data); + visit(*t, ast, data); + return; } - - return {}; } -std::vector RequiredSourceColumnsMatcher::visit(ASTSelectQuery & select, const ASTPtr &, Data & data) +void RequiredSourceColumnsMatcher::visit(ASTSelectQuery & select, const ASTPtr &, Data & data) { /// special case for top-level SELECT items: they are publics for (auto & node : select.select_expression_list->children) @@ -132,7 +132,9 @@ std::vector RequiredSourceColumnsMatcher::visit(ASTSelectQuery & selec /// revisit select_expression_list (with children) when all the aliases are set out.push_back(&select.select_expression_list); - return out; + + for (ASTPtr * add_node : out) + Visitor(data).visit(*add_node); } void RequiredSourceColumnsMatcher::visit(const ASTIdentifier & node, const ASTPtr &, Data & data) @@ -180,7 +182,7 @@ void RequiredSourceColumnsMatcher::visit(ASTTablesInSelectQueryElement & node, c data.tables.emplace_back(ColumnNamesContext::JoinedTable{expr, join}); } -std::vector RequiredSourceColumnsMatcher::visit(ASTTableExpression & node, const ASTPtr &, Data & data) +void RequiredSourceColumnsMatcher::visit(ASTTableExpression & node, const ASTPtr &, Data & data) { /// ASTIdentifiers here are tables. Do not visit them as generic ones. if (node.database_and_table_name) @@ -199,10 +201,11 @@ std::vector RequiredSourceColumnsMatcher::visit(ASTTableExpression & n out.push_back(&node.subquery); } - return out; + for (ASTPtr * add_node : out) + Visitor(data).visit(*add_node); } -std::vector RequiredSourceColumnsMatcher::visit(const ASTArrayJoin & node, const ASTPtr &, Data & data) +void RequiredSourceColumnsMatcher::visit(const ASTArrayJoin & node, const ASTPtr &, Data & data) { ASTPtr expression_list = node.expression_list; if (!expression_list || expression_list->children.empty()) @@ -224,7 +227,8 @@ std::vector RequiredSourceColumnsMatcher::visit(const ASTArrayJoin & n out.push_back(&expr); } - return out; + for (ASTPtr * add_node : out) + Visitor(data).visit(*add_node); } } diff --git a/dbms/src/Interpreters/RequiredSourceColumnsVisitor.h b/dbms/src/Interpreters/RequiredSourceColumnsVisitor.h index 4eb84b2136..ed3ec75ddc 100644 --- a/dbms/src/Interpreters/RequiredSourceColumnsVisitor.h +++ b/dbms/src/Interpreters/RequiredSourceColumnsVisitor.h @@ -21,25 +21,24 @@ struct ASTTableExpression; class RequiredSourceColumnsMatcher { public: + using Visitor = InDepthNodeVisitor; using Data = ColumnNamesContext; - static constexpr const char * label = "RequiredSourceColumns"; - static bool needChildVisit(ASTPtr & node, const ASTPtr & child); - static std::vector visit(ASTPtr & ast, Data & data); + static void visit(ASTPtr & ast, Data & data); private: static void visit(const ASTIdentifier & node, const ASTPtr &, Data & data); static void visit(const ASTFunction & node, const ASTPtr &, Data & data); static void visit(ASTTablesInSelectQueryElement & node, const ASTPtr &, Data & data); - static std::vector visit(ASTTableExpression & node, const ASTPtr &, Data & data); - static std::vector visit(const ASTArrayJoin & node, const ASTPtr &, Data & data); - static std::vector visit(ASTSelectQuery & select, const ASTPtr &, Data & data); + static void visit(ASTTableExpression & node, const ASTPtr &, Data & data); + static void visit(const ASTArrayJoin & node, const ASTPtr &, Data & data); + static void visit(ASTSelectQuery & select, const ASTPtr &, Data & data); }; /// Extracts all the information about columns and tables from ASTSelectQuery block into ColumnNamesContext object. /// It doesn't use anything but AST. It visits nodes from bottom to top except ASTFunction content to get aliases in right manner. /// @note There's some ambiguousness with nested columns names that can't be solved without schema. -using RequiredSourceColumnsVisitor = InDepthNodeVisitor; +using RequiredSourceColumnsVisitor = RequiredSourceColumnsMatcher::Visitor; } diff --git a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp index 00499ad410..07a823e345 100644 --- a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp +++ b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp @@ -44,22 +44,21 @@ bool TranslateQualifiedNamesMatcher::needChildVisit(ASTPtr & node, const ASTPtr return true; } -std::vector TranslateQualifiedNamesMatcher::visit(ASTPtr & ast, Data & data) +void TranslateQualifiedNamesMatcher::visit(ASTPtr & ast, Data & data) { if (auto * t = typeid_cast(ast.get())) - return visit(*t, ast, data); + visit(*t, ast, data); if (auto * t = typeid_cast(ast.get())) - return visit(*t, ast, data); + visit(*t, ast, data); if (auto * t = typeid_cast(ast.get())) - return visit(*t, ast, data); + visit(*t, ast, data); if (auto * node = typeid_cast(ast.get())) visit(*node, ast, data); if (auto * node = typeid_cast(ast.get())) visit(*node, ast, data); - return {}; } -std::vector TranslateQualifiedNamesMatcher::visit(ASTIdentifier & identifier, ASTPtr &, Data & data) +void TranslateQualifiedNamesMatcher::visit(ASTIdentifier & identifier, ASTPtr &, Data & data) { if (IdentifierSemantic::getColumnName(identifier)) { @@ -82,8 +81,6 @@ std::vector TranslateQualifiedNamesMatcher::visit(ASTIdentifier & iden if (!data.tables.empty()) IdentifierSemantic::setColumnNormalName(identifier, data.tables[best_table_pos].first); } - - return {}; } /// As special case, treat count(*) as count(), not as count(list of all columns). @@ -98,7 +95,7 @@ void TranslateQualifiedNamesMatcher::visit(ASTFunction & node, const ASTPtr &, D func_arguments->children.clear(); } -std::vector TranslateQualifiedNamesMatcher::visit(const ASTQualifiedAsterisk & , const ASTPtr & ast, Data & data) +void TranslateQualifiedNamesMatcher::visit(const ASTQualifiedAsterisk & , const ASTPtr & ast, Data & data) { if (ast->children.size() != 1) throw Exception("Logical error: qualified asterisk must have exactly one child", ErrorCodes::LOGICAL_ERROR); @@ -110,22 +107,24 @@ std::vector TranslateQualifiedNamesMatcher::visit(const ASTQualifiedAs for (const auto & known_table : data.tables) if (db_and_table.satisfies(known_table.first, true)) - return {}; + return; throw Exception("Unknown qualified identifier: " + ident->getAliasOrColumnName(), ErrorCodes::UNKNOWN_IDENTIFIER); } -std::vector TranslateQualifiedNamesMatcher::visit(ASTTableJoin & join, const ASTPtr & , Data &) +void TranslateQualifiedNamesMatcher::visit(ASTTableJoin & join, const ASTPtr & , Data & data) { std::vector out; if (join.using_expression_list) out.push_back(&join.using_expression_list); else if (join.on_expression) out.push_back(&join.on_expression); - return out; + + for (ASTPtr * add_node : out) + Visitor(data).visit(*add_node); } -std::vector TranslateQualifiedNamesMatcher::visit(ASTSelectQuery & select, const ASTPtr & , Data & data) +void TranslateQualifiedNamesMatcher::visit(ASTSelectQuery & select, const ASTPtr & , Data & data) { if (auto join = select.join()) extractJoinUsingColumns(join->table_join, data); @@ -139,7 +138,9 @@ std::vector TranslateQualifiedNamesMatcher::visit(ASTSelectQuery & sel out.push_back(&select.where_expression); if (select.having_expression) out.push_back(&select.having_expression); - return out; + + for (ASTPtr * add_node : out) + Visitor(data).visit(*add_node); } /// qualifed names for duplicates diff --git a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h index 15dd6e5192..f8160c2d48 100644 --- a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h +++ b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h @@ -20,6 +20,8 @@ class ASTFunction; class TranslateQualifiedNamesMatcher { public: + using Visitor = InDepthNodeVisitor; + struct Data { const NameSet & source_columns; @@ -46,16 +48,14 @@ public: bool processAsterisks() const { return !tables.empty() && has_columns; } }; - static constexpr const char * label = "TranslateQualifiedNames"; - - static std::vector visit(ASTPtr & ast, Data & data); + static void visit(ASTPtr & ast, Data & data); static bool needChildVisit(ASTPtr & node, const ASTPtr & child); private: - static std::vector visit(ASTIdentifier & node, ASTPtr & ast, Data &); - static std::vector visit(const ASTQualifiedAsterisk & node, const ASTPtr & ast, Data &); - static std::vector visit(ASTTableJoin & node, const ASTPtr & ast, Data &); - static std::vector visit(ASTSelectQuery & node, const ASTPtr & ast, Data &); + static void visit(ASTIdentifier & node, ASTPtr & ast, Data &); + static void visit(const ASTQualifiedAsterisk & node, const ASTPtr & ast, Data &); + static void visit(ASTTableJoin & node, const ASTPtr & ast, Data &); + static void visit(ASTSelectQuery & node, const ASTPtr & ast, Data &); static void visit(ASTExpressionList &, const ASTPtr &, Data &); static void visit(ASTFunction &, const ASTPtr &, Data &); @@ -64,6 +64,6 @@ private: /// Visits AST for names qualification. /// It finds columns and translate their names to the normal form. Expand asterisks and qualified asterisks with column names. -using TranslateQualifiedNamesVisitor = InDepthNodeVisitor; +using TranslateQualifiedNamesVisitor = TranslateQualifiedNamesMatcher::Visitor; }