1#include <Common/typeid_cast.h>
2#include <Parsers/ASTExpressionList.h>
3#include <Parsers/ASTTablesInSelectQuery.h>
4
5
6namespace DB
7{
8
9#define CLONE(member) \
10do \
11{ \
12 if (member) \
13 { \
14 res->member = member->clone(); \
15 res->children.push_back(res->member); \
16 } \
17} \
18while (0)
19
20
21ASTPtr 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
35ASTPtr 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
46ASTPtr 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
56ASTPtr 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
68ASTPtr 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
82void 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
122void 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
188void 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
207void 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
215void 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
226void 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
248void 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