Serenity Operating System
1/*
2 * Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
3 * Copyright (c) 2021, Mahmoud Mandour <ma.mandourr@gmail.com>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include "Parser.h"
9#include <AK/ScopeGuard.h>
10#include <AK/TypeCasts.h>
11
12namespace SQL::AST {
13
14Parser::Parser(Lexer lexer)
15 : m_parser_state(move(lexer))
16{
17}
18
19NonnullRefPtr<Statement> Parser::next_statement()
20{
21 auto terminate_statement = [this](auto statement) {
22 consume(TokenType::SemiColon);
23 return statement;
24 };
25
26 if (match(TokenType::With)) {
27 auto common_table_expression_list = parse_common_table_expression_list();
28 if (!common_table_expression_list)
29 return create_ast_node<ErrorStatement>();
30
31 return terminate_statement(parse_statement_with_expression_list(move(common_table_expression_list)));
32 }
33
34 return terminate_statement(parse_statement());
35}
36
37NonnullRefPtr<Statement> Parser::parse_statement()
38{
39 switch (m_parser_state.m_token.type()) {
40 case TokenType::Create:
41 consume();
42 if (match(TokenType::Schema))
43 return parse_create_schema_statement();
44 else
45 return parse_create_table_statement();
46 case TokenType::Alter:
47 return parse_alter_table_statement();
48 case TokenType::Drop:
49 return parse_drop_table_statement();
50 case TokenType::Describe:
51 return parse_describe_table_statement();
52 case TokenType::Insert:
53 return parse_insert_statement({});
54 case TokenType::Update:
55 return parse_update_statement({});
56 case TokenType::Delete:
57 return parse_delete_statement({});
58 case TokenType::Select:
59 return parse_select_statement({});
60 default:
61 expected("CREATE, ALTER, DROP, DESCRIBE, INSERT, UPDATE, DELETE, or SELECT"sv);
62 return create_ast_node<ErrorStatement>();
63 }
64}
65
66NonnullRefPtr<Statement> Parser::parse_statement_with_expression_list(RefPtr<CommonTableExpressionList> common_table_expression_list)
67{
68 switch (m_parser_state.m_token.type()) {
69 case TokenType::Insert:
70 return parse_insert_statement(move(common_table_expression_list));
71 case TokenType::Update:
72 return parse_update_statement(move(common_table_expression_list));
73 case TokenType::Delete:
74 return parse_delete_statement(move(common_table_expression_list));
75 case TokenType::Select:
76 return parse_select_statement(move(common_table_expression_list));
77 default:
78 expected("INSERT, UPDATE, DELETE, or SELECT"sv);
79 return create_ast_node<ErrorStatement>();
80 }
81}
82
83NonnullRefPtr<CreateSchema> Parser::parse_create_schema_statement()
84{
85 consume(TokenType::Schema);
86
87 bool is_error_if_exists = true;
88 if (consume_if(TokenType::If)) {
89 consume(TokenType::Not);
90 consume(TokenType::Exists);
91 is_error_if_exists = false;
92 }
93
94 DeprecatedString schema_name = consume(TokenType::Identifier).value();
95 return create_ast_node<CreateSchema>(move(schema_name), is_error_if_exists);
96}
97
98NonnullRefPtr<CreateTable> Parser::parse_create_table_statement()
99{
100 // https://sqlite.org/lang_createtable.html
101
102 bool is_temporary = false;
103 if (consume_if(TokenType::Temp) || consume_if(TokenType::Temporary))
104 is_temporary = true;
105
106 consume(TokenType::Table);
107
108 bool is_error_if_table_exists = true;
109 if (consume_if(TokenType::If)) {
110 consume(TokenType::Not);
111 consume(TokenType::Exists);
112 is_error_if_table_exists = false;
113 }
114
115 DeprecatedString schema_name;
116 DeprecatedString table_name;
117 parse_schema_and_table_name(schema_name, table_name);
118
119 if (consume_if(TokenType::As)) {
120 auto select_statement = parse_select_statement({});
121 return create_ast_node<CreateTable>(move(schema_name), move(table_name), move(select_statement), is_temporary, is_error_if_table_exists);
122 }
123
124 Vector<NonnullRefPtr<ColumnDefinition>> column_definitions;
125 parse_comma_separated_list(true, [&]() { column_definitions.append(parse_column_definition()); });
126
127 // FIXME: Parse "table-constraint".
128
129 return create_ast_node<CreateTable>(move(schema_name), move(table_name), move(column_definitions), is_temporary, is_error_if_table_exists);
130}
131
132NonnullRefPtr<AlterTable> Parser::parse_alter_table_statement()
133{
134 // https://sqlite.org/lang_altertable.html
135 consume(TokenType::Alter);
136 consume(TokenType::Table);
137
138 DeprecatedString schema_name;
139 DeprecatedString table_name;
140 parse_schema_and_table_name(schema_name, table_name);
141
142 if (consume_if(TokenType::Add)) {
143 consume_if(TokenType::Column); // COLUMN is optional.
144 auto column = parse_column_definition();
145 return create_ast_node<AddColumn>(move(schema_name), move(table_name), move(column));
146 }
147
148 if (consume_if(TokenType::Drop)) {
149 consume_if(TokenType::Column); // COLUMN is optional.
150 auto column = consume(TokenType::Identifier).value();
151 return create_ast_node<DropColumn>(move(schema_name), move(table_name), move(column));
152 }
153
154 consume(TokenType::Rename);
155
156 if (consume_if(TokenType::To)) {
157 auto new_table_name = consume(TokenType::Identifier).value();
158 return create_ast_node<RenameTable>(move(schema_name), move(table_name), move(new_table_name));
159 }
160
161 consume_if(TokenType::Column); // COLUMN is optional.
162 auto column_name = consume(TokenType::Identifier).value();
163 consume(TokenType::To);
164 auto new_column_name = consume(TokenType::Identifier).value();
165 return create_ast_node<RenameColumn>(move(schema_name), move(table_name), move(column_name), move(new_column_name));
166}
167
168NonnullRefPtr<DropTable> Parser::parse_drop_table_statement()
169{
170 // https://sqlite.org/lang_droptable.html
171 consume(TokenType::Drop);
172 consume(TokenType::Table);
173
174 bool is_error_if_table_does_not_exist = true;
175 if (consume_if(TokenType::If)) {
176 consume(TokenType::Exists);
177 is_error_if_table_does_not_exist = false;
178 }
179
180 DeprecatedString schema_name;
181 DeprecatedString table_name;
182 parse_schema_and_table_name(schema_name, table_name);
183
184 return create_ast_node<DropTable>(move(schema_name), move(table_name), is_error_if_table_does_not_exist);
185}
186
187NonnullRefPtr<DescribeTable> Parser::parse_describe_table_statement()
188{
189 consume(TokenType::Describe);
190 consume(TokenType::Table);
191
192 auto table_name = parse_qualified_table_name();
193
194 return create_ast_node<DescribeTable>(move(table_name));
195}
196
197NonnullRefPtr<Insert> Parser::parse_insert_statement(RefPtr<CommonTableExpressionList> common_table_expression_list)
198{
199 // https://sqlite.org/lang_insert.html
200 consume(TokenType::Insert);
201 auto conflict_resolution = parse_conflict_resolution();
202 consume(TokenType::Into);
203
204 DeprecatedString schema_name;
205 DeprecatedString table_name;
206 parse_schema_and_table_name(schema_name, table_name);
207
208 DeprecatedString alias;
209 if (consume_if(TokenType::As))
210 alias = consume(TokenType::Identifier).value();
211
212 Vector<DeprecatedString> column_names;
213 if (match(TokenType::ParenOpen))
214 parse_comma_separated_list(true, [&]() { column_names.append(consume(TokenType::Identifier).value()); });
215
216 Vector<NonnullRefPtr<ChainedExpression>> chained_expressions;
217 RefPtr<Select> select_statement;
218
219 if (consume_if(TokenType::Values)) {
220 parse_comma_separated_list(false, [&]() {
221 if (auto chained_expression = parse_chained_expression()) {
222 auto chained_expr = dynamic_cast<ChainedExpression*>(chained_expression.ptr());
223 if ((column_names.size() > 0) && (chained_expr->expressions().size() != column_names.size())) {
224 syntax_error("Number of expressions does not match number of columns");
225 } else {
226 chained_expressions.append(static_ptr_cast<ChainedExpression>(chained_expression.release_nonnull()));
227 }
228 } else {
229 expected("Chained expression"sv);
230 }
231 });
232 } else if (match(TokenType::Select)) {
233 select_statement = parse_select_statement({});
234 } else {
235 consume(TokenType::Default);
236 consume(TokenType::Values);
237 }
238
239 RefPtr<ReturningClause> returning_clause;
240 if (match(TokenType::Returning))
241 returning_clause = parse_returning_clause();
242
243 // FIXME: Parse 'upsert-clause'.
244
245 if (!chained_expressions.is_empty())
246 return create_ast_node<Insert>(move(common_table_expression_list), conflict_resolution, move(schema_name), move(table_name), move(alias), move(column_names), move(chained_expressions));
247 if (!select_statement.is_null())
248 return create_ast_node<Insert>(move(common_table_expression_list), conflict_resolution, move(schema_name), move(table_name), move(alias), move(column_names), move(select_statement));
249
250 return create_ast_node<Insert>(move(common_table_expression_list), conflict_resolution, move(schema_name), move(table_name), move(alias), move(column_names));
251}
252
253NonnullRefPtr<Update> Parser::parse_update_statement(RefPtr<CommonTableExpressionList> common_table_expression_list)
254{
255 // https://sqlite.org/lang_update.html
256 consume(TokenType::Update);
257 auto conflict_resolution = parse_conflict_resolution();
258 auto qualified_table_name = parse_qualified_table_name();
259 consume(TokenType::Set);
260
261 Vector<Update::UpdateColumns> update_columns;
262 parse_comma_separated_list(false, [&]() {
263 Vector<DeprecatedString> column_names;
264 if (match(TokenType::ParenOpen)) {
265 parse_comma_separated_list(true, [&]() { column_names.append(consume(TokenType::Identifier).value()); });
266 } else {
267 column_names.append(consume(TokenType::Identifier).value());
268 }
269
270 consume(TokenType::Equals);
271 update_columns.append({ move(column_names), parse_expression() });
272 });
273
274 Vector<NonnullRefPtr<TableOrSubquery>> table_or_subquery_list;
275 if (consume_if(TokenType::From)) {
276 // FIXME: Parse join-clause.
277 parse_comma_separated_list(false, [&]() { table_or_subquery_list.append(parse_table_or_subquery()); });
278 }
279
280 RefPtr<Expression> where_clause;
281 if (consume_if(TokenType::Where))
282 where_clause = parse_expression();
283
284 RefPtr<ReturningClause> returning_clause;
285 if (match(TokenType::Returning))
286 returning_clause = parse_returning_clause();
287
288 return create_ast_node<Update>(move(common_table_expression_list), conflict_resolution, move(qualified_table_name), move(update_columns), move(table_or_subquery_list), move(where_clause), move(returning_clause));
289}
290
291NonnullRefPtr<Delete> Parser::parse_delete_statement(RefPtr<CommonTableExpressionList> common_table_expression_list)
292{
293 // https://sqlite.org/lang_delete.html
294 consume(TokenType::Delete);
295 consume(TokenType::From);
296 auto qualified_table_name = parse_qualified_table_name();
297
298 RefPtr<Expression> where_clause;
299 if (consume_if(TokenType::Where))
300 where_clause = parse_expression();
301
302 RefPtr<ReturningClause> returning_clause;
303 if (match(TokenType::Returning))
304 returning_clause = parse_returning_clause();
305
306 return create_ast_node<Delete>(move(common_table_expression_list), move(qualified_table_name), move(where_clause), move(returning_clause));
307}
308
309NonnullRefPtr<Select> Parser::parse_select_statement(RefPtr<CommonTableExpressionList> common_table_expression_list)
310{
311 // https://sqlite.org/lang_select.html
312 consume(TokenType::Select);
313
314 bool select_all = !consume_if(TokenType::Distinct);
315 consume_if(TokenType::All); // ALL is the default, so ignore it if specified.
316
317 Vector<NonnullRefPtr<ResultColumn>> result_column_list;
318 parse_comma_separated_list(false, [&]() { result_column_list.append(parse_result_column()); });
319
320 Vector<NonnullRefPtr<TableOrSubquery>> table_or_subquery_list;
321 if (consume_if(TokenType::From)) {
322 // FIXME: Parse join-clause.
323 parse_comma_separated_list(false, [&]() { table_or_subquery_list.append(parse_table_or_subquery()); });
324 }
325
326 RefPtr<Expression> where_clause;
327 if (consume_if(TokenType::Where))
328 where_clause = parse_expression();
329
330 RefPtr<GroupByClause> group_by_clause;
331 if (consume_if(TokenType::Group)) {
332 consume(TokenType::By);
333
334 Vector<NonnullRefPtr<Expression>> group_by_list;
335 parse_comma_separated_list(false, [&]() { group_by_list.append(parse_expression()); });
336
337 if (!group_by_list.is_empty()) {
338 RefPtr<Expression> having_clause;
339 if (consume_if(TokenType::Having))
340 having_clause = parse_expression();
341
342 group_by_clause = create_ast_node<GroupByClause>(move(group_by_list), move(having_clause));
343 }
344 }
345
346 // FIXME: Parse 'WINDOW window-name AS window-defn'.
347 // FIXME: Parse 'compound-operator'.
348
349 Vector<NonnullRefPtr<OrderingTerm>> ordering_term_list;
350 if (consume_if(TokenType::Order)) {
351 consume(TokenType::By);
352 parse_comma_separated_list(false, [&]() { ordering_term_list.append(parse_ordering_term()); });
353 }
354
355 RefPtr<LimitClause> limit_clause;
356 if (consume_if(TokenType::Limit)) {
357 auto limit_expression = parse_expression();
358
359 RefPtr<Expression> offset_expression;
360 if (consume_if(TokenType::Offset)) {
361 offset_expression = parse_expression();
362 } else if (consume_if(TokenType::Comma)) {
363 // Note: The limit clause may instead be defined as "offset-expression, limit-expression", effectively reversing the
364 // order of the expressions. SQLite notes "this is counter-intuitive" and "to avoid confusion, programmers are strongly
365 // encouraged to ... avoid using a LIMIT clause with a comma-separated offset."
366 syntax_error("LIMIT clauses of the form 'LIMIT <expr>, <expr>' are not supported");
367 }
368
369 limit_clause = create_ast_node<LimitClause>(move(limit_expression), move(offset_expression));
370 }
371
372 return create_ast_node<Select>(move(common_table_expression_list), select_all, move(result_column_list), move(table_or_subquery_list), move(where_clause), move(group_by_clause), move(ordering_term_list), move(limit_clause));
373}
374
375RefPtr<CommonTableExpressionList> Parser::parse_common_table_expression_list()
376{
377 consume(TokenType::With);
378 bool recursive = consume_if(TokenType::Recursive);
379
380 Vector<NonnullRefPtr<CommonTableExpression>> common_table_expression;
381 parse_comma_separated_list(false, [&]() { common_table_expression.append(parse_common_table_expression()); });
382
383 if (common_table_expression.is_empty()) {
384 expected("Common table expression list"sv);
385 return {};
386 }
387
388 return create_ast_node<CommonTableExpressionList>(recursive, move(common_table_expression));
389}
390
391NonnullRefPtr<Expression> Parser::parse_expression()
392{
393 if (++m_parser_state.m_current_expression_depth > Limits::maximum_expression_tree_depth) {
394 syntax_error(DeprecatedString::formatted("Exceeded maximum expression tree depth of {}", Limits::maximum_expression_tree_depth));
395 return create_ast_node<ErrorExpression>();
396 }
397
398 // https://sqlite.org/lang_expr.html
399 auto expression = parse_primary_expression();
400
401 if (match_secondary_expression())
402 expression = parse_secondary_expression(move(expression));
403
404 // FIXME: Parse 'function-name'.
405 // FIXME: Parse 'raise-function'.
406
407 --m_parser_state.m_current_expression_depth;
408 return expression;
409}
410
411NonnullRefPtr<Expression> Parser::parse_primary_expression()
412{
413 if (auto expression = parse_literal_value_expression())
414 return expression.release_nonnull();
415
416 if (auto expression = parse_bind_parameter_expression())
417 return expression.release_nonnull();
418
419 if (auto expression = parse_column_name_expression())
420 return expression.release_nonnull();
421
422 if (auto expression = parse_unary_operator_expression())
423 return expression.release_nonnull();
424
425 if (auto expression = parse_chained_expression())
426 return expression.release_nonnull();
427
428 if (auto expression = parse_cast_expression())
429 return expression.release_nonnull();
430
431 if (auto expression = parse_case_expression())
432 return expression.release_nonnull();
433
434 if (auto expression = parse_exists_expression(false))
435 return expression.release_nonnull();
436
437 expected("Primary Expression"sv);
438 consume();
439
440 return create_ast_node<ErrorExpression>();
441}
442
443NonnullRefPtr<Expression> Parser::parse_secondary_expression(NonnullRefPtr<Expression> primary)
444{
445 if (auto expression = parse_binary_operator_expression(primary))
446 return expression.release_nonnull();
447
448 if (auto expression = parse_collate_expression(primary))
449 return expression.release_nonnull();
450
451 if (auto expression = parse_is_expression(primary))
452 return expression.release_nonnull();
453
454 bool invert_expression = false;
455 if (consume_if(TokenType::Not))
456 invert_expression = true;
457
458 if (auto expression = parse_match_expression(primary, invert_expression))
459 return expression.release_nonnull();
460
461 if (auto expression = parse_null_expression(primary, invert_expression))
462 return expression.release_nonnull();
463
464 if (auto expression = parse_between_expression(primary, invert_expression))
465 return expression.release_nonnull();
466
467 if (auto expression = parse_in_expression(primary, invert_expression))
468 return expression.release_nonnull();
469
470 expected("Secondary Expression"sv);
471 consume();
472
473 return create_ast_node<ErrorExpression>();
474}
475
476bool Parser::match_secondary_expression() const
477{
478 return match(TokenType::Not)
479 || match(TokenType::DoublePipe)
480 || match(TokenType::Asterisk)
481 || match(TokenType::Divide)
482 || match(TokenType::Modulus)
483 || match(TokenType::Plus)
484 || match(TokenType::Minus)
485 || match(TokenType::ShiftLeft)
486 || match(TokenType::ShiftRight)
487 || match(TokenType::Ampersand)
488 || match(TokenType::Pipe)
489 || match(TokenType::LessThan)
490 || match(TokenType::LessThanEquals)
491 || match(TokenType::GreaterThan)
492 || match(TokenType::GreaterThanEquals)
493 || match(TokenType::Equals)
494 || match(TokenType::EqualsEquals)
495 || match(TokenType::NotEquals1)
496 || match(TokenType::NotEquals2)
497 || match(TokenType::And)
498 || match(TokenType::Or)
499 || match(TokenType::Collate)
500 || match(TokenType::Is)
501 || match(TokenType::Like)
502 || match(TokenType::Glob)
503 || match(TokenType::Match)
504 || match(TokenType::Regexp)
505 || match(TokenType::Isnull)
506 || match(TokenType::Notnull)
507 || match(TokenType::Between)
508 || match(TokenType::In);
509}
510
511RefPtr<Expression> Parser::parse_literal_value_expression()
512{
513 if (match(TokenType::NumericLiteral)) {
514 auto value = consume().double_value();
515 return create_ast_node<NumericLiteral>(value);
516 }
517 if (match(TokenType::StringLiteral)) {
518 // TODO: Should the surrounding ' ' be removed here?
519 auto value = consume().value();
520 return create_ast_node<StringLiteral>(value);
521 }
522 if (match(TokenType::BlobLiteral)) {
523 // TODO: Should the surrounding x' ' be removed here?
524 auto value = consume().value();
525 return create_ast_node<BlobLiteral>(value);
526 }
527 if (consume_if(TokenType::True))
528 return create_ast_node<BooleanLiteral>(true);
529 if (consume_if(TokenType::False))
530 return create_ast_node<BooleanLiteral>(false);
531 if (consume_if(TokenType::Null))
532 return create_ast_node<NullLiteral>();
533
534 return {};
535}
536
537// https://sqlite.org/lang_expr.html#varparam
538RefPtr<Expression> Parser::parse_bind_parameter_expression()
539{
540 // FIXME: Support ?NNN, :AAAA, @AAAA, and $AAAA forms.
541 if (consume_if(TokenType::Placeholder)) {
542 auto parameter = m_parser_state.m_bound_parameters;
543 if (++m_parser_state.m_bound_parameters > Limits::maximum_bound_parameters)
544 syntax_error(DeprecatedString::formatted("Exceeded maximum number of bound parameters {}", Limits::maximum_bound_parameters));
545
546 return create_ast_node<Placeholder>(parameter);
547 }
548
549 return {};
550}
551
552RefPtr<Expression> Parser::parse_column_name_expression(DeprecatedString with_parsed_identifier, bool with_parsed_period)
553{
554 if (with_parsed_identifier.is_null() && !match(TokenType::Identifier))
555 return {};
556
557 DeprecatedString first_identifier;
558 if (with_parsed_identifier.is_null())
559 first_identifier = consume(TokenType::Identifier).value();
560 else
561 first_identifier = move(with_parsed_identifier);
562
563 DeprecatedString schema_name;
564 DeprecatedString table_name;
565 DeprecatedString column_name;
566
567 if (with_parsed_period || consume_if(TokenType::Period)) {
568 DeprecatedString second_identifier = consume(TokenType::Identifier).value();
569
570 if (consume_if(TokenType::Period)) {
571 schema_name = move(first_identifier);
572 table_name = move(second_identifier);
573 column_name = consume(TokenType::Identifier).value();
574 } else {
575 table_name = move(first_identifier);
576 column_name = move(second_identifier);
577 }
578 } else {
579 column_name = move(first_identifier);
580 }
581
582 return create_ast_node<ColumnNameExpression>(move(schema_name), move(table_name), move(column_name));
583}
584
585RefPtr<Expression> Parser::parse_unary_operator_expression()
586{
587 if (consume_if(TokenType::Minus))
588 return create_ast_node<UnaryOperatorExpression>(UnaryOperator::Minus, parse_expression());
589
590 if (consume_if(TokenType::Plus))
591 return create_ast_node<UnaryOperatorExpression>(UnaryOperator::Plus, parse_expression());
592
593 if (consume_if(TokenType::Tilde))
594 return create_ast_node<UnaryOperatorExpression>(UnaryOperator::BitwiseNot, parse_expression());
595
596 if (consume_if(TokenType::Not)) {
597 if (match(TokenType::Exists))
598 return parse_exists_expression(true);
599 else
600 return create_ast_node<UnaryOperatorExpression>(UnaryOperator::Not, parse_expression());
601 }
602
603 return {};
604}
605
606RefPtr<Expression> Parser::parse_binary_operator_expression(NonnullRefPtr<Expression> lhs)
607{
608 if (consume_if(TokenType::DoublePipe))
609 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::Concatenate, move(lhs), parse_expression());
610
611 if (consume_if(TokenType::Asterisk))
612 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::Multiplication, move(lhs), parse_expression());
613
614 if (consume_if(TokenType::Divide))
615 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::Division, move(lhs), parse_expression());
616
617 if (consume_if(TokenType::Modulus))
618 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::Modulo, move(lhs), parse_expression());
619
620 if (consume_if(TokenType::Plus))
621 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::Plus, move(lhs), parse_expression());
622
623 if (consume_if(TokenType::Minus))
624 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::Minus, move(lhs), parse_expression());
625
626 if (consume_if(TokenType::ShiftLeft))
627 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::ShiftLeft, move(lhs), parse_expression());
628
629 if (consume_if(TokenType::ShiftRight))
630 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::ShiftRight, move(lhs), parse_expression());
631
632 if (consume_if(TokenType::Ampersand))
633 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::BitwiseAnd, move(lhs), parse_expression());
634
635 if (consume_if(TokenType::Pipe))
636 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::BitwiseOr, move(lhs), parse_expression());
637
638 if (consume_if(TokenType::LessThan))
639 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::LessThan, move(lhs), parse_expression());
640
641 if (consume_if(TokenType::LessThanEquals))
642 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::LessThanEquals, move(lhs), parse_expression());
643
644 if (consume_if(TokenType::GreaterThan))
645 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::GreaterThan, move(lhs), parse_expression());
646
647 if (consume_if(TokenType::GreaterThanEquals))
648 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::GreaterThanEquals, move(lhs), parse_expression());
649
650 if (consume_if(TokenType::Equals) || consume_if(TokenType::EqualsEquals))
651 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::Equals, move(lhs), parse_expression());
652
653 if (consume_if(TokenType::NotEquals1) || consume_if(TokenType::NotEquals2))
654 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::NotEquals, move(lhs), parse_expression());
655
656 if (consume_if(TokenType::And))
657 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::And, move(lhs), parse_expression());
658
659 if (consume_if(TokenType::Or))
660 return create_ast_node<BinaryOperatorExpression>(BinaryOperator::Or, move(lhs), parse_expression());
661
662 return {};
663}
664
665RefPtr<Expression> Parser::parse_chained_expression()
666{
667 if (!consume_if(TokenType::ParenOpen))
668 return {};
669
670 if (match(TokenType::Select))
671 return parse_exists_expression(false, TokenType::Select);
672
673 Vector<NonnullRefPtr<Expression>> expressions;
674 parse_comma_separated_list(false, [&]() { expressions.append(parse_expression()); });
675 consume(TokenType::ParenClose);
676
677 return create_ast_node<ChainedExpression>(move(expressions));
678}
679
680RefPtr<Expression> Parser::parse_cast_expression()
681{
682 if (!match(TokenType::Cast))
683 return {};
684
685 consume(TokenType::Cast);
686 consume(TokenType::ParenOpen);
687 auto expression = parse_expression();
688 consume(TokenType::As);
689 auto type_name = parse_type_name();
690 consume(TokenType::ParenClose);
691
692 return create_ast_node<CastExpression>(move(expression), move(type_name));
693}
694
695RefPtr<Expression> Parser::parse_case_expression()
696{
697 if (!match(TokenType::Case))
698 return {};
699
700 consume();
701
702 RefPtr<Expression> case_expression;
703 if (!match(TokenType::When)) {
704 case_expression = parse_expression();
705 }
706
707 Vector<CaseExpression::WhenThenClause> when_then_clauses;
708
709 do {
710 consume(TokenType::When);
711 auto when = parse_expression();
712 consume(TokenType::Then);
713 auto then = parse_expression();
714
715 when_then_clauses.append({ move(when), move(then) });
716
717 if (!match(TokenType::When))
718 break;
719 } while (!match(TokenType::Eof));
720
721 RefPtr<Expression> else_expression;
722 if (consume_if(TokenType::Else))
723 else_expression = parse_expression();
724
725 consume(TokenType::End);
726 return create_ast_node<CaseExpression>(move(case_expression), move(when_then_clauses), move(else_expression));
727}
728
729RefPtr<Expression> Parser::parse_exists_expression(bool invert_expression, TokenType opening_token)
730{
731 VERIFY((opening_token == TokenType::Exists) || (opening_token == TokenType::Select));
732
733 if ((opening_token == TokenType::Exists) && !consume_if(TokenType::Exists))
734 return {};
735
736 if (opening_token == TokenType::Exists)
737 consume(TokenType::ParenOpen);
738 auto select_statement = parse_select_statement({});
739 consume(TokenType::ParenClose);
740
741 return create_ast_node<ExistsExpression>(move(select_statement), invert_expression);
742}
743
744RefPtr<Expression> Parser::parse_collate_expression(NonnullRefPtr<Expression> expression)
745{
746 if (!match(TokenType::Collate))
747 return {};
748
749 consume();
750 DeprecatedString collation_name = consume(TokenType::Identifier).value();
751
752 return create_ast_node<CollateExpression>(move(expression), move(collation_name));
753}
754
755RefPtr<Expression> Parser::parse_is_expression(NonnullRefPtr<Expression> expression)
756{
757 if (!match(TokenType::Is))
758 return {};
759
760 consume();
761
762 bool invert_expression = false;
763 if (match(TokenType::Not)) {
764 consume();
765 invert_expression = true;
766 }
767
768 auto rhs = parse_expression();
769 return create_ast_node<IsExpression>(move(expression), move(rhs), invert_expression);
770}
771
772RefPtr<Expression> Parser::parse_match_expression(NonnullRefPtr<Expression> lhs, bool invert_expression)
773{
774 auto parse_escape = [this]() {
775 RefPtr<Expression> escape;
776 if (consume_if(TokenType::Escape)) {
777 escape = parse_expression();
778 }
779 return escape;
780 };
781
782 if (consume_if(TokenType::Like)) {
783 NonnullRefPtr<Expression> rhs = parse_expression();
784 RefPtr<Expression> escape = parse_escape();
785 return create_ast_node<MatchExpression>(MatchOperator::Like, move(lhs), move(rhs), move(escape), invert_expression);
786 }
787
788 if (consume_if(TokenType::Glob)) {
789 NonnullRefPtr<Expression> rhs = parse_expression();
790 RefPtr<Expression> escape = parse_escape();
791 return create_ast_node<MatchExpression>(MatchOperator::Glob, move(lhs), move(rhs), move(escape), invert_expression);
792 }
793
794 if (consume_if(TokenType::Match)) {
795 NonnullRefPtr<Expression> rhs = parse_expression();
796 RefPtr<Expression> escape = parse_escape();
797 return create_ast_node<MatchExpression>(MatchOperator::Match, move(lhs), move(rhs), move(escape), invert_expression);
798 }
799
800 if (consume_if(TokenType::Regexp)) {
801 NonnullRefPtr<Expression> rhs = parse_expression();
802 RefPtr<Expression> escape = parse_escape();
803 return create_ast_node<MatchExpression>(MatchOperator::Regexp, move(lhs), move(rhs), move(escape), invert_expression);
804 }
805
806 return {};
807}
808
809RefPtr<Expression> Parser::parse_null_expression(NonnullRefPtr<Expression> expression, bool invert_expression)
810{
811 if (!match(TokenType::Isnull) && !match(TokenType::Notnull) && !(invert_expression && match(TokenType::Null)))
812 return {};
813
814 auto type = consume().type();
815 invert_expression |= (type == TokenType::Notnull);
816
817 return create_ast_node<NullExpression>(move(expression), invert_expression);
818}
819
820RefPtr<Expression> Parser::parse_between_expression(NonnullRefPtr<Expression> expression, bool invert_expression)
821{
822 if (!match(TokenType::Between))
823 return {};
824
825 consume();
826
827 auto nested = parse_expression();
828 if (!is<BinaryOperatorExpression>(*nested)) {
829 expected("Binary Expression"sv);
830 return create_ast_node<ErrorExpression>();
831 }
832
833 auto const& binary_expression = static_cast<BinaryOperatorExpression const&>(*nested);
834 if (binary_expression.type() != BinaryOperator::And) {
835 expected("AND Expression"sv);
836 return create_ast_node<ErrorExpression>();
837 }
838
839 return create_ast_node<BetweenExpression>(move(expression), binary_expression.lhs(), binary_expression.rhs(), invert_expression);
840}
841
842RefPtr<Expression> Parser::parse_in_expression(NonnullRefPtr<Expression> expression, bool invert_expression)
843{
844 if (!match(TokenType::In))
845 return {};
846
847 consume();
848
849 if (consume_if(TokenType::ParenOpen)) {
850 if (match(TokenType::Select)) {
851 auto select_statement = parse_select_statement({});
852 return create_ast_node<InSelectionExpression>(move(expression), move(select_statement), invert_expression);
853 }
854
855 // FIXME: Consolidate this with parse_chained_expression(). That method consumes the opening paren as
856 // well, and also requires at least one expression (whereas this allows for an empty chain).
857 Vector<NonnullRefPtr<Expression>> expressions;
858 if (!match(TokenType::ParenClose))
859 parse_comma_separated_list(false, [&]() { expressions.append(parse_expression()); });
860
861 consume(TokenType::ParenClose);
862
863 auto chain = create_ast_node<ChainedExpression>(move(expressions));
864 return create_ast_node<InChainedExpression>(move(expression), move(chain), invert_expression);
865 }
866
867 DeprecatedString schema_name;
868 DeprecatedString table_name;
869 parse_schema_and_table_name(schema_name, table_name);
870
871 if (match(TokenType::ParenOpen)) {
872 // FIXME: Parse "table-function".
873 return {};
874 }
875
876 return create_ast_node<InTableExpression>(move(expression), move(schema_name), move(table_name), invert_expression);
877}
878
879NonnullRefPtr<ColumnDefinition> Parser::parse_column_definition()
880{
881 // https://sqlite.org/syntax/column-def.html
882 auto name = consume(TokenType::Identifier).value();
883
884 auto type_name = match(TokenType::Identifier)
885 ? parse_type_name()
886 // https://www.sqlite.org/datatype3.html: If no type is specified then the column has affinity BLOB.
887 : create_ast_node<TypeName>("BLOB", Vector<NonnullRefPtr<SignedNumber>> {});
888
889 // FIXME: Parse "column-constraint".
890
891 return create_ast_node<ColumnDefinition>(move(name), move(type_name));
892}
893
894NonnullRefPtr<TypeName> Parser::parse_type_name()
895{
896 // https: //sqlite.org/syntax/type-name.html
897 auto name = consume(TokenType::Identifier).value();
898 Vector<NonnullRefPtr<SignedNumber>> signed_numbers;
899
900 if (consume_if(TokenType::ParenOpen)) {
901 signed_numbers.append(parse_signed_number());
902
903 if (consume_if(TokenType::Comma))
904 signed_numbers.append(parse_signed_number());
905
906 consume(TokenType::ParenClose);
907 }
908
909 return create_ast_node<TypeName>(move(name), move(signed_numbers));
910}
911
912NonnullRefPtr<SignedNumber> Parser::parse_signed_number()
913{
914 // https://sqlite.org/syntax/signed-number.html
915 bool is_positive = true;
916
917 if (consume_if(TokenType::Plus))
918 is_positive = true;
919 else if (consume_if(TokenType::Minus))
920 is_positive = false;
921
922 if (match(TokenType::NumericLiteral)) {
923 auto number = consume(TokenType::NumericLiteral).double_value();
924 return create_ast_node<SignedNumber>(is_positive ? number : (number * -1));
925 }
926
927 expected("NumericLiteral"sv);
928 return create_ast_node<SignedNumber>(0);
929}
930
931NonnullRefPtr<CommonTableExpression> Parser::parse_common_table_expression()
932{
933 // https://sqlite.org/syntax/common-table-expression.html
934 auto table_name = consume(TokenType::Identifier).value();
935
936 Vector<DeprecatedString> column_names;
937 if (match(TokenType::ParenOpen))
938 parse_comma_separated_list(true, [&]() { column_names.append(consume(TokenType::Identifier).value()); });
939
940 consume(TokenType::As);
941 consume(TokenType::ParenOpen);
942 auto select_statement = parse_select_statement({});
943 consume(TokenType::ParenClose);
944
945 return create_ast_node<CommonTableExpression>(move(table_name), move(column_names), move(select_statement));
946}
947
948NonnullRefPtr<QualifiedTableName> Parser::parse_qualified_table_name()
949{
950 // https://sqlite.org/syntax/qualified-table-name.html
951 DeprecatedString schema_name;
952 DeprecatedString table_name;
953 parse_schema_and_table_name(schema_name, table_name);
954
955 DeprecatedString alias;
956 if (consume_if(TokenType::As))
957 alias = consume(TokenType::Identifier).value();
958
959 // Note: The qualified-table-name spec may include an "INDEXED BY index-name" or "NOT INDEXED" clause. This is a SQLite extension
960 // "designed to help detect undesirable query plan changes during regression testing", and "application developers are admonished
961 // to omit all use of INDEXED BY during application design, implementation, testing, and tuning". Our implementation purposefully
962 // omits parsing INDEXED BY for now until there is good reason to add support.
963
964 return create_ast_node<QualifiedTableName>(move(schema_name), move(table_name), move(alias));
965}
966
967NonnullRefPtr<ReturningClause> Parser::parse_returning_clause()
968{
969 // https://sqlite.org/syntax/returning-clause.html
970 consume(TokenType::Returning);
971
972 if (consume_if(TokenType::Asterisk))
973 return create_ast_node<ReturningClause>();
974
975 Vector<ReturningClause::ColumnClause> columns;
976 parse_comma_separated_list(false, [&]() {
977 auto expression = parse_expression();
978
979 DeprecatedString column_alias;
980 if (consume_if(TokenType::As) || match(TokenType::Identifier))
981 column_alias = consume(TokenType::Identifier).value();
982
983 columns.append({ move(expression), move(column_alias) });
984 });
985
986 return create_ast_node<ReturningClause>(move(columns));
987}
988
989NonnullRefPtr<ResultColumn> Parser::parse_result_column()
990{
991 // https://sqlite.org/syntax/result-column.html
992 if (consume_if(TokenType::Asterisk))
993 return create_ast_node<ResultColumn>();
994
995 // If we match an identifier now, we don't know whether it is a table-name of the form "table-name.*", or if it is the start of a
996 // column-name-expression, until we try to parse the asterisk. So if we consume an identifier and a period, but don't find an
997 // asterisk, hold onto that information to form a column-name-expression later.
998 DeprecatedString table_name;
999 bool parsed_period = false;
1000
1001 if (match(TokenType::Identifier)) {
1002 table_name = consume().value();
1003 parsed_period = consume_if(TokenType::Period);
1004 if (parsed_period && consume_if(TokenType::Asterisk))
1005 return create_ast_node<ResultColumn>(move(table_name));
1006 }
1007
1008 auto expression = table_name.is_null()
1009 ? parse_expression()
1010 : static_cast<NonnullRefPtr<Expression>>(*parse_column_name_expression(move(table_name), parsed_period));
1011
1012 DeprecatedString column_alias;
1013 if (consume_if(TokenType::As) || match(TokenType::Identifier))
1014 column_alias = consume(TokenType::Identifier).value();
1015
1016 return create_ast_node<ResultColumn>(move(expression), move(column_alias));
1017}
1018
1019NonnullRefPtr<TableOrSubquery> Parser::parse_table_or_subquery()
1020{
1021 if (++m_parser_state.m_current_subquery_depth > Limits::maximum_subquery_depth)
1022 syntax_error(DeprecatedString::formatted("Exceeded maximum subquery depth of {}", Limits::maximum_subquery_depth));
1023
1024 ScopeGuard guard([&]() { --m_parser_state.m_current_subquery_depth; });
1025
1026 // https://sqlite.org/syntax/table-or-subquery.html
1027 if (match(TokenType::Identifier)) {
1028 DeprecatedString schema_name;
1029 DeprecatedString table_name;
1030 parse_schema_and_table_name(schema_name, table_name);
1031
1032 DeprecatedString table_alias;
1033 if (consume_if(TokenType::As) || match(TokenType::Identifier))
1034 table_alias = consume(TokenType::Identifier).value();
1035
1036 return create_ast_node<TableOrSubquery>(move(schema_name), move(table_name), move(table_alias));
1037 }
1038
1039 // FIXME: Parse join-clause.
1040
1041 Vector<NonnullRefPtr<TableOrSubquery>> subqueries;
1042 parse_comma_separated_list(true, [&]() { subqueries.append(parse_table_or_subquery()); });
1043
1044 return create_ast_node<TableOrSubquery>(move(subqueries));
1045}
1046
1047NonnullRefPtr<OrderingTerm> Parser::parse_ordering_term()
1048{
1049 // https://sqlite.org/syntax/ordering-term.html
1050 auto expression = parse_expression();
1051
1052 DeprecatedString collation_name;
1053 if (is<CollateExpression>(*expression)) {
1054 auto const& collate = static_cast<CollateExpression const&>(*expression);
1055 collation_name = collate.collation_name();
1056 expression = collate.expression();
1057 } else if (consume_if(TokenType::Collate)) {
1058 collation_name = consume(TokenType::Identifier).value();
1059 }
1060
1061 Order order = consume_if(TokenType::Desc) ? Order::Descending : Order::Ascending;
1062 consume_if(TokenType::Asc); // ASC is the default, so ignore it if specified.
1063
1064 Nulls nulls = order == Order::Ascending ? Nulls::First : Nulls::Last;
1065 if (consume_if(TokenType::Nulls)) {
1066 if (consume_if(TokenType::First))
1067 nulls = Nulls::First;
1068 else if (consume_if(TokenType::Last))
1069 nulls = Nulls::Last;
1070 else
1071 expected("FIRST or LAST"sv);
1072 }
1073
1074 return create_ast_node<OrderingTerm>(move(expression), move(collation_name), order, nulls);
1075}
1076
1077void Parser::parse_schema_and_table_name(DeprecatedString& schema_name, DeprecatedString& table_name)
1078{
1079 DeprecatedString schema_or_table_name = consume(TokenType::Identifier).value();
1080
1081 if (consume_if(TokenType::Period)) {
1082 schema_name = move(schema_or_table_name);
1083 table_name = consume(TokenType::Identifier).value();
1084 } else {
1085 table_name = move(schema_or_table_name);
1086 }
1087}
1088
1089ConflictResolution Parser::parse_conflict_resolution()
1090{
1091 // https://sqlite.org/lang_conflict.html
1092 if (consume_if(TokenType::Or)) {
1093 if (consume_if(TokenType::Abort))
1094 return ConflictResolution::Abort;
1095 if (consume_if(TokenType::Fail))
1096 return ConflictResolution::Fail;
1097 if (consume_if(TokenType::Ignore))
1098 return ConflictResolution::Ignore;
1099 if (consume_if(TokenType::Replace))
1100 return ConflictResolution::Replace;
1101 if (consume_if(TokenType::Rollback))
1102 return ConflictResolution::Rollback;
1103
1104 expected("ABORT, FAIL, IGNORE, REPLACE, or ROLLBACK"sv);
1105 }
1106
1107 return ConflictResolution::Abort;
1108}
1109
1110Token Parser::consume()
1111{
1112 auto old_token = m_parser_state.m_token;
1113 m_parser_state.m_token = m_parser_state.m_lexer.next();
1114 return old_token;
1115}
1116
1117Token Parser::consume(TokenType expected_type)
1118{
1119 if (!match(expected_type)) {
1120 expected(Token::name(expected_type));
1121 }
1122 return consume();
1123}
1124
1125bool Parser::consume_if(TokenType expected_type)
1126{
1127 if (!match(expected_type))
1128 return false;
1129
1130 consume();
1131 return true;
1132}
1133
1134bool Parser::match(TokenType type) const
1135{
1136 return m_parser_state.m_token.type() == type;
1137}
1138
1139void Parser::expected(StringView what)
1140{
1141 syntax_error(DeprecatedString::formatted("Unexpected token {}, expected {}", m_parser_state.m_token.name(), what));
1142}
1143
1144void Parser::syntax_error(DeprecatedString message)
1145{
1146 m_parser_state.m_errors.append({ move(message), position() });
1147}
1148
1149SourcePosition Parser::position() const
1150{
1151 return m_parser_state.m_token.start_position();
1152}
1153
1154Parser::ParserState::ParserState(Lexer lexer)
1155 : m_lexer(move(lexer))
1156 , m_token(m_lexer.next())
1157{
1158}
1159
1160}