1pub mod element_type;
3
4use crate::{SqlElementType, SqlLanguage};
5use oak_core::{
6 GreenNode, OakError, Parser, ParserState, TextEdit, TokenType,
7 parser::{
8 ParseCache, ParseOutput, parse_with_lexer,
9 pratt::{Associativity, Pratt, PrattParser, binary},
10 },
11 source::Source,
12};
13
14pub struct SqlParser<'config> {
28 pub(crate) config: &'config SqlLanguage,
29}
30
31impl<'config> SqlParser<'config> {
32 pub fn new(config: &'config SqlLanguage) -> Self {
34 Self { config }
35 }
36}
37
38pub(crate) type State<'a, S> = ParserState<'a, SqlLanguage, S>;
39
40impl<'config> Pratt<SqlLanguage> for SqlParser<'config> {
41 fn primary<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> &'a GreenNode<'a, SqlLanguage> {
42 use crate::lexer::SqlTokenType::*;
43 let cp = state.checkpoint();
44 match state.peek_kind() {
45 Some(Identifier_) => {
46 state.bump();
47 state.finish_at(cp, SqlElementType::Identifier)
48 }
49 Some(LeftBracket) => {
50 state.bump();
51 while state.not_at_end() && state.peek_kind() != Some(RightBracket) {
52 PrattParser::parse(state, 0, self);
53 if !state.eat(Comma) {
54 break;
55 }
56 }
57 state.expect(RightBracket).ok();
58 state.finish_at(cp, SqlElementType::Expression)
59 }
60 Some(NumberLiteral) | Some(FloatLiteral) | Some(StringLiteral) | Some(BooleanLiteral) | Some(NullLiteral) | Some(True) | Some(False) | Some(Null) => {
61 state.bump();
62 state.finish_at(cp, SqlElementType::Expression)
63 }
64 Some(LeftParen) => {
65 state.bump();
66 PrattParser::parse(state, 0, self);
67 state.expect(RightParen).ok();
68 state.finish_at(cp, SqlElementType::Expression)
69 }
70 _ => {
71 state.bump();
72 state.finish_at(cp, SqlElementType::ErrorNode)
73 }
74 }
75 }
76
77 fn prefix<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> &'a GreenNode<'a, SqlLanguage> {
78 self.primary(state)
79 }
80
81 fn infix<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, left: &'a GreenNode<'a, SqlLanguage>, min_precedence: u8) -> Option<&'a GreenNode<'a, SqlLanguage>> {
82 use crate::lexer::SqlTokenType::*;
83 let kind = state.peek_kind()?;
84
85 let (prec, assoc) = match kind {
86 Or => (1, Associativity::Left),
87 And => (2, Associativity::Left),
88 Equal | NotEqual | Less | Greater | LessEqual | GreaterEqual | Like | In | Between | Is => (3, Associativity::Left),
89 Concat => (4, Associativity::Left),
90 Plus | Minus => (10, Associativity::Left),
91 Star | Slash | Percent => (11, Associativity::Left),
92 DoubleColon => (15, Associativity::Left),
93 _ => return None,
94 };
95
96 if prec < min_precedence {
97 return None;
98 }
99
100 let expr_kind = SqlElementType::Expression;
101 Some(binary(state, left, kind, prec, assoc, expr_kind, |s, p| PrattParser::parse(s, p, self)))
102 }
103}
104
105impl<'config> SqlParser<'config> {
106 fn parse_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
107 use crate::lexer::SqlTokenType::*;
108 match state.peek_kind() {
109 Some(Select) => self.parse_select(state)?,
110 Some(Insert) => self.parse_insert(state)?,
111 Some(Update) => self.parse_update(state)?,
112 Some(Delete) => self.parse_delete(state)?,
113 Some(Create) => self.parse_create(state)?,
114 Some(Drop) => self.parse_drop(state)?,
115 Some(Alter) => self.parse_alter(state)?,
116 Some(Explain) => self.parse_explain(state)?,
117 Some(Begin) | Some(Commit) | Some(Rollback) | Some(Transaction) => self.parse_transaction(state)?,
118 Some(Pragma) => self.parse_pragma(state)?,
119 Some(Show) => self.parse_show(state)?,
120 Some(Set) => self.parse_set(state)?,
121 _ => {
122 let cp = state.checkpoint();
123 state.advance_until(Semicolon);
124 state.eat(Semicolon);
125 state.finish_at(cp, SqlElementType::ErrorNode);
126 }
127 }
128 Ok(())
129 }
130
131 fn parse_set<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
132 use crate::lexer::SqlTokenType::*;
133 let cp = state.checkpoint();
134 state.expect(Set).ok();
135 state.expect(Identifier_).ok();
136 state.expect(Equal).ok();
137 PrattParser::parse(state, 0, self);
138 state.eat(Semicolon);
139 state.finish_at(cp, SqlElementType::Expression);
140 Ok(())
141 }
142
143 fn parse_explain<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
144 use crate::lexer::SqlTokenType::*;
145 let cp = state.checkpoint();
146 state.expect(Explain).ok();
147 self.parse_statement(state)?;
148 state.finish_at(cp, SqlElementType::ExplainStatement);
149 Ok(())
150 }
151
152 fn parse_transaction<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
153 use crate::lexer::SqlTokenType::*;
154 let cp = state.checkpoint();
155 match state.peek_kind() {
156 Some(Begin) => {
157 state.bump();
158 state.eat(Transaction);
159 }
160 Some(Commit) => {
161 state.bump();
162 state.eat(Transaction);
163 }
164 Some(Rollback) => {
165 state.bump();
166 state.eat(Transaction);
167 }
168 Some(Transaction) => {
169 state.bump();
170 }
171 _ => return Err(OakError::custom_error("Expected BEGIN, COMMIT, or ROLLBACK")),
172 }
173 state.eat(Semicolon);
174 state.finish_at(cp, SqlElementType::TransactionStatement);
175 Ok(())
176 }
177
178 fn parse_pragma<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
179 use crate::lexer::SqlTokenType::*;
180 let cp = state.checkpoint();
181 state.expect(Pragma).ok();
182 state.expect(Identifier_).ok();
183 if state.eat(Equal) || state.eat(LeftParen) {
184 PrattParser::parse(state, 0, self);
185 state.eat(RightParen);
186 }
187 state.eat(Semicolon);
188 state.finish_at(cp, SqlElementType::PragmaStatement);
189 Ok(())
190 }
191
192 fn parse_show<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
193 use crate::lexer::SqlTokenType::*;
194 let cp = state.checkpoint();
195 state.expect(Show).ok();
196 state.expect(Identifier_).ok();
197 state.eat(Semicolon);
198 state.finish_at(cp, SqlElementType::ShowStatement);
199 Ok(())
200 }
201
202 fn parse_select<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
203 use crate::lexer::SqlTokenType::*;
204 let cp = state.checkpoint();
205 state.expect(Select).ok();
206 state.eat(Distinct);
207 state.eat(All);
208
209 while state.not_at_end() && state.peek_kind() != Some(From) {
211 let item_cp = state.checkpoint();
212 if state.eat(Star) {
213 }
215 else {
216 PrattParser::parse(state, 0, self);
217 if state.eat(As) {
218 state.expect(Identifier_).ok();
219 }
220 else if state.peek_kind() == Some(Identifier_) {
221 state.bump();
222 }
223 }
224 state.finish_at(item_cp, SqlElementType::SelectItem);
225
226 if !state.eat(Comma) {
227 break;
228 }
229 }
230
231 if state.eat(From) {
232 let table_cp = state.checkpoint();
233 state.expect(Identifier_).ok(); state.finish_at(table_cp, SqlElementType::TableName);
235
236 while let Some(kind) = state.peek_kind() {
238 if matches!(kind, Join | Inner | Left | Right | Full) {
239 let join_cp = state.checkpoint();
240 if kind != Join {
241 state.bump(); state.eat(Outer);
243 }
244 state.expect(Join).ok();
245
246 let table_cp = state.checkpoint();
247 state.expect(Identifier_).ok(); state.finish_at(table_cp, SqlElementType::TableName);
249
250 if state.eat(On) {
251 PrattParser::parse(state, 0, self); }
253 state.finish_at(join_cp, SqlElementType::JoinClause);
254 }
255 else {
256 break;
257 }
258 }
259 }
260
261 if state.eat(Where) {
262 PrattParser::parse(state, 0, self);
263 }
264
265 if state.eat(Group) {
266 let group_cp = state.checkpoint();
267 state.expect(By).ok();
268 while state.not_at_end() {
269 PrattParser::parse(state, 0, self);
270 if !state.eat(Comma) {
271 break;
272 }
273 }
274 state.finish_at(group_cp, SqlElementType::GroupByClause);
275 }
276
277 if state.eat(Having) {
278 let having_cp = state.checkpoint();
279 PrattParser::parse(state, 0, self);
280 state.finish_at(having_cp, SqlElementType::HavingClause);
281 }
282
283 if state.eat(Order) {
284 let order_cp = state.checkpoint();
285 state.expect(By).ok();
286 while state.not_at_end() {
287 PrattParser::parse(state, 0, self);
288 if state.eat(Asc) || state.eat(Desc) {
289 }
291 if !state.eat(Comma) {
292 break;
293 }
294 }
295 state.finish_at(order_cp, SqlElementType::OrderByClause);
296 }
297
298 if state.eat(Limit) {
299 let limit_cp = state.checkpoint();
300 state.expect(NumberLiteral).ok();
301 if state.eat(Offset) {
302 state.expect(NumberLiteral).ok();
303 }
304 state.finish_at(limit_cp, SqlElementType::LimitClause);
305 }
306 else if state.eat(Offset) {
307 let offset_cp = state.checkpoint();
308 state.expect(NumberLiteral).ok();
309 state.finish_at(offset_cp, SqlElementType::LimitClause);
310 }
311
312 state.eat(Semicolon);
313 state.finish_at(cp, SqlElementType::SelectStatement);
314 Ok(())
315 }
316
317 fn parse_insert<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
318 use crate::lexer::SqlTokenType::*;
319 let cp = state.checkpoint();
320 state.expect(Insert).ok();
321 state.eat(Into);
322
323 let table_cp = state.checkpoint();
324 state.expect(Identifier_).ok(); state.finish_at(table_cp, SqlElementType::TableName);
326
327 if state.eat(LeftParen) {
328 while state.not_at_end() && state.peek_kind() != Some(RightParen) {
329 let col_cp = state.checkpoint();
330 state.expect(Identifier_).ok();
331 state.finish_at(col_cp, SqlElementType::ColumnName);
332 if !state.eat(Comma) {
333 break;
334 }
335 }
336 state.expect(RightParen).ok();
337 }
338
339 if state.eat(Values) {
340 let values_cp = state.checkpoint();
341 while state.eat(LeftParen) {
342 let value_list_cp = state.checkpoint();
343 while state.not_at_end() && state.peek_kind() != Some(RightParen) {
344 PrattParser::parse(state, 0, self);
345 if !state.eat(Comma) {
346 break;
347 }
348 }
349 state.expect(RightParen).ok();
350 state.finish_at(value_list_cp, SqlElementType::ValueList);
351
352 if !state.eat(Comma) {
353 break;
354 }
355 }
356 state.finish_at(values_cp, SqlElementType::ValueList);
357 }
358 else if state.peek_kind() == Some(Select) {
359 self.parse_select(state)?;
360 }
361
362 self.parse_on_conflict(state);
363 self.parse_returning_clause(state);
364
365 state.eat(Semicolon);
366 state.finish_at(cp, SqlElementType::InsertStatement);
367 Ok(())
368 }
369
370 fn parse_on_conflict<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) {
371 use crate::lexer::SqlTokenType::*;
372 if state.eat(On) {
373 if state.eat(Conflict) {
374 let cp = state.checkpoint();
375 if state.eat(LeftParen) {
377 while state.not_at_end() && state.peek_kind() != Some(RightParen) {
378 state.expect(Identifier_).ok();
379 if !state.eat(Comma) {
380 break;
381 }
382 }
383 state.expect(RightParen).ok();
384 }
385
386 if state.eat(Do) {
387 if state.eat(Nothing) {
388 }
390 else if state.eat(Update) {
391 state.expect(Set).ok();
392 while state.not_at_end() && state.peek_kind() != Some(Where) && state.peek_kind() != Some(Semicolon) && state.peek_kind() != Some(Returning) {
393 let assign_cp = state.checkpoint();
394 state.expect(Identifier_).ok();
395 state.expect(Equal).ok();
396 PrattParser::parse(state, 0, self);
397 state.finish_at(assign_cp, SqlElementType::Assignment);
398 if !state.eat(Comma) {
399 break;
400 }
401 }
402 if state.eat(Where) {
403 PrattParser::parse(state, 0, self);
404 }
405 }
406 }
407 state.finish_at(cp, SqlElementType::ConflictClause);
408 }
409 }
410 }
411
412 fn parse_returning_clause<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) {
413 use crate::lexer::SqlTokenType::*;
414 if state.eat(Returning) {
415 let cp = state.checkpoint();
416 while state.not_at_end() && state.peek_kind() != Some(Semicolon) {
417 if state.eat(Star) {
418 }
420 else {
421 PrattParser::parse(state, 0, self);
422 if state.eat(As) {
423 state.expect(Identifier_).ok();
424 }
425 else if state.peek_kind() == Some(Identifier_) {
426 state.bump();
427 }
428 }
429 if !state.eat(Comma) {
430 break;
431 }
432 }
433 state.finish_at(cp, SqlElementType::ReturningClause);
434 }
435 }
436
437 fn parse_update<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
438 use crate::lexer::SqlTokenType::*;
439 let cp = state.checkpoint();
440 state.expect(Update).ok();
441
442 let table_cp = state.checkpoint();
443 state.expect(Identifier_).ok(); state.finish_at(table_cp, SqlElementType::TableName);
445
446 if state.eat(Set) {
447 while state.not_at_end() && state.peek_kind() != Some(Where) && state.peek_kind() != Some(Semicolon) {
448 let assign_cp = state.checkpoint();
449
450 let col_cp = state.checkpoint();
451 state.expect(Identifier_).ok(); state.finish_at(col_cp, SqlElementType::ColumnName);
453
454 state.expect(Equal).ok();
455 PrattParser::parse(state, 0, self);
456 state.finish_at(assign_cp, SqlElementType::Assignment);
457
458 if !state.eat(Comma) {
459 break;
460 }
461 }
462 }
463
464 if state.eat(Where) {
465 PrattParser::parse(state, 0, self);
466 }
467
468 self.parse_returning_clause(state);
469
470 state.eat(Semicolon);
471 state.finish_at(cp, SqlElementType::UpdateStatement);
472 Ok(())
473 }
474
475 fn parse_delete<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
476 use crate::lexer::SqlTokenType::*;
477 let cp = state.checkpoint();
478 state.expect(Delete).ok();
479 state.eat(From);
480
481 let table_cp = state.checkpoint();
482 state.expect(Identifier_).ok(); state.finish_at(table_cp, SqlElementType::TableName);
484
485 if state.eat(Where) {
486 PrattParser::parse(state, 0, self);
487 }
488
489 state.eat(Semicolon);
490 state.finish_at(cp, SqlElementType::DeleteStatement);
491 Ok(())
492 }
493
494 fn parse_create<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
495 use crate::lexer::SqlTokenType::*;
496 let cp = state.checkpoint();
497 state.expect(Create).ok();
498
499 if state.eat(Table) {
500 state.eat(If);
501 state.eat(Not);
502 state.eat(Exists);
503
504 let table_cp = state.checkpoint();
505 state.expect(Identifier_).ok(); state.finish_at(table_cp, SqlElementType::TableName);
507
508 if state.eat(LeftParen) {
509 while state.not_at_end() && state.peek_kind() != Some(RightParen) {
510 let col_cp = state.checkpoint();
511
512 let name_cp = state.checkpoint();
513 state.expect(Identifier_).ok(); state.finish_at(name_cp, SqlElementType::ColumnName);
515
516 self.parse_data_type(state);
518
519 while state.not_at_end() && !matches!(state.peek_kind(), Some(Comma) | Some(RightParen)) {
521 if state.eat(Primary) {
522 state.expect(Key).ok();
523 }
524 else if state.eat(Not) {
525 state.expect(Null).ok();
526 }
527 else if state.eat(Null) {
528 }
529 else if state.eat(Unique) {
530 }
531 else if state.eat(Default) {
532 let expr_cp = state.checkpoint();
533 PrattParser::parse(state, 0, self);
534 state.finish_at(expr_cp, SqlElementType::Expression);
535 }
536 else if state.eat(Check) {
537 if state.eat(LeftParen) {
538 let expr_cp = state.checkpoint();
539 PrattParser::parse(state, 0, self);
540 state.finish_at(expr_cp, SqlElementType::Expression);
541 state.expect(RightParen).ok();
542 }
543 }
544 else if state.eat(AutoIncrement) {
545 }
546 else {
547 state.bump();
548 }
549 }
550
551 state.finish_at(col_cp, SqlElementType::ColumnDefinition);
552 if !state.eat(Comma) {
553 break;
554 }
555 }
556 state.expect(RightParen).ok();
557 }
558 }
559 else if state.eat(View) {
560 let name_cp = state.checkpoint();
561 state.expect(Identifier_).ok();
562 state.finish_at(name_cp, SqlElementType::Identifier);
563
564 state.expect(As).ok();
565 self.parse_select(state)?;
566 }
567 else if state.peek_kind() == Some(Index) || state.peek_kind() == Some(Unique) {
568 state.eat(Unique);
569 if state.eat(Index) {
570 let name_cp = state.checkpoint();
571 state.expect(Identifier_).ok(); state.finish_at(name_cp, SqlElementType::Identifier);
573
574 state.expect(On).ok();
575
576 let table_cp = state.checkpoint();
577 state.expect(Identifier_).ok(); state.finish_at(table_cp, SqlElementType::TableName);
579
580 if state.eat(LeftParen) {
581 while state.not_at_end() && state.peek_kind() != Some(RightParen) {
582 let col_cp = state.checkpoint();
583 state.expect(Identifier_).ok();
584 state.finish_at(col_cp, SqlElementType::Identifier);
585 state.eat(Comma);
586 }
587 state.expect(RightParen).ok();
588 }
589 }
590 }
591 else if state.eat(Database) || state.eat(Schema) {
592 state.eat(If);
593 state.eat(Not);
594 state.eat(Exists);
595 let name_cp = state.checkpoint();
596 state.expect(Identifier_).ok();
597 state.finish_at(name_cp, SqlElementType::Identifier);
598 }
599
600 state.eat(Semicolon);
601 state.finish_at(cp, SqlElementType::CreateStatement);
602 Ok(())
603 }
604
605 fn parse_drop<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
606 use crate::lexer::SqlTokenType::*;
607 let cp = state.checkpoint();
608 state.expect(Drop).ok();
609
610 if state.eat(Table) || state.eat(View) || state.eat(Index) || state.eat(Database) || state.eat(Schema) {
611 state.eat(If);
612 state.eat(Exists);
613 let table_cp = state.checkpoint();
614 state.expect(Identifier_).ok(); state.finish_at(table_cp, SqlElementType::TableName);
616 }
617
618 state.eat(Semicolon);
619 state.finish_at(cp, SqlElementType::DropStatement);
620 Ok(())
621 }
622
623 fn parse_alter<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
624 use crate::lexer::SqlTokenType::*;
625 let cp = state.checkpoint();
626 state.expect(Alter).ok();
627
628 if state.eat(Table) {
629 let table_cp = state.checkpoint();
630 state.expect(Identifier_).ok(); state.finish_at(table_cp, SqlElementType::TableName);
632
633 if state.peek_kind() == Some(Add) || state.peek_kind() == Some(Drop) || state.peek_kind() == Some(Rename) {
635 let action_cp = state.checkpoint();
636 if state.eat(Add) {
637 state.eat(Column);
638 state.expect(Identifier_).ok();
639 self.parse_data_type(state);
641 }
642 else if state.eat(Drop) {
643 state.eat(Column);
644 state.expect(Identifier_).ok();
645 }
646 else if state.eat(Rename) {
647 state.eat(To);
648 state.expect(Identifier_).ok();
649 }
650 state.finish_at(action_cp, SqlElementType::AlterAction);
651 }
652 }
653
654 state.eat(Semicolon);
655 state.finish_at(cp, SqlElementType::AlterStatement);
656 Ok(())
657 }
658
659 fn parse_data_type<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) {
660 use crate::lexer::SqlTokenType::*;
661 if state.not_at_end() && !matches!(state.peek_kind(), Some(Comma) | Some(RightParen) | Some(Primary) | Some(Not) | Some(Null) | Some(Unique) | Some(Default) | Some(Check) | Some(Foreign) | Some(References) | Some(Semicolon)) {
662 state.bump(); if state.eat(LeftParen) {
664 state.expect(NumberLiteral).ok();
665 if state.eat(Comma) {
666 state.expect(NumberLiteral).ok();
667 }
668 state.expect(RightParen).ok();
669 }
670 }
671 }
672}
673
674impl<'config> Parser<SqlLanguage> for SqlParser<'config> {
675 fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl ParseCache<SqlLanguage>) -> ParseOutput<'a, SqlLanguage> {
676 let lexer = crate::lexer::SqlLexer::new(&self.config);
677 parse_with_lexer(&lexer, text, edits, cache, |state| {
678 let cp = state.checkpoint();
679 while state.not_at_end() {
680 if state.current().map(|t| t.kind.is_ignored()).unwrap_or(false) {
681 state.advance();
682 continue;
683 }
684 self.parse_statement(state)?
685 }
686 Ok(state.finish_at(cp, SqlElementType::Root))
687 })
688 }
689}