1 | #include <Common/typeid_cast.h> |
2 | #include <Parsers/ASTExpressionList.h> |
3 | #include <Parsers/ASTTablesInSelectQuery.h> |
4 | |
5 | |
6 | namespace DB |
7 | { |
8 | |
9 | #define CLONE(member) \ |
10 | do \ |
11 | { \ |
12 | if (member) \ |
13 | { \ |
14 | res->member = member->clone(); \ |
15 | res->children.push_back(res->member); \ |
16 | } \ |
17 | } \ |
18 | while (0) |
19 | |
20 | |
21 | ASTPtr ASTTableExpression::clone() const |
22 | { |
23 | auto res = std::make_shared<ASTTableExpression>(*this); |
24 | res->children.clear(); |
25 | |
26 | CLONE(database_and_table_name); |
27 | CLONE(table_function); |
28 | CLONE(subquery); |
29 | CLONE(sample_size); |
30 | CLONE(sample_offset); |
31 | |
32 | return res; |
33 | } |
34 | |
35 | ASTPtr ASTTableJoin::clone() const |
36 | { |
37 | auto res = std::make_shared<ASTTableJoin>(*this); |
38 | res->children.clear(); |
39 | |
40 | CLONE(using_expression_list); |
41 | CLONE(on_expression); |
42 | |
43 | return res; |
44 | } |
45 | |
46 | ASTPtr ASTArrayJoin::clone() const |
47 | { |
48 | auto res = std::make_shared<ASTArrayJoin>(*this); |
49 | res->children.clear(); |
50 | |
51 | CLONE(expression_list); |
52 | |
53 | return res; |
54 | } |
55 | |
56 | ASTPtr ASTTablesInSelectQueryElement::clone() const |
57 | { |
58 | auto res = std::make_shared<ASTTablesInSelectQueryElement>(*this); |
59 | res->children.clear(); |
60 | |
61 | CLONE(table_join); |
62 | CLONE(table_expression); |
63 | CLONE(array_join); |
64 | |
65 | return res; |
66 | } |
67 | |
68 | ASTPtr ASTTablesInSelectQuery::clone() const |
69 | { |
70 | const auto res = std::make_shared<ASTTablesInSelectQuery>(*this); |
71 | res->children.clear(); |
72 | |
73 | for (const auto & child : children) |
74 | res->children.emplace_back(child->clone()); |
75 | |
76 | return res; |
77 | } |
78 | |
79 | #undef CLONE |
80 | |
81 | |
82 | void ASTTableExpression::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const |
83 | { |
84 | frame.current_select = this; |
85 | std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' '); |
86 | |
87 | if (database_and_table_name) |
88 | { |
89 | database_and_table_name->formatImpl(settings, state, frame); |
90 | } |
91 | else if (table_function) |
92 | { |
93 | table_function->formatImpl(settings, state, frame); |
94 | } |
95 | else if (subquery) |
96 | { |
97 | subquery->formatImpl(settings, state, frame); |
98 | } |
99 | |
100 | if (final) |
101 | { |
102 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << settings.nl_or_ws << indent_str |
103 | << "FINAL" << (settings.hilite ? hilite_none : "" ); |
104 | } |
105 | |
106 | if (sample_size) |
107 | { |
108 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << settings.nl_or_ws << indent_str |
109 | << "SAMPLE " << (settings.hilite ? hilite_none : "" ); |
110 | sample_size->formatImpl(settings, state, frame); |
111 | |
112 | if (sample_offset) |
113 | { |
114 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << ' ' |
115 | << "OFFSET " << (settings.hilite ? hilite_none : "" ); |
116 | sample_offset->formatImpl(settings, state, frame); |
117 | } |
118 | } |
119 | } |
120 | |
121 | |
122 | void ASTTableJoin::formatImplBeforeTable(const FormatSettings & settings, FormatState &, FormatStateStacked) const |
123 | { |
124 | settings.ostr << (settings.hilite ? hilite_keyword : "" ); |
125 | |
126 | switch (locality) |
127 | { |
128 | case Locality::Unspecified: |
129 | break; |
130 | case Locality::Local: |
131 | break; |
132 | case Locality::Global: |
133 | settings.ostr << "GLOBAL " ; |
134 | break; |
135 | } |
136 | |
137 | if (kind != Kind::Cross && kind != Kind::Comma) |
138 | { |
139 | switch (strictness) |
140 | { |
141 | case Strictness::Unspecified: |
142 | break; |
143 | case Strictness::RightAny: |
144 | case Strictness::Any: |
145 | settings.ostr << "ANY " ; |
146 | break; |
147 | case Strictness::All: |
148 | settings.ostr << "ALL " ; |
149 | break; |
150 | case Strictness::Asof: |
151 | settings.ostr << "ASOF " ; |
152 | break; |
153 | case Strictness::Semi: |
154 | settings.ostr << "SEMI " ; |
155 | break; |
156 | case Strictness::Anti: |
157 | settings.ostr << "ANTI " ; |
158 | break; |
159 | } |
160 | } |
161 | |
162 | switch (kind) |
163 | { |
164 | case Kind::Inner: |
165 | settings.ostr << "INNER JOIN" ; |
166 | break; |
167 | case Kind::Left: |
168 | settings.ostr << "LEFT JOIN" ; |
169 | break; |
170 | case Kind::Right: |
171 | settings.ostr << "RIGHT JOIN" ; |
172 | break; |
173 | case Kind::Full: |
174 | settings.ostr << "FULL OUTER JOIN" ; |
175 | break; |
176 | case Kind::Cross: |
177 | settings.ostr << "CROSS JOIN" ; |
178 | break; |
179 | case Kind::Comma: |
180 | settings.ostr << "," ; |
181 | break; |
182 | } |
183 | |
184 | settings.ostr << (settings.hilite ? hilite_none : "" ); |
185 | } |
186 | |
187 | |
188 | void ASTTableJoin::formatImplAfterTable(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const |
189 | { |
190 | frame.need_parens = false; |
191 | |
192 | if (using_expression_list) |
193 | { |
194 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << " USING " << (settings.hilite ? hilite_none : "" ); |
195 | settings.ostr << "(" ; |
196 | using_expression_list->formatImpl(settings, state, frame); |
197 | settings.ostr << ")" ; |
198 | } |
199 | else if (on_expression) |
200 | { |
201 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << " ON " << (settings.hilite ? hilite_none : "" ); |
202 | on_expression->formatImpl(settings, state, frame); |
203 | } |
204 | } |
205 | |
206 | |
207 | void ASTTableJoin::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const |
208 | { |
209 | formatImplBeforeTable(settings, state, frame); |
210 | settings.ostr << " ... " ; |
211 | formatImplAfterTable(settings, state, frame); |
212 | } |
213 | |
214 | |
215 | void ASTArrayJoin::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const |
216 | { |
217 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) |
218 | << (kind == Kind::Left ? "LEFT " : "" ) << "ARRAY JOIN " << (settings.hilite ? hilite_none : "" ); |
219 | |
220 | settings.one_line |
221 | ? expression_list->formatImpl(settings, state, frame) |
222 | : expression_list->as<ASTExpressionList &>().formatImplMultiline(settings, state, frame); |
223 | } |
224 | |
225 | |
226 | void ASTTablesInSelectQueryElement::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const |
227 | { |
228 | if (table_expression) |
229 | { |
230 | if (table_join) |
231 | { |
232 | table_join->as<ASTTableJoin &>().formatImplBeforeTable(settings, state, frame); |
233 | settings.ostr << " " ; |
234 | } |
235 | |
236 | table_expression->formatImpl(settings, state, frame); |
237 | |
238 | if (table_join) |
239 | table_join->as<ASTTableJoin &>().formatImplAfterTable(settings, state, frame); |
240 | } |
241 | else if (array_join) |
242 | { |
243 | array_join->formatImpl(settings, state, frame); |
244 | } |
245 | } |
246 | |
247 | |
248 | void ASTTablesInSelectQuery::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const |
249 | { |
250 | std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' '); |
251 | |
252 | for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it) |
253 | { |
254 | if (it != children.begin()) |
255 | settings.ostr << settings.nl_or_ws << indent_str; |
256 | |
257 | (*it)->formatImpl(settings, state, frame); |
258 | } |
259 | } |
260 | |
261 | } |
262 | |