#pragma once #include #include #include #include namespace DB { class ASTIdentifier; class ASTQualifiedAsterisk; struct ASTTableJoin; class ASTSelectQuery; class ASTExpressionList; class ASTFunction; /// Visit one node for names qualification. @sa InDepthNodeVisitor. class TranslateQualifiedNamesMatcher { public: struct Data { const NameSet & source_columns; const std::vector & tables; std::unordered_set join_using_columns; bool has_columns; Data(const NameSet & source_columns_, const std::vector & tables_, bool has_columns_ = true) : source_columns(source_columns_) , tables(tables_) , has_columns(has_columns_) {} static std::vector tablesOnly(const std::vector & tables) { std::vector tables_with_columns; tables_with_columns.reserve(tables.size()); for (const auto & table : tables) tables_with_columns.emplace_back(TableWithColumnNames{table, {}}); return tables_with_columns; } bool processAsterisks() const { return !tables.empty() && has_columns; } }; static constexpr const char * label = "TranslateQualifiedNames"; static std::vector 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(ASTExpressionList &, const ASTPtr &, Data &); static void visit(ASTFunction &, const ASTPtr &, Data &); static void extractJoinUsingColumns(const ASTPtr ast, Data & data); }; /// 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; }