#pragma once #include #include #include #include namespace DB { class ASTIdentifier; class AnalyzedJoin; namespace ASOF { enum class Inequality; } class CollectJoinOnKeysMatcher { public: using Visitor = ConstInDepthNodeVisitor; struct Data { AnalyzedJoin & analyzed_join; const NameSet & source_columns; const NameSet & joined_columns; const Aliases & aliases; const bool is_asof{false}; ASTPtr asof_left_key{}; ASTPtr asof_right_key{}; bool has_some{false}; void addJoinKeys(const ASTPtr & left_ast, const ASTPtr & right_ast, const std::pair & table_no); void addAsofJoinKeys(const ASTPtr & left_ast, const ASTPtr & right_ast, const std::pair & table_no, const ASOF::Inequality & asof_inequality); void asofToJoinKeys(); }; static void visit(const ASTPtr & ast, Data & data) { if (auto * func = ast->as()) visit(*func, ast, data); } static bool needChildVisit(const ASTPtr & node, const ASTPtr &) { if (auto * func = node->as()) if (func->name == "equals") return false; return true; } private: static void visit(const ASTFunction & func, const ASTPtr & ast, Data & data); static void getIdentifiers(const ASTPtr & ast, std::vector & out); static std::pair getTableNumbers(const ASTPtr & expr, const ASTPtr & left_ast, const ASTPtr & right_ast, Data & data); static const ASTIdentifier * unrollAliases(const ASTIdentifier * identifier, const Aliases & aliases); static size_t getTableForIdentifiers(std::vector & identifiers, const Data & data); [[noreturn]] static void throwSyntaxException(const String & msg); }; /// Parse JOIN ON expression and collect ASTs for joined columns. using CollectJoinOnKeysVisitor = CollectJoinOnKeysMatcher::Visitor; }