1#pragma once
2
3#include <Core/Names.h>
4#include <Parsers/ASTFunction.h>
5#include <Interpreters/InDepthNodeVisitor.h>
6#include <Interpreters/DatabaseAndTableWithAlias.h>
7#include <Interpreters/Aliases.h>
8
9
10namespace DB
11{
12
13class ASTIdentifier;
14class AnalyzedJoin;
15
16namespace ASOF
17{
18 enum class Inequality;
19}
20
21class CollectJoinOnKeysMatcher
22{
23public:
24 using Visitor = ConstInDepthNodeVisitor<CollectJoinOnKeysMatcher, true>;
25
26 struct Data
27 {
28 AnalyzedJoin & analyzed_join;
29 const TableWithColumnNames & left_table;
30 const TableWithColumnNames & right_table;
31 const Aliases & aliases;
32 const bool is_asof{false};
33 ASTPtr asof_left_key{};
34 ASTPtr asof_right_key{};
35 bool has_some{false};
36
37 void addJoinKeys(const ASTPtr & left_ast, const ASTPtr & right_ast, const std::pair<size_t, size_t> & table_no);
38 void addAsofJoinKeys(const ASTPtr & left_ast, const ASTPtr & right_ast, const std::pair<size_t, size_t> & table_no,
39 const ASOF::Inequality & asof_inequality);
40 void asofToJoinKeys();
41 };
42
43 static void visit(const ASTPtr & ast, Data & data)
44 {
45 if (auto * func = ast->as<ASTFunction>())
46 visit(*func, ast, data);
47 }
48
49 static bool needChildVisit(const ASTPtr & node, const ASTPtr &)
50 {
51 if (auto * func = node->as<ASTFunction>())
52 if (func->name == "equals")
53 return false;
54 return true;
55 }
56
57private:
58 static void visit(const ASTFunction & func, const ASTPtr & ast, Data & data);
59
60 static void getIdentifiers(const ASTPtr & ast, std::vector<const ASTIdentifier *> & out);
61 static std::pair<size_t, size_t> getTableNumbers(const ASTPtr & expr, const ASTPtr & left_ast, const ASTPtr & right_ast, Data & data);
62 static const ASTIdentifier * unrollAliases(const ASTIdentifier * identifier, const Aliases & aliases);
63 static size_t getTableForIdentifiers(std::vector<const ASTIdentifier *> & identifiers, const Data & data);
64
65 [[noreturn]] static void throwSyntaxException(const String & msg);
66};
67
68/// Parse JOIN ON expression and collect ASTs for joined columns.
69using CollectJoinOnKeysVisitor = CollectJoinOnKeysMatcher::Visitor;
70
71}
72