1#pragma once
2
3#include <vector>
4
5#include <Core/Names.h>
6#include <Interpreters/DatabaseAndTableWithAlias.h>
7#include <Interpreters/InDepthNodeVisitor.h>
8
9namespace DB
10{
11
12class ASTIdentifier;
13class ASTQualifiedAsterisk;
14struct ASTTableJoin;
15class ASTSelectQuery;
16class ASTExpressionList;
17class ASTFunction;
18
19/// Visit one node for names qualification. @sa InDepthNodeVisitor.
20class TranslateQualifiedNamesMatcher
21{
22public:
23 using Visitor = InDepthNodeVisitor<TranslateQualifiedNamesMatcher, true>;
24
25 struct Data
26 {
27 const NameSet source_columns;
28 const std::vector<TableWithColumnNames> tables;
29 std::unordered_set<String> join_using_columns;
30 bool has_columns;
31
32 Data(const NameSet & source_columns_, std::vector<TableWithColumnNames> && tables_, bool has_columns_ = true)
33 : source_columns(source_columns_)
34 , tables(tables_)
35 , has_columns(has_columns_)
36 {}
37
38 bool hasColumn(const String & name) const { return source_columns.count(name); }
39 bool hasTable() const { return !tables.empty(); }
40 bool processAsterisks() const { return hasTable() && has_columns; }
41 bool unknownColumn(size_t table_pos, const ASTIdentifier & node) const;
42
43 static std::vector<TableWithColumnNames> tablesOnly(const std::vector<DatabaseAndTableWithAlias> & tables)
44 {
45 std::vector<TableWithColumnNames> tables_with_columns;
46 tables_with_columns.reserve(tables.size());
47
48 for (const auto & table : tables)
49 tables_with_columns.emplace_back(TableWithColumnNames{table, {}});
50 return tables_with_columns;
51 }
52 };
53
54 static void visit(ASTPtr & ast, Data & data);
55 static bool needChildVisit(ASTPtr & node, const ASTPtr & child);
56
57private:
58 static void visit(ASTIdentifier & node, ASTPtr & ast, Data &);
59 static void visit(const ASTQualifiedAsterisk & node, const ASTPtr & ast, Data &);
60 static void visit(ASTTableJoin & node, const ASTPtr & ast, Data &);
61 static void visit(ASTSelectQuery & node, const ASTPtr & ast, Data &);
62 static void visit(ASTExpressionList &, const ASTPtr &, Data &);
63 static void visit(ASTFunction &, const ASTPtr &, Data &);
64
65 static void extractJoinUsingColumns(const ASTPtr ast, Data & data);
66};
67
68/// Visits AST for names qualification.
69/// It finds columns and translate their names to the normal form. Expand asterisks and qualified asterisks with column names.
70using TranslateQualifiedNamesVisitor = TranslateQualifiedNamesMatcher::Visitor;
71
72/// Restore ASTIdentifiers to long form
73struct RestoreQualifiedNamesData
74{
75 using TypeToVisit = ASTIdentifier;
76
77 void visit(ASTIdentifier & identifier, ASTPtr & ast);
78};
79
80using RestoreQualifiedNamesMatcher = OneTypeMatcher<RestoreQualifiedNamesData>;
81using RestoreQualifiedNamesVisitor = InDepthNodeVisitor<RestoreQualifiedNamesMatcher, true>;
82
83}
84