1#include <Interpreters/ColumnNamesContext.h>
2#include <Interpreters/IdentifierSemantic.h>
3#include <DataTypes/NestedUtils.h>
4
5namespace DB
6{
7
8bool ColumnNamesContext::addTableAliasIfAny(const IAST & ast)
9{
10 String alias = ast.tryGetAlias();
11 if (alias.empty())
12 return false;
13
14 table_aliases.insert(alias);
15 return true;
16}
17
18bool ColumnNamesContext::addColumnAliasIfAny(const IAST & ast)
19{
20 String alias = ast.tryGetAlias();
21 if (alias.empty())
22 return false;
23
24 if (required_names.count(alias))
25 masked_columns.insert(alias);
26
27 complex_aliases.insert(alias);
28 return true;
29}
30
31void ColumnNamesContext::addColumnIdentifier(const ASTIdentifier & node)
32{
33 if (!IdentifierSemantic::getColumnName(node))
34 return;
35
36 /// There should be no complex cases after query normalization. Names to aliases: one-to-many.
37 String alias = node.tryGetAlias();
38 required_names[node.name].addInclusion(alias);
39}
40
41bool ColumnNamesContext::addArrayJoinAliasIfAny(const IAST & ast)
42{
43 String alias = ast.tryGetAlias();
44 if (alias.empty())
45 return false;
46
47 array_join_columns.insert(alias);
48 return true;
49}
50
51void ColumnNamesContext::addArrayJoinIdentifier(const ASTIdentifier & node)
52{
53 array_join_columns.insert(node.name);
54}
55
56size_t ColumnNamesContext::nameInclusion(const String & name) const
57{
58 auto it = required_names.find(name);
59 if (it != required_names.end())
60 return it->second.appears;
61 return 0;
62}
63
64NameSet ColumnNamesContext::requiredColumns() const
65{
66 NameSet required;
67 for (const auto & pr : required_names)
68 {
69 const auto & name = pr.first;
70 String table_name = Nested::extractTableName(name);
71
72 /// Tech debt. There's its own logic for ARRAY JOIN columns.
73 if (array_join_columns.count(name) || array_join_columns.count(table_name))
74 continue;
75
76 if (!complex_aliases.count(name) || masked_columns.count(name))
77 required.insert(name);
78 }
79 return required;
80}
81
82std::ostream & operator << (std::ostream & os, const ColumnNamesContext & cols)
83{
84 os << "required_names: ";
85 for (const auto & pr : cols.required_names)
86 {
87 os << "'" << pr.first << "'";
88 for (auto & alias : pr.second.aliases)
89 os << "/'" << alias << "'";
90 }
91 os << " source_tables: ";
92 for (const auto & x : cols.tables)
93 {
94 auto alias = x.alias();
95 auto name = x.name();
96 if (alias && name)
97 os << "'" << *alias << "'/'" << *name << "' ";
98 else if (alias)
99 os << "'" << *alias << "' ";
100 else if (name)
101 os << "'" << *name << "' ";
102 }
103 os << "table_aliases: ";
104 for (const auto & x : cols.table_aliases)
105 os << "'" << x << "' ";
106 os << "complex_aliases: ";
107 for (const auto & x : cols.complex_aliases)
108 os << "'" << x << "' ";
109 os << "masked_columns: ";
110 for (const auto & x : cols.masked_columns)
111 os << "'" << x << "' ";
112 os << "array_join_columns: ";
113 for (const auto & x : cols.array_join_columns)
114 os << "'" << x << "' ";
115 return os;
116}
117
118}
119