1#pragma once
2
3#include <Parsers/IParserBase.h>
4#include <Parsers/ExpressionElementParsers.h>
5#include <Parsers/ExpressionListParsers.h>
6#include <Parsers/ASTNameTypePair.h>
7#include <Parsers/ASTColumnDeclaration.h>
8#include <Parsers/ASTIdentifier.h>
9#include <Parsers/ASTLiteral.h>
10#include <Parsers/CommonParsers.h>
11#include <Poco/String.h>
12
13
14namespace DB
15{
16
17/** A nested table. For example, Nested(UInt32 CounterID, FixedString(2) UserAgentMajor)
18 */
19class ParserNestedTable : public IParserBase
20{
21protected:
22 const char * getName() const { return "nested table"; }
23 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
24};
25
26
27/** Parametric type or Storage. For example:
28 * FixedString(10) or
29 * Partitioned(Log, ChunkID) or
30 * Nested(UInt32 CounterID, FixedString(2) UserAgentMajor)
31 * Result of parsing - ASTFunction with or without parameters.
32 */
33class ParserIdentifierWithParameters : public IParserBase
34{
35protected:
36 const char * getName() const { return "identifier with parameters"; }
37 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
38};
39
40template <typename NameParser>
41class IParserNameTypePair : public IParserBase
42{
43protected:
44 const char * getName() const { return "name and type pair"; }
45 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
46};
47
48/** The name and type are separated by a space. For example, URL String. */
49using ParserNameTypePair = IParserNameTypePair<ParserIdentifier>;
50/** Name and type separated by a space. The name can contain a dot. For example, Hits.URL String. */
51using ParserCompoundNameTypePair = IParserNameTypePair<ParserCompoundIdentifier>;
52
53template <typename NameParser>
54bool IParserNameTypePair<NameParser>::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
55{
56 NameParser name_parser;
57 ParserIdentifierWithOptionalParameters type_parser;
58
59 ASTPtr name, type;
60 if (name_parser.parse(pos, name, expected)
61 && type_parser.parse(pos, type, expected))
62 {
63 auto name_type_pair = std::make_shared<ASTNameTypePair>();
64 tryGetIdentifierNameInto(name, name_type_pair->name);
65 name_type_pair->type = type;
66 name_type_pair->children.push_back(type);
67 node = name_type_pair;
68 return true;
69 }
70
71 return false;
72}
73
74/** List of columns. */
75class ParserNameTypePairList : public IParserBase
76{
77protected:
78 const char * getName() const { return "name and type pair list"; }
79 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
80};
81
82/** List of table names. */
83class ParserNameList : public IParserBase
84{
85protected:
86 const char * getName() const { return "name list"; }
87 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
88};
89
90
91template <typename NameParser>
92class IParserColumnDeclaration : public IParserBase
93{
94public:
95 explicit IParserColumnDeclaration(bool require_type_ = true) : require_type(require_type_)
96 {
97 }
98
99protected:
100 using ASTDeclarePtr = std::shared_ptr<ASTColumnDeclaration>;
101
102 const char * getName() const { return "column declaration"; }
103
104 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
105
106 bool require_type = true;
107};
108
109using ParserColumnDeclaration = IParserColumnDeclaration<ParserIdentifier>;
110using ParserCompoundColumnDeclaration = IParserColumnDeclaration<ParserCompoundIdentifier>;
111
112template <typename NameParser>
113bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
114{
115 NameParser name_parser;
116 ParserIdentifierWithOptionalParameters type_parser;
117 ParserKeyword s_default{"DEFAULT"};
118 ParserKeyword s_materialized{"MATERIALIZED"};
119 ParserKeyword s_alias{"ALIAS"};
120 ParserKeyword s_comment{"COMMENT"};
121 ParserKeyword s_codec{"CODEC"};
122 ParserKeyword s_ttl{"TTL"};
123 ParserTernaryOperatorExpression expr_parser;
124 ParserStringLiteral string_literal_parser;
125 ParserCodec codec_parser;
126 ParserExpression expression_parser;
127
128 /// mandatory column name
129 ASTPtr name;
130 if (!name_parser.parse(pos, name, expected))
131 return false;
132
133 /** column name should be followed by type name if it
134 * is not immediately followed by {DEFAULT, MATERIALIZED, ALIAS, COMMENT}
135 */
136 ASTPtr type;
137 String default_specifier;
138 ASTPtr default_expression;
139 ASTPtr comment_expression;
140 ASTPtr codec_expression;
141 ASTPtr ttl_expression;
142
143 if (!s_default.checkWithoutMoving(pos, expected) &&
144 !s_materialized.checkWithoutMoving(pos, expected) &&
145 !s_alias.checkWithoutMoving(pos, expected) &&
146 !s_comment.checkWithoutMoving(pos, expected) &&
147 !s_codec.checkWithoutMoving(pos, expected))
148 {
149 if (!type_parser.parse(pos, type, expected))
150 return false;
151 }
152
153 Pos pos_before_specifier = pos;
154 if (s_default.ignore(pos, expected) || s_materialized.ignore(pos, expected) || s_alias.ignore(pos, expected))
155 {
156 default_specifier = Poco::toUpper(std::string{pos_before_specifier->begin, pos_before_specifier->end});
157
158 /// should be followed by an expression
159 if (!expr_parser.parse(pos, default_expression, expected))
160 return false;
161 }
162
163 if (require_type && !type && !default_expression)
164 return false; /// reject column name without type
165
166
167 if (s_comment.ignore(pos, expected))
168 {
169 /// should be followed by a string literal
170 if (!string_literal_parser.parse(pos, comment_expression, expected))
171 return false;
172 }
173
174 if (s_codec.ignore(pos, expected))
175 {
176 if (!codec_parser.parse(pos, codec_expression, expected))
177 return false;
178 }
179
180 if (s_ttl.ignore(pos, expected))
181 {
182 if (!expression_parser.parse(pos, ttl_expression, expected))
183 return false;
184 }
185
186 const auto column_declaration = std::make_shared<ASTColumnDeclaration>();
187 node = column_declaration;
188 tryGetIdentifierNameInto(name, column_declaration->name);
189
190 if (type)
191 {
192 column_declaration->type = type;
193 column_declaration->children.push_back(std::move(type));
194 }
195
196 if (default_expression)
197 {
198 column_declaration->default_specifier = default_specifier;
199 column_declaration->default_expression = default_expression;
200 column_declaration->children.push_back(std::move(default_expression));
201 }
202
203 if (comment_expression)
204 {
205 column_declaration->comment = comment_expression;
206 column_declaration->children.push_back(std::move(comment_expression));
207 }
208
209 if (codec_expression)
210 {
211 column_declaration->codec = codec_expression;
212 column_declaration->children.push_back(std::move(codec_expression));
213 }
214
215 if (ttl_expression)
216 {
217 column_declaration->ttl = ttl_expression;
218 column_declaration->children.push_back(std::move(ttl_expression));
219 }
220
221 return true;
222}
223
224class ParserColumnDeclarationList : public IParserBase
225{
226protected:
227 const char * getName() const { return "column declaration list"; }
228 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
229};
230
231
232/** name BY expr TYPE typename(arg1, arg2, ...) GRANULARITY value */
233class ParserIndexDeclaration : public IParserBase
234{
235public:
236 ParserIndexDeclaration() {}
237
238protected:
239 const char * getName() const override { return "index declaration"; }
240 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
241};
242
243class ParserConstraintDeclaration : public IParserBase
244{
245protected:
246 const char * getName() const override { return "constraint declaration"; }
247 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
248};
249
250class ParserTablePropertyDeclaration : public IParserBase
251{
252protected:
253 const char * getName() const override { return "table property (column, index, constraint) declaration"; }
254 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
255};
256
257
258class ParserIndexDeclarationList : public IParserBase
259{
260protected:
261 const char * getName() const override { return "index declaration list"; }
262 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
263};
264
265class ParserConstraintDeclarationList : public IParserBase
266{
267protected:
268 const char * getName() const override { return "constraint declaration list"; }
269 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
270};
271
272
273class ParserTablePropertiesDeclarationList : public IParserBase
274{
275protected:
276 const char * getName() const override { return "columns or indices declaration list"; }
277 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
278};
279
280
281/**
282 * ENGINE = name [PARTITION BY expr] [ORDER BY expr] [PRIMARY KEY expr] [SAMPLE BY expr] [SETTINGS name = value, ...]
283 */
284class ParserStorage : public IParserBase
285{
286protected:
287 const char * getName() const { return "storage definition"; }
288 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
289};
290
291/** Query like this:
292 * CREATE|ATTACH TABLE [IF NOT EXISTS] [db.]name
293 * (
294 * name1 type1,
295 * name2 type2,
296 * ...
297 * INDEX name1 expr TYPE type1(args) GRANULARITY value,
298 * ...
299 * ) ENGINE = engine
300 *
301 * Or:
302 * CREATE|ATTACH TABLE [IF NOT EXISTS] [db.]name AS [db2.]name2 [ENGINE = engine]
303 *
304 * Or:
305 * CREATE|ATTACH TABLE [IF NOT EXISTS] [db.]name AS ENGINE = engine SELECT ...
306 *
307 */
308class ParserCreateTableQuery : public IParserBase
309{
310protected:
311 const char * getName() const { return "CREATE TABLE or ATTACH TABLE query"; }
312 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
313};
314
315/// CREATE|ATTACH LIVE VIEW [IF NOT EXISTS] [db.]name [TO [db.]name] AS SELECT ...
316class ParserCreateLiveViewQuery : public IParserBase
317{
318protected:
319 const char * getName() const { return "CREATE LIVE VIEW query"; }
320 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
321};
322
323/// CREATE|ATTACH DATABASE db [ENGINE = engine]
324class ParserCreateDatabaseQuery : public IParserBase
325{
326protected:
327 const char * getName() const { return "CREATE DATABASE query"; }
328 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
329};
330
331/// CREATE[OR REPLACE]|ATTACH [[MATERIALIZED] VIEW] | [VIEW]] [IF NOT EXISTS] [db.]name [TO [db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...
332class ParserCreateViewQuery : public IParserBase
333{
334protected:
335 const char * getName() const { return "CREATE VIEW query"; }
336 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
337};
338
339/// Parses complete dictionary create query. Uses ParserDictionary and
340/// ParserDictionaryAttributeDeclaration. Produces ASTCreateQuery.
341/// CREATE DICTIONAY [IF NOT EXISTS] [db.]name (attrs) PRIMARY KEY key SOURCE(s(params)) LAYOUT(l(params)) LIFETIME([min v1 max] v2) [RANGE(min v1 max v2)]
342class ParserCreateDictionaryQuery : public IParserBase
343{
344protected:
345 const char * getName() const override { return "CREATE DICTIONARY"; }
346 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
347};
348
349
350/** Query like this:
351 * CREATE|ATTACH TABLE [IF NOT EXISTS] [db.]name
352 * (
353 * name1 type1,
354 * name2 type2,
355 * ...
356 * INDEX name1 expr TYPE type1(args) GRANULARITY value,
357 * ...
358 * ) ENGINE = engine
359 *
360 * Or:
361 * CREATE|ATTACH TABLE [IF NOT EXISTS] [db.]name AS [db2.]name2 [ENGINE = engine]
362 *
363 * Or:
364 * CREATE|ATTACH TABLE [IF NOT EXISTS] [db.]name AS ENGINE = engine SELECT ...
365 *
366 * Or:
367 * CREATE|ATTACH DATABASE db [ENGINE = engine]
368 *
369 * Or:
370 * CREATE[OR REPLACE]|ATTACH [[MATERIALIZED] VIEW] | [VIEW]] [IF NOT EXISTS] [db.]name [TO [db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...
371 */
372class ParserCreateQuery : public IParserBase
373{
374protected:
375 const char * getName() const { return "CREATE TABLE or ATTACH TABLE query"; }
376 bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
377};
378
379}
380