Branch data Line data Source code
1 : : #include "parse/Parser.hpp"
2 : :
3 : : #include <cerrno>
4 : : #include <cstdlib>
5 : : #include <initializer_list>
6 : : #include <mutable/catalog/Catalog.hpp>
7 : 1 : #include <mutable/catalog/Schema.hpp>
8 : 1 : #include <utility>
9 : 1 :
10 : 1 :
11 : 1 : using namespace m;
12 : 1 : using namespace m::ast;
13 : 1 :
14 : 1 :
15 : 1 : namespace {
16 : 1 :
17 : 1 : /** Returns the precedence of an operator. A higher value means the operator has higher precedence. */
18 : 6480 : int get_precedence(const TokenType tt)
19 : 1 : {
20 : 6480 : int p = 0;
21 : 1 : /* List all binary operators. The higher up an operator is in the switch statement, the higher its precedence. */
22 [ + + + + : 6480 : switch (tt) {
+ + + +
+ ]
23 : 5113 : default: return -1;
24 : 1 : /* bitwise NOT */
25 : 90 : case TK_TILDE: ++p;
26 : 1 : /* multiplicative */
27 : 1 : case TK_ASTERISK:
28 : 1 : case TK_SLASH:
29 : 158 : case TK_PERCENT: ++p;
30 : 1 : /* additive */
31 : 1 : case TK_PLUS:
32 : 232 : case TK_MINUS: ++p;
33 : 1 : /* string concat */
34 : 246 : case TK_DOTDOT: ++p;
35 : 1 : /* comparison */
36 : 1 : case TK_LESS:
37 : 1 : case TK_GREATER:
38 : 1 : case TK_LESS_EQUAL:
39 : 1 : case TK_GREATER_EQUAL:
40 : 1 : case TK_EQUAL:
41 : 1 : case TK_BANG_EQUAL:
42 : 770 : case TK_Like: ++p;
43 : 1 : /* logical NOT */
44 : 805 : case TK_Not: ++p;
45 : : /* logical AND */
46 : 1339 : case TK_And: ++p;
47 : : /* logical OR */
48 : 1367 : case TK_Or: ++p;
49 : 1367 : }
50 : 1367 : return p;
51 : 6479 : }
52 : :
53 : : /** Returns `true` if \p tt is an integral `TokenType`. */
54 : 4 : bool is_integer(TokenType tt)
55 : : {
56 [ + + ]: 4 : switch (tt) {
57 : : case TK_OCT_INT:
58 : : case TK_DEC_INT:
59 : : case TK_HEX_INT:
60 : 3 : return true;
61 : :
62 : : default:
63 : 1 : return false;
64 : : }
65 : 4 : }
66 : :
67 : 0 : }
68 : :
69 : :
70 : : /*======================================================================================================================
71 : : * Follow sets
72 : : *====================================================================================================================*/
73 : :
74 : 1 : namespace {
75 : :
76 : 38 : constexpr Parser::follow_set_t make_follow_set(std::initializer_list<TokenType> tokens)
77 : : {
78 : 38 : Parser::follow_set_t F{};
79 [ + + ]: 359 : for (TokenType tk : tokens) {
80 : 321 : M_insist(tk < TokenType::TokenType_MAX);
81 : 321 : F[tk] = true;
82 : : }
83 : 38 : return F;
84 : : }
85 : :
86 : : #define M_FOLLOW(NAME, SET) \
87 : : const Parser::follow_set_t follow_set_##NAME = make_follow_set SET ;
88 : : #include "tables/FollowSet.tbl"
89 : : #undef M_FOLLOW
90 : :
91 : : }
92 : :
93 : :
94 : : /*======================================================================================================================
95 : : * Parser
96 : : *====================================================================================================================*/
97 : :
98 : 203 : std::unique_ptr<Command> Parser::parse()
99 : : {
100 [ + + ]: 203 : if (token().type == TK_INSTRUCTION)
101 : 3 : return parse_Instruction();
102 : : else
103 : 200 : return parse_Stmt();
104 : 203 : }
105 : :
106 : 19 : std::unique_ptr<Instruction> Parser::parse_Instruction()
107 : : {
108 : 19 : auto &C = Catalog::Get();
109 : 19 : M_insist(is(TK_INSTRUCTION));
110 : :
111 : 19 : Token instr = consume();
112 [ + - ]: 19 : std::string_view sv(*(instr.text));
113 : 19 : const char *delimiter = " \n";
114 : :
115 : : /*----- Isolate the instruction's name -----*/
116 : 19 : std::string::size_type end = sv.find_first_of(delimiter);
117 [ + - + - ]: 19 : ThreadSafePooledString instruction_name = C.pool(sv.substr(1, end - 1)); // skip leading `\`
118 : :
119 : : /*----- Separate the arguments. -----*/
120 : 19 : std::vector<std::string> args;
121 : 45 : for (;;) {
122 : 45 : std::string::size_type start = sv.find_first_not_of(delimiter, end);
123 [ + + ]: 45 : if (start == std::string::npos)
124 : 19 : break;
125 : 26 : end = sv.find_first_of(delimiter, start);
126 [ + - + - ]: 26 : args.emplace_back(sv.substr(start, end - start));
127 : : }
128 : :
129 [ + - ]: 19 : expect(TK_SEMICOL);
130 [ + - ]: 19 : return std::make_unique<Instruction>(std::move(instr), std::move(instruction_name), std::move(args));
131 : 19 : }
132 : :
133 : 1358 : std::unique_ptr<Stmt> Parser::parse_Stmt()
134 : : {
135 : 1358 : Token start = token();
136 : 1358 : std::unique_ptr<Stmt> stmt = nullptr;
137 [ + - + + : 1358 : switch (token().type) {
+ + + + +
+ + + ]
138 : : default:
139 [ + - + - ]: 2 : stmt = std::make_unique<ErrorStmt>(token());
140 [ + - + - : 2 : diag.e(token().pos) << "expected a statement, got " << token().text << '\n';
+ - + - +
- + - ]
141 [ + - ]: 2 : consume();
142 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
143 : :
144 [ + - + - ]: 1 : case TK_SEMICOL: return std::make_unique<EmptyStmt>(consume());
145 : :
146 : : case TK_Create:
147 [ + - + + : 41 : switch (token<1>().type) {
+ + ]
148 : : default:
149 [ + - + - ]: 1 : stmt = std::make_unique<ErrorStmt>(token());
150 [ + - + - : 1 : diag.e(token<1>().pos) << "expected a create database statement or a create table statement, got "
+ - ]
151 [ + - + - : 1 : << token<1>().text << '\n';
+ - ]
152 [ + - ]: 1 : consume();
153 [ + - - + ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
154 : :
155 [ + - ]: 4 : case TK_Database: stmt = parse_CreateDatabaseStmt(); break;
156 [ + - ]: 29 : case TK_Table: stmt = parse_CreateTableStmt(); break;
157 : : case TK_Unique:
158 [ + - ]: 7 : case TK_Index: stmt = parse_CreateIndexStmt(); break;
159 : : }
160 : 40 : break;
161 : :
162 : : case TK_Drop:
163 [ + - - + : 11 : switch (token<1>().type) {
+ + ]
164 : : default:
165 [ # # # # ]: 0 : stmt = std::make_unique<ErrorStmt>(token());
166 [ # # # # : 0 : diag.e(token().pos) << "expected a drop database, table, or index statement, got "
# # ]
167 [ # # # # : 0 : << token().text << '\n';
# # ]
168 [ # # ]: 0 : consume();
169 [ # # # # ]: 0 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
170 : :
171 [ + - ]: 3 : case TK_Database: stmt = parse_DropDatabaseStmt(); break;
172 [ + - ]: 4 : case TK_Table: stmt = parse_DropTableStmt(); break;
173 [ + - ]: 4 : case TK_Index: stmt = parse_DropIndexStmt(); break;
174 : : }
175 : 11 : break;
176 : :
177 [ + - ]: 6 : case TK_Use: stmt = parse_UseDatabaseStmt(); break;
178 [ + - ]: 511 : case TK_Select: stmt = parse_SelectStmt(); break;
179 [ + - ]: 770 : case TK_Insert: stmt = parse_InsertStmt(); break;
180 [ + - ]: 3 : case TK_Update: stmt = parse_UpdateStmt(); break;
181 [ + - ]: 2 : case TK_Delete: stmt = parse_DeleteStmt(); break;
182 [ + - ]: 11 : case TK_Import: stmt = parse_ImportStmt(); break;
183 : : }
184 [ + - ]: 1354 : expect(TK_SEMICOL);
185 : 1354 : return stmt;
186 : 1358 : }
187 : :
188 : : /*======================================================================================================================
189 : : * statements
190 : : *====================================================================================================================*/
191 : :
192 : 12 : std::unique_ptr<Stmt> Parser::parse_CreateDatabaseStmt()
193 : : {
194 : 12 : Token start = token();
195 : :
196 : : /* 'CREATE' 'DATABASE' identifier */
197 [ + - + + ]: 12 : if (not expect(TK_Create)) {
198 [ + - ]: 1 : consume();
199 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
200 : : }
201 : :
202 [ + - + + ]: 11 : if (not expect(TK_Database))
203 [ + - + - ]: 3 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
204 : :
205 [ + - + - ]: 8 : Token database_name = token();
206 [ + - + + ]: 8 : if (not expect(TK_IDENTIFIER))
207 [ + - - + ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
208 : :
209 [ + - ]: 6 : return std::make_unique<CreateDatabaseStmt>(std::move(database_name));
210 : 12 : }
211 : :
212 : 15 : std::unique_ptr<Stmt> Parser::parse_DropDatabaseStmt()
213 : : {
214 : 15 : Token start = token();
215 : :
216 : : /* 'DROP' 'DATABASE' */
217 [ + - + + ]: 15 : if (not expect(TK_Drop)) {
218 [ + - ]: 2 : consume();
219 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
220 : : }
221 : :
222 [ + - + + ]: 13 : if (not expect(TK_Database))
223 [ + - + - ]: 3 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
224 : :
225 : : /* [ 'IF' 'EXISTS' ] */
226 : 10 : bool has_if_exists = false;
227 [ + - + + ]: 10 : if (accept(TK_If)) {
228 [ + - + + ]: 5 : if (not expect(TK_Exists))
229 [ + - - + ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
230 : 3 : has_if_exists = true;
231 : 3 : }
232 : :
233 : : /* identifier */
234 [ + - + - ]: 8 : Token database_name = token();
235 [ + - + + ]: 8 : if (not expect(TK_IDENTIFIER))
236 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
237 : :
238 [ + - ]: 7 : return std::make_unique<DropDatabaseStmt>(std::move(database_name), has_if_exists);
239 : 15 : }
240 : :
241 : 13 : std::unique_ptr<Stmt> Parser::parse_UseDatabaseStmt()
242 : : {
243 : 13 : Token start = token();
244 : :
245 : : /* 'USE' identifier */
246 [ + - + + ]: 13 : if (not expect(TK_Use)) {
247 [ + - ]: 2 : consume();
248 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
249 : : }
250 : :
251 [ + - + - ]: 11 : Token database_name = token();
252 [ + - + + ]: 11 : if (not expect(TK_IDENTIFIER))
253 [ + - - + ]: 3 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
254 : :
255 [ + - ]: 8 : return std::make_unique<UseDatabaseStmt>(std::move(database_name));
256 : 13 : }
257 : :
258 : 59 : std::unique_ptr<Stmt> Parser::parse_CreateTableStmt()
259 : : {
260 : 59 : Token start = token();
261 : 59 : std::vector<std::unique_ptr<CreateTableStmt::attribute_definition>> attrs;
262 : :
263 : : /* 'CREATE' 'TABLE' identifier '(' */
264 [ + - + + ]: 59 : if (not expect(TK_Create)) {
265 [ + - ]: 1 : consume();
266 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
267 : : }
268 : :
269 [ + - + + ]: 58 : if (not expect(TK_Table))
270 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
271 : :
272 [ + - + - ]: 56 : Token table_name = token();
273 [ + - + + ]: 56 : if (not expect(TK_IDENTIFIER))
274 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
275 : :
276 [ + - + + ]: 54 : if (not expect(TK_LPAR))
277 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
278 : :
279 : : /* identifier data-type { constraint } [ ',' identifier data-type { constraint } ] */
280 : 53 : do {
281 [ + - + - ]: 98 : Token id = token();
282 [ + - + + ]: 98 : if (not expect(TK_IDENTIFIER))
283 [ + - + - ]: 3 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
284 : :
285 [ + - + - ]: 95 : const Type *type = M_notnull(parse_data_type());
286 : :
287 : : /* Parse the list of constraints. */
288 : 95 : std::vector<std::unique_ptr<Constraint>> constraints;
289 : 140 : for (;;) {
290 [ + - + + : 140 : switch (token().type) {
+ + + + ]
291 : : /* 'PRIMARY' 'KEY' */
292 : : case TK_Primary: {
293 [ + - ]: 19 : Token tok = consume();
294 [ + - + + ]: 19 : if (not expect(TK_Key)) goto constraint_error_recovery;
295 [ + - + - ]: 18 : constraints.push_back(std::make_unique<PrimaryKeyConstraint>(std::move(tok)));
296 : 18 : break;
297 : 19 : }
298 : :
299 : : /* 'NOT' 'NULL' */
300 : : case TK_Not: {
301 [ + - ]: 7 : Token tok = consume();
302 [ + - + + ]: 7 : if (not expect(TK_Null)) goto constraint_error_recovery;
303 [ + - + - ]: 6 : constraints.push_back(std::make_unique<NotNullConstraint>(std::move(tok)));
304 : 6 : break;
305 [ - + ]: 7 : }
306 : :
307 : : /* 'UNIQUE' */
308 : : case TK_Unique: {
309 [ + - ]: 6 : Token tok = consume();
310 [ + - + - ]: 6 : constraints.push_back(std::make_unique<UniqueConstraint>(std::move(tok)));
311 : : break;
312 : 6 : }
313 : :
314 : : /* 'CHECK' '(' expression ')' */
315 : : case TK_Check: {
316 [ + - ]: 8 : Token tok = consume();
317 [ + - + + ]: 8 : if (not expect(TK_LPAR)) goto constraint_error_recovery;
318 [ + - ]: 7 : std::unique_ptr<Expr> cond = parse_Expr();
319 [ + - + - ]: 7 : if (not expect(TK_RPAR)) goto constraint_error_recovery;
320 [ + - - + ]: 7 : constraints.push_back(std::make_unique<CheckConditionConstraint>(std::move(tok), std::move(cond)));
321 : 7 : break;
322 : 8 : }
323 : :
324 : : /* 'REFERENCES' identifier '(' identifier ')' */
325 : : case TK_References: {
326 [ + - ]: 12 : Token tok = consume();
327 [ + - + - ]: 12 : Token ref_table_name = token();
328 [ + - + + ]: 12 : if (not expect(TK_IDENTIFIER)) goto constraint_error_recovery;
329 [ + - + + ]: 10 : if (not expect(TK_LPAR)) goto constraint_error_recovery;
330 [ + - + - ]: 8 : Token attr_name = token();
331 [ + - + - ]: 8 : if (not expect(TK_IDENTIFIER)) goto constraint_error_recovery;
332 [ + - + - ]: 8 : if (not expect(TK_RPAR)) goto constraint_error_recovery;
333 [ + - + - ]: 8 : constraints.push_back(std::make_unique<ReferenceConstraint>(
334 : : std::move(tok),
335 : : std::move(ref_table_name),
336 : : std::move(attr_name),
337 : 8 : ReferenceConstraint::ON_DELETE_RESTRICT)
338 : : );
339 : 8 : break;
340 : 12 : }
341 : :
342 : : default:
343 : 88 : goto exit_constraints;
344 : : }
345 : :
346 : : }
347 : : constraint_error_recovery:
348 [ + - ]: 7 : recover(follow_set_CONSTRAINT);
349 : : exit_constraints:
350 [ + - + - ]: 95 : attrs.push_back(std::make_unique<CreateTableStmt::attribute_definition>(std::move(id),
351 : : std::move(type),
352 : : std::move(constraints)));
353 [ + + + - : 98 : } while (accept(TK_COMMA));
+ + ]
354 : :
355 : : /* ')' */
356 [ + - + + ]: 50 : if (not expect(TK_RPAR))
357 [ + - + - ]: 3 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
358 : :
359 [ + - ]: 47 : return std::make_unique<CreateTableStmt>(std::move(table_name), std::move(attrs));
360 : 59 : }
361 : :
362 : 20 : std::unique_ptr<Stmt> Parser::parse_DropTableStmt()
363 : : {
364 : 20 : Token start = token();
365 : :
366 : : /* 'DROP' 'TABLE' */
367 [ + - + + ]: 20 : if (not expect(TK_Drop)) {
368 [ + - ]: 2 : consume();
369 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
370 : : }
371 : :
372 [ + - + + ]: 18 : if (not expect(TK_Table))
373 [ + - + - ]: 3 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
374 : :
375 : : /* [ 'IF' 'EXISTS' ] */
376 : 15 : bool has_if_exists = false;
377 [ + - + + ]: 15 : if (accept(TK_If)) {
378 [ + - + + ]: 8 : if (not expect(TK_Exists))
379 [ + - - + ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
380 : 6 : has_if_exists = true;
381 : 6 : }
382 : :
383 : : /* identifier { ',' identifier } */
384 : 13 : std::vector<std::unique_ptr<Token>> table_names;
385 : 13 : do {
386 [ + - + - ]: 17 : Token table_name = token();
387 [ + - + + ]: 17 : if (not expect(TK_IDENTIFIER))
388 [ + - + - ]: 5 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
389 [ + - + - ]: 12 : table_names.emplace_back(std::make_unique<Token>(std::move(table_name)));
390 [ + + + - : 17 : } while (accept(TK_COMMA));
+ + ]
391 : :
392 [ + - ]: 8 : return std::make_unique<DropTableStmt>(std::move(table_names), has_if_exists);
393 : 20 : }
394 : :
395 : 32 : std::unique_ptr<Stmt> Parser::parse_CreateIndexStmt()
396 : : {
397 : 32 : Token start = token();
398 : :
399 : : /* 'CREATE' [ 'UNIQUE' ] 'INDEX' */
400 [ + - + + ]: 32 : if (not expect(TK_Create))
401 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
402 : :
403 [ + - ]: 31 : Token has_unique = Token::CreateArtificial();
404 [ + - + - : 31 : if (token() == TK_Unique)
+ + ]
405 [ + - + - ]: 3 : has_unique = consume();
406 : :
407 [ + - + + ]: 31 : if (not expect(TK_Index))
408 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
409 : :
410 : : /* [ [ 'IF' 'NOT' 'EXISTS' ] identifier ] */
411 : 29 : bool has_if_not_exists = false;
412 [ + - ]: 29 : Token index_name = Token::CreateArtificial();
413 [ + - + + ]: 29 : if (accept(TK_If)) {
414 [ + - - + ]: 3 : if (not expect(TK_Not))
415 [ # # # # ]: 0 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
416 [ + - - + ]: 3 : if (not expect(TK_Exists))
417 [ # # # # ]: 0 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
418 : 3 : has_if_not_exists = true;
419 [ + - + - ]: 3 : index_name = token();
420 [ + - + + ]: 3 : if (not expect(TK_IDENTIFIER))
421 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
422 [ + - + + ]: 28 : } else if (token().type == TK_IDENTIFIER)
423 [ + - + - ]: 5 : index_name = consume();
424 : :
425 : : /* 'ON' identifier */
426 [ + - + + ]: 28 : if (not expect(TK_On))
427 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
428 : :
429 [ + - + - ]: 27 : Token table_name = token();
430 [ + - + + ]: 27 : if (not expect(TK_IDENTIFIER))
431 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
432 : :
433 : : /* [ 'USING' identifier */
434 [ + - ]: 26 : Token method = Token::CreateArtificial();
435 [ + - + + ]: 26 : if (accept(TK_Using)) {
436 [ + - + + : 5 : if (token().type != TK_IDENTIFIER and token().type != TK_Default) {
+ - + + ]
437 [ + - + - : 1 : diag.e(token().pos) << "expected an identifier or DEFAULT, got " << token().text << '\n';
+ - + - +
- + - ]
438 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
439 : : }
440 [ + - + - ]: 4 : method = consume();
441 : 4 : }
442 : :
443 : : /* '(' key_field { ',' key_field } ')' */
444 [ + - + + ]: 25 : if (not expect(TK_LPAR))
445 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
446 : 23 : std::vector<std::unique_ptr<Expr>> key_fields;
447 : 23 : do {
448 [ + - + + : 29 : switch (token().type) {
+ ]
449 : : /* identifier */
450 : : case TK_IDENTIFIER: {
451 [ + - + - ]: 21 : auto id = std::make_unique<Designator>(consume());
452 [ + - ]: 21 : key_fields.emplace_back(std::move(id));
453 : : break;
454 : 21 : }
455 : : /* '(' expression ')' */
456 : : case TK_LPAR: {
457 [ + - ]: 6 : auto expr = parse_Expr();
458 [ + - ]: 6 : key_fields.emplace_back(std::move(expr));
459 : : break;
460 : 6 : }
461 : : default: {
462 [ + - + - : 2 : diag.e(token().pos) << "expected an identifier or expression, got " << token().text << '\n';
+ - + - +
- + - ]
463 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
464 : : }
465 : : }
466 [ + - + + ]: 27 : } while(accept(TK_COMMA));
467 [ + - + + ]: 21 : if (not expect(TK_RPAR))
468 [ + - - + ]: 5 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
469 : :
470 [ + - ]: 16 : return std::make_unique<CreateIndexStmt>(
471 : : /* has_unique= */ std::move(has_unique),
472 : : /* has_if_not_exists= */ has_if_not_exists,
473 : : /* index_name= */ std::move(index_name),
474 : : /* table_name= */ std::move(table_name),
475 : : /* method= */ std::move(method),
476 : : /* key_fields= */ std::move(key_fields)
477 : : );
478 : 32 : }
479 : :
480 : 20 : std::unique_ptr<Stmt> Parser::parse_DropIndexStmt()
481 : : {
482 : 20 : Token start = token();
483 : :
484 : : /* 'DROP' 'INDEX' */
485 [ + - + + ]: 20 : if (not expect(TK_Drop)) {
486 [ + - ]: 2 : consume();
487 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
488 : : }
489 : :
490 [ + - + + ]: 18 : if (not expect(TK_Index))
491 [ + - + - ]: 3 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
492 : :
493 : : /* [ 'IF' 'EXISTS' ] */
494 : 15 : bool has_if_exists = false;
495 [ + - + + ]: 15 : if (accept(TK_If)) {
496 [ + - + + ]: 8 : if (not expect(TK_Exists))
497 [ + - - + ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
498 : 6 : has_if_exists = true;
499 : 6 : }
500 : :
501 : : /* identifier { ',' identifier } */
502 : 13 : std::vector<std::unique_ptr<Token>> index_names;
503 : 13 : do {
504 [ + - + - ]: 17 : Token index_name = token();
505 [ + - + + ]: 17 : if (not expect(TK_IDENTIFIER))
506 [ + - + - ]: 5 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
507 [ + - + - ]: 12 : index_names.emplace_back(std::make_unique<Token>(std::move(index_name)));
508 [ + + + - : 17 : } while (accept(TK_COMMA));
+ + ]
509 : :
510 [ + - ]: 8 : return std::make_unique<DropIndexStmt>(std::move(index_names), has_if_exists);
511 : 20 : }
512 : :
513 : 608 : std::unique_ptr<Stmt> Parser::parse_SelectStmt()
514 : : {
515 : 608 : std::unique_ptr<Clause> select = parse_SelectClause();
516 : 608 : std::unique_ptr<Clause> from = nullptr;
517 : 608 : std::unique_ptr<Clause> where = nullptr;
518 : 608 : std::unique_ptr<Clause> group_by = nullptr;
519 : 608 : std::unique_ptr<Clause> having = nullptr;
520 : 608 : std::unique_ptr<Clause> order_by = nullptr;
521 : 608 : std::unique_ptr<Clause> limit = nullptr;
522 : :
523 [ + - + - : 608 : if (token() == TK_From)
+ + ]
524 [ + - ]: 564 : from = parse_FromClause();
525 [ + - + - : 608 : if (token() == TK_Where)
+ + ]
526 [ + - ]: 203 : where = parse_WhereClause();
527 [ + - + - : 608 : if (token() == TK_Group)
+ + ]
528 [ + - ]: 62 : group_by = parse_GroupByClause();
529 [ + - + - : 608 : if (token() == TK_Having)
+ + ]
530 [ + - ]: 44 : having = parse_HavingClause();
531 [ + - + - : 608 : if (token() == TK_Order)
+ + ]
532 [ + - ]: 37 : order_by = parse_OrderByClause();
533 [ + - + - : 608 : if (token() == TK_Limit)
+ + ]
534 [ + - ]: 8 : limit = parse_LimitClause();
535 : :
536 [ + - ]: 608 : return std::make_unique<SelectStmt>(std::move(select),
537 : : std::move(from),
538 : : std::move(where),
539 : : std::move(group_by),
540 : : std::move(having),
541 : : std::move(order_by),
542 : : std::move(limit));
543 : 608 : }
544 : :
545 : 788 : std::unique_ptr<Stmt> Parser::parse_InsertStmt()
546 : : {
547 : 788 : Token start = token();
548 : :
549 : : /* 'INSERT' 'INTO' identifier 'VALUES' */
550 [ + - + + ]: 788 : if (not expect(TK_Insert)) {
551 [ + - ]: 1 : consume();
552 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
553 : : }
554 : :
555 [ + - + + ]: 787 : if (not expect(TK_Into))
556 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
557 : :
558 [ + - + - ]: 785 : Token table_name = token();
559 [ + - + + ]: 785 : if (not expect(TK_IDENTIFIER))
560 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
561 : :
562 [ + - + + ]: 783 : if (not expect(TK_Values))
563 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
564 : :
565 : : /* tuple { ',' tuple } */
566 : 781 : std::vector<InsertStmt::tuple_t> tuples;
567 : 781 : do {
568 : : /* '(' ( 'DEFAULT' | 'NULL' | expression ) { ',' ( 'DEFAULT' | 'NULL' | expression ) } ')' */
569 : 861 : InsertStmt::tuple_t tuple;
570 [ + - + + ]: 861 : if (not expect(TK_LPAR)) goto tuple_error_recovery;
571 : 859 : do {
572 [ + - + + : 3422 : switch (token().type) {
+ ]
573 : : case TK_Default:
574 [ + - ]: 6 : consume();
575 [ + - ]: 6 : tuple.emplace_back(InsertStmt::I_Default, nullptr);
576 : 6 : break;
577 : :
578 : : case TK_Null:
579 [ + - ]: 186 : consume();
580 [ + - ]: 186 : tuple.emplace_back(InsertStmt::I_Null, nullptr);
581 : 186 : break;
582 : :
583 : : default: {
584 [ - + ]: 3230 : auto e = parse_Expr();
585 [ + - ]: 3230 : tuple.emplace_back(InsertStmt::I_Expr, std::move(e));
586 : : break;
587 : 3230 : }
588 : : }
589 [ + - + + ]: 3422 : } while (accept(TK_COMMA));
590 [ + - + + ]: 859 : if (not expect(TK_RPAR)) goto tuple_error_recovery;
591 [ + - ]: 858 : tuples.emplace_back(std::move(tuple));
592 : 858 : continue;
593 : : tuple_error_recovery:
594 [ + - ]: 3 : recover(follow_set_TUPLE);
595 [ - + + + : 861 : } while (accept(TK_COMMA));
- + + ]
596 : :
597 [ + - ]: 781 : return std::make_unique<InsertStmt>(std::move(table_name), std::move(tuples));
598 : 788 : }
599 : :
600 : 14 : std::unique_ptr<Stmt> Parser::parse_UpdateStmt()
601 : : {
602 : 14 : Token start = token();
603 : :
604 : : /* 'UPDATE' identifier 'SET' */
605 [ + - + + ]: 14 : if (not expect(TK_Update)) {
606 [ + - ]: 1 : consume();
607 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
608 : : }
609 : :
610 [ + - + - ]: 13 : Token table_name = token();
611 [ + - + + ]: 13 : if (not expect(TK_IDENTIFIER))
612 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
613 : :
614 [ + - + + ]: 12 : if (not expect(TK_Set))
615 [ + - - + ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
616 : :
617 : : /* identifier '=' expression { ',' identifier '=' expression } ; */
618 : 10 : std::vector<UpdateStmt::set_type> set;
619 : 10 : do {
620 [ + - + - ]: 12 : auto id = token();
621 [ + - - + ]: 12 : if (not expect(TK_IDENTIFIER))
622 [ # # # # ]: 0 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
623 : :
624 [ + - + + ]: 12 : if (not expect(TK_EQUAL))
625 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
626 : :
627 [ + - ]: 10 : auto e = parse_Expr();
628 [ + - ]: 10 : set.emplace_back(id, std::move(e));
629 [ + + + - : 12 : } while (accept(TK_COMMA));
+ + ]
630 : :
631 : : /* [ where-clause ] */
632 : 8 : std::unique_ptr<Clause> where = nullptr;
633 [ + - + - : 8 : if (token() == TK_Where)
+ + ]
634 [ + - ]: 1 : where = parse_WhereClause();
635 : :
636 [ + - ]: 8 : return std::make_unique<UpdateStmt>(std::move(table_name), std::move(set), std::move(where));
637 : 14 : }
638 : :
639 : 14 : std::unique_ptr<Stmt> Parser::parse_DeleteStmt()
640 : : {
641 : 14 : Token start = token();
642 : :
643 : : /* 'DELETE' 'FROM' identifier */
644 [ + - + + ]: 14 : if (not expect(TK_Delete)) {
645 [ + - ]: 2 : consume();
646 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
647 : : }
648 : :
649 [ + - + + ]: 12 : if (not expect(TK_From))
650 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
651 : :
652 [ + - + - ]: 10 : Token table_name = token();
653 [ + - + + ]: 10 : if (not expect(TK_IDENTIFIER))
654 [ + - - + ]: 3 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
655 : :
656 : : /*[ where-clause ] ; */
657 : 7 : std::unique_ptr<Clause> where = nullptr;
658 [ + - + - : 7 : if (token() == TK_Where)
+ + ]
659 [ + - ]: 2 : where = parse_WhereClause();
660 : :
661 [ + - ]: 7 : return std::make_unique<DeleteStmt>(std::move(table_name), std::move(where));
662 : 14 : }
663 : :
664 : 41 : std::unique_ptr<Stmt> Parser::parse_ImportStmt()
665 : : {
666 : 41 : Token start = token();
667 : :
668 : : /* 'IMPORT' 'INTO' identifier */
669 [ + - + + ]: 41 : if (not expect(TK_Import)) {
670 [ + - ]: 3 : consume();
671 [ + - + - ]: 3 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
672 : : }
673 : :
674 [ + - + + ]: 38 : if (not expect(TK_Into))
675 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
676 : :
677 [ + - + - ]: 36 : Token table_name = token();
678 [ + - + + ]: 36 : if (not expect(TK_IDENTIFIER))
679 [ + - + - ]: 2 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
680 : :
681 [ + - + + ]: 34 : switch (token().type) {
682 : : /* 'DSV' string-literal */
683 : : case TK_Dsv: {
684 [ + - ]: 33 : consume();
685 [ + - + - ]: 33 : DSVImportStmt stmt(std::move(table_name));
686 [ + - + - ]: 33 : stmt.path = token();
687 : :
688 [ + - + + ]: 33 : if (not expect(TK_STRING_LITERAL))
689 [ + - + - ]: 4 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
690 : :
691 : : /* [ 'ROWS' integer-constant ] */
692 [ + - + + ]: 29 : if (accept(TK_Rows)) {
693 [ + - + - ]: 1 : stmt.rows = token();
694 [ + - + - : 1 : if (token() == TK_DEC_INT or token() == TK_OCT_INT) {
- + # # #
# # # ]
695 [ + - ]: 1 : consume();
696 : 1 : } else {
697 [ # # # # : 0 : diag.e(token().pos) << "expected a decimal integer, got " << token().text << '\n';
# # # # #
# # # ]
698 [ # # # # ]: 0 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
699 : : }
700 : 1 : }
701 : :
702 : : /* [ 'DELIMITER' string-literal ] */
703 [ + - + + ]: 29 : if (accept(TK_Delimiter)) {
704 [ + - + - ]: 6 : stmt.delimiter = token();
705 [ + - + + ]: 6 : if (not expect(TK_STRING_LITERAL))
706 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
707 : 5 : }
708 : :
709 : : /* [ 'ESCAPE' string-literal ] */
710 [ + - + + ]: 28 : if (accept(TK_Escape)) {
711 [ + - + - ]: 5 : stmt.escape = token();
712 [ + - + + ]: 5 : if (not expect(TK_STRING_LITERAL))
713 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
714 : 4 : }
715 : :
716 : : /* [ 'QUOTE' string-literal ] */
717 [ + - + + ]: 27 : if (accept(TK_Quote)) {
718 [ + - + - ]: 6 : stmt.quote = token();
719 [ + - + + ]: 6 : if (not expect(TK_STRING_LITERAL))
720 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
721 : 5 : }
722 : :
723 : : /* [ 'HAS' 'HEADER' ] */
724 [ + - + + ]: 26 : if (accept(TK_Has)) {
725 [ + - + + ]: 4 : if (not expect(TK_Header))
726 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
727 : 3 : stmt.has_header = true;
728 : 3 : }
729 : :
730 : : /* [ 'SKIP' 'HEADER' ] */
731 [ + - + + ]: 25 : if (accept(TK_Skip)) {
732 [ + - + + ]: 5 : if (not expect(TK_Header))
733 [ + - - + ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
734 : 4 : stmt.skip_header = true;
735 : 4 : }
736 : :
737 [ + - ]: 24 : return std::make_unique<DSVImportStmt>(stmt);
738 : 33 : }
739 : :
740 : : default:
741 [ + - + - : 1 : diag.e(token().pos) << "Unrecognized input format \"" << token().text << "\".\n";
+ - + - +
- + - ]
742 [ + - + - ]: 1 : return recover<ErrorStmt>(std::move(start), follow_set_STATEMENT);
743 : : }
744 : 41 : }
745 : :
746 : : /*======================================================================================================================
747 : : * Clauses
748 : : *====================================================================================================================*/
749 : :
750 : 639 : std::unique_ptr<Clause> Parser::parse_SelectClause()
751 : : {
752 : 639 : Token start = token();
753 : :
754 : : /* 'SELECT' */
755 [ + - + + ]: 639 : if (not expect(TK_Select)) {
756 [ + - ]: 5 : consume();
757 [ + - + - ]: 5 : return recover<ErrorClause>(std::move(start), follow_set_SELECT_CLAUSE);
758 : : }
759 : :
760 : : /* ( '*' | expression [ [ 'AS' ] identifier ] ) */
761 [ + - ]: 634 : Token select_all = Token::CreateArtificial();
762 : 634 : std::vector<SelectClause::select_type> select;
763 [ + - + - : 634 : if (token() == TK_ASTERISK) {
+ + ]
764 [ + - + - ]: 296 : select_all = token();
765 [ + - ]: 296 : consume();
766 : 296 : } else {
767 [ + - ]: 338 : auto e = parse_Expr();
768 [ + - ]: 338 : Token tok = Token::CreateArtificial();
769 [ + - + + ]: 338 : if (accept(TK_As)) {
770 [ + - + - ]: 37 : tok = token();
771 [ + - + + ]: 37 : if (not expect(TK_IDENTIFIER))
772 [ + - - + ]: 2 : return recover<ErrorClause>(std::move(start), follow_set_SELECT_CLAUSE);
773 [ + - + + ]: 336 : } else if (token().type == TK_IDENTIFIER) {
774 [ + - + - ]: 5 : tok = token();
775 [ + - ]: 5 : consume();
776 : 5 : }
777 [ + - ]: 336 : select.emplace_back(std::move(e), std::move(tok));
778 [ + + ]: 338 : }
779 : :
780 : : /* { ',' expression [ [ 'AS' ] identifier ] } */
781 [ + - + + ]: 696 : while (accept(TK_COMMA)) {
782 [ + - ]: 64 : auto e = parse_Expr();
783 [ + - ]: 64 : Token tok = Token::CreateArtificial();
784 [ + - + + ]: 64 : if (accept(TK_As)) {
785 [ + - + - ]: 29 : tok = token();
786 [ + - - + ]: 29 : if (not expect(TK_IDENTIFIER))
787 [ # # # # ]: 0 : return recover<ErrorClause>(std::move(start), follow_set_SELECT_CLAUSE);
788 [ + - + + ]: 64 : } else if (token().type == TK_IDENTIFIER) {
789 [ + - + - ]: 1 : tok = token();
790 [ + - ]: 1 : consume();
791 : 1 : }
792 [ + - ]: 64 : select.emplace_back(std::move(e), std::move(tok));
793 [ - + ]: 64 : }
794 : :
795 [ + - ]: 632 : return std::make_unique<SelectClause>(std::move(start), std::move(select), std::move(select_all));
796 : 639 : }
797 : :
798 : 587 : std::unique_ptr<Clause> Parser::parse_FromClause()
799 : : {
800 : 587 : Token start = token();
801 : :
802 : : /* 'FROM' */
803 [ + - + + ]: 587 : if (not expect(TK_From)) {
804 [ + - ]: 2 : consume();
805 [ + - - + ]: 2 : return recover<ErrorClause>(std::move(start), follow_set_FROM_CLAUSE);
806 : : }
807 : :
808 : : /* table-or-select-statement { ',' table-or-select-statement } */
809 : 585 : std::vector<FromClause::from_type> from;
810 : 585 : do {
811 [ + - ]: 848 : Token alias = Token::CreateArtificial();
812 [ + - + + ]: 848 : if (accept(TK_LPAR)) {
813 [ + - ]: 30 : std::unique_ptr<Stmt> S = parse_SelectStmt();
814 [ + - - + ]: 30 : if (not expect(TK_RPAR))
815 [ # # # # ]: 0 : return recover<ErrorClause>(std::move(start), follow_set_FROM_CLAUSE);
816 [ + - ]: 30 : accept(TK_As);
817 [ + - + - ]: 30 : alias = token();
818 [ + - + + ]: 30 : if (not expect(TK_IDENTIFIER))
819 [ + - + - ]: 1 : return recover<ErrorClause>(std::move(start), follow_set_FROM_CLAUSE);
820 [ + - ]: 29 : from.emplace_back(std::move(S), std::move(alias));
821 [ + + ]: 30 : } else {
822 [ + - + - ]: 818 : Token table = token();
823 [ + - + + ]: 818 : if (not expect(TK_IDENTIFIER))
824 [ + - + - ]: 5 : return recover<ErrorClause>(std::move(start), follow_set_FROM_CLAUSE);
825 [ + - + + ]: 813 : if (accept(TK_As)) {
826 [ + - + - ]: 54 : alias = token();
827 [ + - + + ]: 54 : if (not expect(TK_IDENTIFIER))
828 [ + - + - ]: 2 : return recover<ErrorClause>(std::move(start), follow_set_FROM_CLAUSE);
829 [ + - + + ]: 811 : } else if (token().type == TK_IDENTIFIER) {
830 [ + - + - ]: 6 : alias = token();
831 [ + - ]: 6 : consume();
832 : 6 : }
833 [ + - ]: 811 : from.emplace_back(std::move(table), std::move(alias));
834 [ + + ]: 818 : }
835 [ + + + - : 848 : } while (accept(TK_COMMA));
+ + ]
836 : :
837 [ + - ]: 577 : return std::make_unique<FromClause>(std::move(start), std::move(from));
838 : 587 : }
839 : :
840 : 213 : std::unique_ptr<Clause> Parser::parse_WhereClause()
841 : : {
842 : 213 : Token start = token();
843 : :
844 : : /* 'WHERE' */
845 [ + - + + ]: 213 : if (not expect(TK_Where)) {
846 [ + - ]: 2 : consume();
847 [ + - - + ]: 2 : return recover<ErrorClause>(std::move(start), follow_set_WHERE_CLAUSE);
848 : : }
849 : :
850 : : /* expression */
851 [ + - ]: 211 : std::unique_ptr<Expr> where = parse_Expr();
852 : :
853 [ + - ]: 211 : return std::make_unique<WhereClause>(std::move(start), std::move(where));
854 : 213 : }
855 : :
856 : 84 : std::unique_ptr<Clause> Parser::parse_GroupByClause()
857 : : {
858 : 84 : Token start = token();
859 : :
860 : : /* 'GROUP' 'BY' */
861 [ + - + + ]: 84 : if (not expect(TK_Group)) {
862 [ + - ]: 3 : consume();
863 [ + - - + ]: 3 : return recover<ErrorClause>(std::move(start), follow_set_GROUP_BY_CLAUSE);
864 : : }
865 [ + - + + ]: 81 : if (not expect(TK_By))
866 [ + - - + ]: 1 : return recover<ErrorClause>(std::move(start), follow_set_GROUP_BY_CLAUSE);
867 : :
868 : : /* expr [ 'AS' identifier ] { ',' expr [ 'AS' identifier ] } */
869 : 80 : std::vector<GroupByClause::group_type> group_by;
870 : 80 : do {
871 [ + - ]: 84 : auto e = parse_Expr();
872 [ + - ]: 84 : Token tok = Token::CreateArtificial();
873 [ + - + + ]: 84 : if (accept(TK_As)) {
874 [ + - + - ]: 12 : tok = token();
875 [ + - + + ]: 12 : if (not expect(TK_IDENTIFIER))
876 [ + - + - ]: 2 : return recover<ErrorClause>(std::move(start), follow_set_GROUP_BY_CLAUSE);
877 [ + - + + ]: 82 : } else if (token().type == TK_IDENTIFIER) {
878 [ + - + - ]: 5 : tok = token();
879 [ + - ]: 5 : consume();
880 : 5 : }
881 [ + - ]: 82 : group_by.emplace_back(std::move(e), std::move(tok));
882 [ + + + - : 84 : } while (accept(TK_COMMA));
+ + ]
883 : :
884 [ + - ]: 78 : return std::make_unique<GroupByClause>(std::move(start), std::move(group_by));
885 : 84 : }
886 : :
887 : 51 : std::unique_ptr<Clause> Parser::parse_HavingClause()
888 : : {
889 : 51 : Token start = token();
890 : :
891 : : /* 'HAVING' */
892 [ + - + + ]: 51 : if (not expect(TK_Having)) {
893 [ + - ]: 2 : consume();
894 [ + - - + ]: 2 : return recover<ErrorClause>(std::move(start), follow_set_HAVING_CLAUSE);
895 : : }
896 : :
897 : : /* expression */
898 [ + - ]: 49 : std::unique_ptr<Expr> having = parse_Expr();
899 : :
900 [ + - ]: 49 : return std::make_unique<HavingClause>(std::move(start), std::move(having));
901 : 51 : }
902 : :
903 : 51 : std::unique_ptr<Clause> Parser::parse_OrderByClause()
904 : : {
905 : 51 : Token start = token();
906 : :
907 : : /* 'ORDER' 'BY' */
908 [ + - + + ]: 51 : if (not expect(TK_Order)) {
909 [ + - ]: 3 : consume();
910 [ + - - + ]: 3 : return recover<ErrorClause>(std::move(start), follow_set_ORDER_BY_CLAUSE);
911 : : }
912 [ + - + + ]: 48 : if (not expect(TK_By))
913 [ + - - + ]: 1 : return recover<ErrorClause>(std::move(start), follow_set_ORDER_BY_CLAUSE);
914 : :
915 : : /* expression [ 'ASC' | 'DESC' ] { ',' expression [ 'ASC' | 'DESC' ] } */
916 : 47 : std::vector<OrderByClause::order_type> order_by;
917 : 47 : do {
918 [ + - ]: 60 : auto e = parse_Expr();
919 [ + - + + ]: 60 : if (accept(TK_Descending)) {
920 [ + - ]: 13 : order_by.emplace_back(std::move(e), false);
921 : 13 : } else {
922 [ + - ]: 47 : accept(TK_Ascending);
923 [ + - ]: 47 : order_by.emplace_back(std::move(e), true);
924 : : }
925 [ + - + + ]: 60 : } while (accept(TK_COMMA));
926 : :
927 [ + - ]: 47 : return std::make_unique<OrderByClause>(std::move(start), std::move(order_by));
928 : 51 : }
929 : :
930 : 25 : std::unique_ptr<Clause> Parser::parse_LimitClause()
931 : : {
932 : 25 : Token start = token();
933 : :
934 : : /* 'LIMIT' integer-constant */
935 [ + - + + ]: 25 : if (not expect(TK_Limit)) {
936 [ + - ]: 4 : consume();
937 [ + - + - ]: 4 : return recover<ErrorClause>(std::move(start), follow_set_LIMIT_CLAUSE);
938 : : }
939 [ + - + - ]: 21 : Token limit = token();
940 [ + + + + : 21 : if (limit.type == TK_DEC_INT or limit.type == TK_OCT_INT or limit.type == TK_HEX_INT) {
+ + ]
941 [ + - ]: 15 : consume();
942 : 15 : } else {
943 [ + - + - : 6 : diag.e(limit.pos) << "expected integer limit, got " << limit.text << '\n';
+ - + - ]
944 [ + - + - ]: 6 : return recover<ErrorClause>(std::move(start), follow_set_LIMIT_CLAUSE);
945 : : }
946 : :
947 : : /* [ 'OFFSET' integer-constant ] */
948 [ + - ]: 15 : Token offset = Token::CreateArtificial();
949 [ + - + + ]: 15 : if (accept(TK_Offset)) {
950 [ + - + - ]: 7 : offset = token();
951 [ + + + + : 7 : if (offset.type == TK_DEC_INT or offset.type == TK_OCT_INT or offset.type == TK_HEX_INT) {
+ + ]
952 [ + - ]: 5 : consume();
953 : 5 : } else {
954 [ + - + - : 2 : diag.e(offset.pos) << "expected integer offset, got " << offset.text << '\n';
+ - + - ]
955 [ + - + - ]: 2 : return recover<ErrorClause>(std::move(start), follow_set_LIMIT_CLAUSE);
956 : : }
957 : 5 : }
958 : :
959 [ + - ]: 13 : return std::make_unique<LimitClause>(std::move(start), std::move(limit), std::move(offset));
960 : 25 : }
961 : :
962 : : /*======================================================================================================================
963 : : * Expressions
964 : : *====================================================================================================================*/
965 : :
966 : 5493 : std::unique_ptr<Expr> Parser::parse_Expr(const int precedence_lhs, std::unique_ptr<Expr> lhs)
967 : : {
968 : : /*
969 : : * primary-expression ::= designator | constant | '(' expression ')' | '(' select-statement ')' ;
970 : : * unary-expression ::= [ '+' | '-' | '~' ] postfix-expression ;
971 : : * logical-not-expression ::= 'NOT' logical-not-expression | comparative-expression ;
972 : : */
973 [ + + + + : 5493 : switch (token().type) {
+ + ]
974 : : /* primary-expression */
975 : : case TK_IDENTIFIER:
976 : 1473 : lhs = parse_designator(); // XXX For SUM(x), 'SUM' is parsed as designator; should be identifier.
977 : 1473 : break;
978 : : case TK_Null:
979 : : case TK_True:
980 : : case TK_False:
981 : : case TK_STRING_LITERAL:
982 : : case TK_DATE:
983 : : case TK_DATE_TIME:
984 : : case TK_OCT_INT:
985 : : case TK_DEC_INT:
986 : : case TK_HEX_INT:
987 : : case TK_DEC_FLOAT:
988 : : case TK_HEX_FLOAT:
989 [ + - ]: 3759 : lhs = std::make_unique<Constant>(consume());
990 : 3759 : break;
991 : : case TK_LPAR:
992 : 80 : consume();
993 [ + + ]: 80 : if (token().type == TK_Select)
994 [ - + ]: 47 : lhs = std::make_unique<QueryExpr>(token(), parse_SelectStmt());
995 : : else
996 [ - + ]: 33 : lhs = parse_Expr();
997 [ + + ]: 80 : if (not expect(TK_RPAR)) {
998 : 10 : recover(follow_set_PRIMARY_EXPRESSION);
999 : 10 : }
1000 : 80 : break;
1001 : :
1002 : : /* unary-expression */
1003 : : case TK_PLUS:
1004 : : case TK_MINUS:
1005 : : case TK_TILDE: {
1006 : 89 : auto tok = consume();
1007 [ + - ]: 89 : int p = get_precedence(TK_TILDE); // the precedence of TK_TILDE equals that of unary plus and minus
1008 [ + - + - ]: 89 : lhs = std::make_unique<UnaryExpr>(std::move(tok), parse_Expr(p));
1009 : : break;
1010 : 89 : }
1011 : :
1012 : : /* logical-NOT-expression */
1013 : : case TK_Not: {
1014 : 35 : auto tok = consume();
1015 [ + - ]: 35 : int p = get_precedence(tok.type);
1016 [ + - + - ]: 35 : lhs = std::make_unique<UnaryExpr>(std::move(tok), parse_Expr(p));
1017 : : break;
1018 : 35 : }
1019 : :
1020 : : default:
1021 : 57 : diag.e(token().pos) << "expected expression, got " << token().text << '\n';
1022 : 57 : recover(follow_set_EXPRESSION);
1023 : 57 : return std::make_unique<ErrorExpr>(token());
1024 : : }
1025 : :
1026 : : /* postfix-expression ::= postfix-expression '(' [ expression { ',' expression } ] ')' | primary-expression */
1027 [ + + ]: 5531 : while (token() == TK_LPAR) {
1028 : 95 : Token lpar = consume();
1029 : 95 : std::vector<std::unique_ptr<Expr>> args;
1030 [ + - + + ]: 95 : if (token().type == TK_ASTERISK) {
1031 [ + - ]: 2 : consume();
1032 [ + - + + ]: 95 : } else if (token().type != TK_RPAR) {
1033 : 88 : do
1034 [ + - + - : 185 : args.push_back(parse_Expr());
+ + ]
1035 [ + - ]: 97 : while (accept(TK_COMMA));
1036 : 88 : }
1037 [ + - + + ]: 95 : if (not expect(TK_RPAR)) {
1038 [ + - ]: 4 : recover(follow_set_POSTFIX_EXPRESSION);
1039 [ + - + - ]: 4 : lhs = std::make_unique<ErrorExpr>(token());
1040 : 4 : continue;
1041 : : }
1042 [ + - ]: 91 : lhs = std::make_unique<FnApplicationExpr>(std::move(lpar), std::move(lhs), std::move(args));
1043 [ + + ]: 95 : }
1044 : :
1045 : 6355 : for (;;) {
1046 : 6355 : Token op = token();
1047 [ + - + - ]: 6355 : int p = get_precedence(op);
1048 [ + + ]: 6355 : if (precedence_lhs > p) return lhs; // left operator has higher precedence_lhs
1049 [ + - ]: 919 : consume();
1050 : :
1051 [ + - ]: 919 : auto rhs = parse_Expr(p + 1);
1052 [ + - ]: 919 : lhs = std::make_unique<BinaryExpr>(std::move(op), std::move(lhs), std::move(rhs));
1053 [ + + ]: 6355 : }
1054 : 5493 : }
1055 : :
1056 : 1479 : std::unique_ptr<Expr> Parser::parse_designator()
1057 : : {
1058 : 1479 : Token lhs = token();
1059 [ + - + + ]: 1479 : if (not expect(TK_IDENTIFIER)) {
1060 [ + - ]: 1 : recover(follow_set_DESIGNATOR);
1061 [ + - ]: 1 : return std::make_unique<ErrorExpr>(std::move(lhs));
1062 : : }
1063 [ + - + - : 1478 : if (token() == TK_DOT) {
+ + ]
1064 [ + - ]: 821 : Token dot = consume();
1065 [ + - + - ]: 821 : Token rhs = token();
1066 [ + - + + ]: 821 : if (not expect(TK_IDENTIFIER)) {
1067 [ + - ]: 1 : recover(follow_set_DESIGNATOR);
1068 [ + - ]: 1 : return std::make_unique<ErrorExpr>(std::move(rhs));
1069 : : }
1070 [ + - ]: 820 : return std::make_unique<Designator>(std::move(dot), std::move(lhs), std::move(rhs)); // tbl.attr
1071 : 821 : }
1072 [ + - ]: 657 : return std::make_unique<Designator>(std::move(lhs)); // attr
1073 : 1479 : }
1074 : :
1075 : 4 : std::unique_ptr<Expr> Parser::expect_integer()
1076 : : {
1077 [ + + ]: 4 : if (is_integer(token().type)) {
1078 [ - + ]: 3 : return std::make_unique<Constant>(consume());
1079 : : } else {
1080 : 1 : diag.e(token().pos) << "expected integer constant, got " << token().text << '\n';
1081 : 1 : return std::make_unique<ErrorExpr>(token());
1082 : : }
1083 : 4 : }
1084 : :
1085 : : /*======================================================================================================================
1086 : : * Types
1087 : : *====================================================================================================================*/
1088 : :
1089 : 123 : const Type * Parser::parse_data_type()
1090 : : {
1091 [ + + + + : 123 : switch (token().type) {
+ + + +
+ ]
1092 : : default:
1093 : 2 : diag.e(token().pos) << "expected data-type, got " << token().text << '\n';
1094 : 2 : goto error_recovery;
1095 : :
1096 : : /* BOOL */
1097 : : case TK_Bool:
1098 : 23 : consume();
1099 [ + - ]: 23 : return Type::Get_Boolean(Type::TY_Scalar);
1100 : :
1101 : : /* 'CHAR' '(' decimal-constant ')' */
1102 : : case TK_Char:
1103 : : /* 'VARCHAR' '(' decimal-constant ')' */
1104 : : case TK_Varchar: {
1105 : 6 : bool is_varying = token().type == TK_Varchar;
1106 : 6 : consume();
1107 [ + - ]: 6 : if (not expect(TK_LPAR)) goto error_recovery;
1108 : 6 : Token tok = token();
1109 [ + - + + ]: 6 : if (not expect(TK_DEC_INT)) goto error_recovery;
1110 [ + - + - ]: 5 : if (not expect(TK_RPAR)) goto error_recovery;
1111 : 5 : errno = 0;
1112 [ + - ]: 5 : std::size_t length = strtoul(*(tok.text), nullptr, 10);
1113 [ + + ]: 5 : if (errno) {
1114 [ + - + - : 1 : diag.e(tok.pos) << tok.text << " is not a valid length\n";
+ - ]
1115 : 1 : goto error_recovery;
1116 : : }
1117 [ + + + - : 4 : return is_varying ? Type::Get_Varchar(Type::TY_Scalar, length) : Type::Get_Char(Type::TY_Scalar, length);
+ - + - ]
1118 [ + + ]: 6 : }
1119 : :
1120 : : /* DATE */
1121 : : case TK_Date:
1122 : 2 : consume();
1123 [ + - ]: 2 : return Type::Get_Date(Type::TY_Scalar);
1124 : :
1125 : : /* DATETIME */
1126 : : case TK_Datetime:
1127 : 2 : consume();
1128 [ + - ]: 2 : return Type::Get_Datetime(Type::TY_Scalar);
1129 : :
1130 : : /* 'INT' '(' decimal-constant ')' */
1131 : : case TK_Int: {
1132 : 63 : consume();
1133 [ + + ]: 63 : if (not expect(TK_LPAR)) goto error_recovery;
1134 : 62 : Token tok = token();
1135 [ + - + + ]: 62 : if (not expect(TK_DEC_INT)) goto error_recovery;
1136 [ + - + + ]: 58 : if (not expect(TK_RPAR)) goto error_recovery;
1137 : 56 : errno = 0;
1138 [ + - ]: 56 : std::size_t bytes = strtoul(*(tok.text), nullptr, 10);
1139 [ + + ]: 56 : if (errno) {
1140 [ + - + - : 1 : diag.e(tok.pos) << tok.text << " is not a valid size for an INT\n";
+ - ]
1141 : 1 : goto error_recovery;
1142 : : }
1143 [ + - + - ]: 55 : return Type::Get_Integer(Type::TY_Scalar, bytes);
1144 : 62 : }
1145 : :
1146 : : /* 'FLOAT' */
1147 : : case TK_Float:
1148 : 9 : consume();
1149 [ + - ]: 9 : return Type::Get_Float(Type::TY_Scalar);
1150 : :
1151 : : /* 'DOUBLE' */
1152 : : case TK_Double:
1153 : 4 : consume();
1154 [ + - ]: 4 : return Type::Get_Double(Type::TY_Scalar);
1155 : :
1156 : : /* 'DECIMAL' '(' decimal-constant [ ',' decimal-constant ] ')' */
1157 : : case TK_Decimal: {
1158 : 12 : consume();
1159 [ + - ]: 12 : if (not expect(TK_LPAR)) goto error_recovery;
1160 : 12 : Token precision = token();
1161 [ + - ]: 12 : Token scale = Token::CreateArtificial();
1162 [ + - + + ]: 12 : if (not expect(TK_DEC_INT)) goto error_recovery;
1163 [ + - + + ]: 10 : if (accept(TK_COMMA)) {
1164 [ + - + - ]: 9 : scale = token();
1165 [ + - + + ]: 9 : if (not expect(TK_DEC_INT)) goto error_recovery;
1166 : 6 : }
1167 [ + - + + ]: 7 : if (not expect(TK_RPAR)) goto error_recovery;
1168 : 6 : errno = 0;
1169 [ + - ]: 6 : std::size_t p = strtoul(*(precision.text), nullptr, 10);
1170 [ + + ]: 6 : if (errno) {
1171 [ + - + - : 1 : diag.e(precision.pos) << precision.text << " is not a valid precision for a DECIMAL\n";
+ - ]
1172 : 1 : goto error_recovery;
1173 : : }
1174 : 5 : errno = 0;
1175 [ + - + + : 5 : std::size_t s = scale.text.has_value() ? strtoul(*(scale.text), nullptr, 10) : 0;
+ - ]
1176 [ + + ]: 5 : if (errno) {
1177 [ + - + - : 1 : diag.e(scale.pos) << scale.text << " is not a valid scale for a DECIMAL\n";
+ - ]
1178 : 1 : goto error_recovery;
1179 : : }
1180 [ + - + - ]: 4 : return Type::Get_Decimal(Type::TY_Scalar, p, s);
1181 : 12 : }
1182 : : }
1183 : :
1184 : : error_recovery:
1185 : 20 : recover(follow_set_DATA_TYPE);
1186 [ + - ]: 20 : return Type::Get_Error();
1187 : 145 : }
|