1use super::*;
16
17const RESERVED_ALIAS_KEYWORDS: &[&str] = &[
20 "JOIN",
21 "LEFT",
22 "RIGHT",
23 "INNER",
24 "OUTER",
25 "CROSS",
26 "FULL",
27 "NATURAL",
28 "ON",
29 "USING",
30 "WHERE",
31 "GROUP",
32 "HAVING",
33 "ORDER",
34 "LIMIT",
35 "OFFSET",
36 "FETCH",
37 "WINDOW",
38 "FOR",
39 "INTO",
40 "UNION",
41 "INTERSECT",
42 "EXCEPT",
43];
44
45fn is_reserved_alias_keyword(upper: &str) -> bool {
47 RESERVED_ALIAS_KEYWORDS
48 .iter()
49 .any(|&kw| kw.eq_ignore_ascii_case(upper))
50}
51
52fn is_table_alias_token(token: &Token) -> bool {
53 matches!(token.token_type, TokenType::Identifier | TokenType::Keyword)
54 && !is_reserved_alias_keyword(&token.literal)
55}
56
57impl Parser {
58 pub fn parse_select_statement(&mut self) -> Option<SelectStatement> {
60 let token = self.cur_token.clone();
61
62 let mut stmt = SelectStatement {
63 token,
64 distinct: false,
65 distinct_on: vec![],
66 columns: Vec::new(),
67 with: None,
68 table_expr: None,
69 where_clause: None,
70 group_by: GroupByClause::default(),
71 having: None,
72 window_defs: Vec::new(),
73 order_by: Vec::new(),
74 limit: None,
75 offset: None,
76 set_operations: Vec::new(),
77 };
78
79 if self.peek_token_is_keyword("DISTINCT") {
81 self.next_token();
82 stmt.distinct = true;
83 self.parse_distinct_on(&mut stmt);
84 }
85
86 self.next_token();
88 stmt.columns = self.parse_select_columns();
89
90 if self.peek_token_is_keyword("FROM") {
92 self.next_token(); self.next_token(); stmt.table_expr = Some(Box::new(self.parse_table_expression()?));
95 }
96
97 if self.peek_token_is_keyword("WHERE") {
99 self.next_token(); self.current_clause = "WHERE".to_string();
101 self.next_token();
102 stmt.where_clause = Some(Box::new(self.parse_expression(Precedence::Lowest)?));
103 }
104
105 if self.peek_token_is_keyword("GROUP") {
107 self.next_token(); if !self.expect_keyword("BY") {
109 return None;
110 }
111 self.current_clause = "GROUP BY".to_string();
112 stmt.group_by = self.parse_group_by_clause();
113 }
114
115 if self.peek_token_is_keyword("HAVING") {
117 self.next_token(); self.current_clause = "HAVING".to_string();
119 self.next_token();
120 stmt.having = Some(Box::new(self.parse_expression(Precedence::Lowest)?));
121 }
122
123 if self.peek_token_is_keyword("WINDOW") {
125 self.next_token(); self.current_clause = "WINDOW".to_string();
127 stmt.window_defs = self.parse_window_definitions();
128 }
129
130 while self.peek_token_is_keyword("UNION")
132 || self.peek_token_is_keyword("INTERSECT")
133 || self.peek_token_is_keyword("EXCEPT")
134 {
135 if let Some(set_op) = self.parse_set_operation() {
136 stmt.set_operations.push(set_op);
137 } else {
138 break;
139 }
140 }
141
142 if self.peek_token_is_keyword("ORDER") {
144 self.next_token(); if !self.expect_keyword("BY") {
146 return None;
147 }
148 self.current_clause = "ORDER BY".to_string();
149 stmt.order_by = self.parse_order_by_expressions();
150 }
151
152 if self.peek_token_is_keyword("LIMIT") {
154 self.next_token(); self.current_clause = "LIMIT".to_string();
156 self.next_token();
157 stmt.limit = Some(Box::new(self.parse_expression(Precedence::Lowest)?));
158 }
159
160 if self.peek_token_is_keyword("OFFSET") {
162 self.next_token(); self.current_clause = "OFFSET".to_string();
164 self.next_token();
165 stmt.offset = Some(Box::new(self.parse_expression(Precedence::Lowest)?));
166
167 if self.peek_token_is_keyword("ROWS") || self.peek_token_is_keyword("ROW") {
169 self.next_token();
170 }
171 }
172
173 if self.peek_token_is_keyword("FETCH") {
175 self.next_token(); if !self.peek_token_is_keyword("FIRST") && !self.peek_token_is_keyword("NEXT") {
179 self.add_error(format!(
180 "expected FIRST or NEXT after FETCH at {}",
181 self.peek_token.position
182 ));
183 return None;
184 }
185 self.next_token(); self.current_clause = "FETCH".to_string();
188 self.next_token();
189 stmt.limit = Some(Box::new(self.parse_expression(Precedence::Lowest)?));
190
191 if self.peek_token_is_keyword("ROWS") || self.peek_token_is_keyword("ROW") {
193 self.next_token();
194 }
195
196 if self.peek_token_is_keyword("ONLY") {
198 self.next_token();
199 }
200 }
201
202 self.current_clause.clear();
203 Some(stmt)
204 }
205
206 pub(super) fn parse_set_operation(&mut self) -> Option<SetOperation> {
209 self.next_token(); let keyword = self.cur_token.literal.to_uppercase();
212 let operation = if keyword == "UNION" {
213 if self.peek_token_is_keyword("ALL") {
214 self.next_token();
215 SetOperationType::UnionAll
216 } else {
217 SetOperationType::Union
218 }
219 } else if keyword == "INTERSECT" {
220 if self.peek_token_is_keyword("ALL") {
221 self.next_token();
222 SetOperationType::IntersectAll
223 } else {
224 SetOperationType::Intersect
225 }
226 } else if keyword == "EXCEPT" {
227 if self.peek_token_is_keyword("ALL") {
228 self.next_token();
229 SetOperationType::ExceptAll
230 } else {
231 SetOperationType::Except
232 }
233 } else {
234 return None;
235 };
236
237 if !self.expect_keyword("SELECT") {
239 return None;
240 }
241
242 let mut right = self.parse_simple_select()?;
244
245 if keyword == "UNION" || keyword == "EXCEPT" {
249 while self.peek_token_is_keyword("INTERSECT") {
250 if let Some(set_op) = self.parse_set_operation() {
251 right.set_operations.push(set_op);
252 } else {
253 break;
254 }
255 }
256 }
257
258 Some(SetOperation {
259 operation,
260 right: Box::new(right),
261 })
262 }
263
264 pub(super) fn parse_simple_select(&mut self) -> Option<SelectStatement> {
266 let token = self.cur_token.clone();
267
268 let mut stmt = SelectStatement {
269 token,
270 distinct: false,
271 distinct_on: vec![],
272 columns: Vec::new(),
273 with: None,
274 table_expr: None,
275 where_clause: None,
276 group_by: GroupByClause::default(),
277 having: None,
278 window_defs: Vec::new(),
279 order_by: Vec::new(),
280 limit: None,
281 offset: None,
282 set_operations: Vec::new(),
283 };
284
285 if self.peek_token_is_keyword("DISTINCT") {
287 self.next_token();
288 stmt.distinct = true;
289 self.parse_distinct_on(&mut stmt);
290 }
291
292 self.next_token();
294 stmt.columns = self.parse_select_columns();
295
296 if self.peek_token_is_keyword("FROM") {
298 self.next_token(); self.next_token(); stmt.table_expr = Some(Box::new(self.parse_table_expression()?));
301 }
302
303 if self.peek_token_is_keyword("WHERE") {
305 self.next_token(); self.current_clause = "WHERE".to_string();
307 self.next_token();
308 stmt.where_clause = Some(Box::new(self.parse_expression(Precedence::Lowest)?));
309 }
310
311 if self.peek_token_is_keyword("GROUP") {
313 self.next_token(); if !self.expect_keyword("BY") {
315 return None;
316 }
317 self.current_clause = "GROUP BY".to_string();
318 stmt.group_by = self.parse_group_by_clause();
319 }
320
321 if self.peek_token_is_keyword("HAVING") {
323 self.next_token(); self.current_clause = "HAVING".to_string();
325 self.next_token();
326 stmt.having = Some(Box::new(self.parse_expression(Precedence::Lowest)?));
327 }
328
329 self.current_clause.clear();
330 Some(stmt)
331 }
332
333 pub(super) fn parse_select_columns(&mut self) -> Vec<Expression> {
335 let mut columns = Vec::new();
336
337 if let Some(col) = self.parse_select_column() {
339 columns.push(col);
340 }
341
342 while self.peek_token_is_punctuator(",") {
344 self.next_token(); self.next_token(); if let Some(col) = self.parse_select_column() {
347 columns.push(col);
348 }
349 }
350
351 columns
352 }
353
354 pub(super) fn parse_select_column(&mut self) -> Option<Expression> {
356 if self.cur_token_is(TokenType::Operator) && self.cur_token.literal == "*" {
358 return Some(Expression::Star(StarExpression {
359 token: self.cur_token.clone(),
360 }));
361 }
362
363 let expr = self.parse_expression(Precedence::Lowest)?;
365
366 if self.peek_token_is_keyword("AS") {
368 self.next_token(); if !self.peek_token_is(TokenType::Identifier) && !self.peek_token_is(TokenType::Keyword)
371 {
372 self.peek_error(TokenType::Identifier);
373 return None;
374 }
375 self.next_token();
376 return Some(Expression::Aliased(AliasedExpression {
377 token: self.cur_token.clone(),
378 expression: Box::new(expr),
379 alias: self.cur_token_as_column_identifier(),
380 }));
381 }
382
383 if self.peek_token_is(TokenType::Identifier) {
386 let alias_candidate = self.peek_token.literal.to_uppercase();
387 let reserved = [
389 "FROM",
390 "WHERE",
391 "GROUP",
392 "HAVING",
393 "ORDER",
394 "LIMIT",
395 "OFFSET",
396 "UNION",
397 "INTERSECT",
398 "EXCEPT",
399 "INTO",
400 "FOR",
401 "WINDOW",
402 "FETCH",
403 "ON",
404 "USING",
405 "NATURAL",
406 "LEFT",
407 "RIGHT",
408 "INNER",
409 "OUTER",
410 "CROSS",
411 "FULL",
412 "JOIN",
413 ];
414 if !reserved.contains(&alias_candidate.as_str()) {
415 self.next_token();
416 return Some(Expression::Aliased(AliasedExpression {
417 token: self.cur_token.clone(),
418 expression: Box::new(expr),
419 alias: Identifier::new(self.cur_token.clone(), self.cur_token.literal.clone()),
420 }));
421 }
422 }
423
424 Some(expr)
425 }
426
427 pub(super) fn parse_table_expression(&mut self) -> Option<Expression> {
429 let left = self.parse_simple_table_expression()?;
430 self.parse_join_table_expression(left)
431 }
432
433 pub(super) fn parse_simple_table_expression(&mut self) -> Option<Expression> {
435 if self.cur_token_is_punctuator("(") {
437 self.next_token();
438 if self.cur_token_is_keyword("SELECT") {
439 let subquery = self.parse_select_statement()?;
440
441 if !self.expect_peek(TokenType::Punctuator) || self.cur_token.literal != ")" {
442 self.add_error(format!(
443 "expected ')' after subquery at {}",
444 self.cur_token.position
445 ));
446 return None;
447 }
448
449 let mut alias = None;
450 if self.peek_token_is_keyword("AS") {
451 self.next_token();
452 if !is_table_alias_token(&self.peek_token) {
453 self.add_error(format!(
454 "expected alias after AS at {}",
455 self.peek_token.position
456 ));
457 return None;
458 }
459 self.next_token();
460 alias = Some(Identifier::new(
461 self.cur_token.clone(),
462 self.cur_token.literal.clone(),
463 ));
464 } else if is_table_alias_token(&self.peek_token) {
465 self.next_token();
466 alias = Some(Identifier::new(
467 self.cur_token.clone(),
468 self.cur_token.literal.clone(),
469 ));
470 }
471
472 return Some(Expression::SubquerySource(Box::new(SubqueryTableSource {
473 token: self.cur_token.clone(),
474 subquery: Box::new(subquery),
475 alias,
476 })));
477 } else if self.cur_token_is_keyword("VALUES") {
478 return self.parse_values_table_source();
480 }
481 }
482
483 if !self.cur_token_is(TokenType::Identifier) && !self.cur_token_is(TokenType::Keyword) {
485 self.add_error(format!(
486 "expected table name at {}",
487 self.cur_token.position
488 ));
489 return None;
490 }
491
492 let token = self.cur_token.clone();
493
494 if self.peek_token_is_punctuator("(") {
496 let name = Identifier::new(token.clone(), self.cur_token.literal.clone());
497 return self.parse_function_table_source(token, name);
498 }
499
500 let name = self.parse_relation_identifier_current()?;
501
502 let as_of = if self.peek_token_is_keyword("AS") {
504 self.next_token(); if self.peek_token_is_keyword("OF") {
506 self.next_token(); self.next_token(); let as_of_type = self.cur_token.literal.to_uppercase();
510 if as_of_type != "TRANSACTION" && as_of_type != "TIMESTAMP" {
511 self.add_error(format!(
512 "expected TRANSACTION or TIMESTAMP after AS OF at {}",
513 self.cur_token.position
514 ));
515 return None;
516 }
517
518 self.next_token();
519 let value = self.parse_expression(Precedence::Lowest)?;
520
521 Some(AsOfClause {
522 token: self.cur_token.clone(),
523 as_of_type,
524 value: Box::new(value),
525 })
526 } else {
527 None
529 }
530 } else {
531 None
532 };
533
534 let mut alias = None;
536 if self.peek_token_is_keyword("AS") {
537 self.next_token(); if !is_table_alias_token(&self.peek_token) {
539 self.add_error(format!(
540 "expected alias after AS at {}",
541 self.peek_token.position
542 ));
543 return None;
544 }
545 self.next_token();
546 alias = Some(Identifier::new(
547 self.cur_token.clone(),
548 self.cur_token.literal.clone(),
549 ));
550 } else if is_table_alias_token(&self.peek_token) {
551 self.next_token();
552 alias = Some(Identifier::new(
553 self.cur_token.clone(),
554 self.cur_token.literal.clone(),
555 ));
556 }
557
558 Some(Expression::TableSource(Box::new(SimpleTableSource {
559 token,
560 name,
561 alias,
562 as_of,
563 })))
564 }
565
566 pub(super) fn parse_join_table_expression(
568 &mut self,
569 mut left: Expression,
570 ) -> Option<Expression> {
571 loop {
572 let join_type = if self.peek_token_is_keyword("JOIN") {
574 self.next_token();
575 SmartString::const_new("INNER")
576 } else if self.peek_token_is_keyword("INNER") {
577 self.next_token();
578 if !self.expect_keyword("JOIN") {
579 return None;
580 }
581 SmartString::const_new("INNER")
582 } else if self.peek_token_is_keyword("LEFT") {
583 self.next_token();
584 if self.peek_token_is_keyword("OUTER") {
585 self.next_token();
586 }
587 if !self.expect_keyword("JOIN") {
588 return None;
589 }
590 SmartString::const_new("LEFT")
591 } else if self.peek_token_is_keyword("RIGHT") {
592 self.next_token();
593 if self.peek_token_is_keyword("OUTER") {
594 self.next_token();
595 }
596 if !self.expect_keyword("JOIN") {
597 return None;
598 }
599 SmartString::const_new("RIGHT")
600 } else if self.peek_token_is_keyword("FULL") {
601 self.next_token();
602 if self.peek_token_is_keyword("OUTER") {
603 self.next_token();
604 }
605 if !self.expect_keyword("JOIN") {
606 return None;
607 }
608 SmartString::const_new("FULL")
609 } else if self.peek_token_is_keyword("CROSS") {
610 self.next_token();
611 if !self.expect_keyword("JOIN") {
612 return None;
613 }
614 SmartString::const_new("CROSS")
615 } else if self.peek_token_is_keyword("NATURAL") {
616 self.next_token();
617 let natural_type = if self.peek_token_is_keyword("LEFT") {
618 self.next_token();
619 if self.peek_token_is_keyword("OUTER") {
620 self.next_token();
621 }
622 "NATURAL LEFT"
623 } else if self.peek_token_is_keyword("RIGHT") {
624 self.next_token();
625 if self.peek_token_is_keyword("OUTER") {
626 self.next_token();
627 }
628 "NATURAL RIGHT"
629 } else {
630 "NATURAL"
631 };
632 if !self.expect_keyword("JOIN") {
633 return None;
634 }
635 SmartString::const_new(natural_type)
636 } else if self.peek_token_is_punctuator(",") {
637 self.next_token(); SmartString::const_new("CROSS")
640 } else {
641 break;
643 };
644
645 let token = self.cur_token.clone();
646 self.next_token();
647 let right = self.parse_simple_table_expression()?;
648
649 let mut condition = None;
651 let mut using_columns = Vec::new();
652
653 if !join_type.starts_with("CROSS") && !join_type.starts_with("NATURAL") {
654 if self.peek_token_is_keyword("ON") {
655 self.next_token(); self.next_token();
657 condition = Some(Box::new(self.parse_expression(Precedence::Lowest)?));
658 } else if self.peek_token_is_keyword("USING") {
659 self.next_token(); if !self.expect_peek(TokenType::Punctuator) || self.cur_token.literal != "(" {
661 self.add_error(format!(
662 "expected '(' after USING at {}",
663 self.cur_token.position
664 ));
665 return None;
666 }
667 using_columns = self.parse_identifier_list();
668 if !self.expect_peek(TokenType::Punctuator) || self.cur_token.literal != ")" {
669 self.add_error(format!(
670 "expected ')' after USING columns at {}",
671 self.cur_token.position
672 ));
673 return None;
674 }
675 } else {
676 self.add_error(format!("{} JOIN requires an ON or USING clause", join_type));
677 return None;
678 }
679 }
680
681 left = Expression::JoinSource(Box::new(JoinTableSource {
682 token,
683 left: Box::new(left),
684 join_type,
685 right: Box::new(right),
686 condition,
687 using_columns,
688 }));
689 }
690
691 Some(left)
692 }
693
694 pub(super) fn parse_with_statement(&mut self) -> Option<Statement> {
696 let with_clause = self.parse_with_clause()?;
697
698 self.next_token();
700 if self.cur_token_is_keyword("SELECT") {
701 let mut select = self.parse_select_statement()?;
702 select.with = Some(with_clause);
703 Some(Statement::Select(select))
704 } else if self.cur_token_is_keyword("INSERT") {
705 let mut insert = self.parse_insert_statement()?;
707 if let Some(ref mut select) = insert.select {
709 select.with = Some(with_clause);
710 } else {
711 self.add_error(
712 "WITH clause requires INSERT ... SELECT, not INSERT ... VALUES".to_string(),
713 );
714 return None;
715 }
716 Some(Statement::Insert(insert))
717 } else {
718 self.add_error(format!(
719 "expected SELECT or INSERT after WITH clause at {}",
720 self.cur_token.position
721 ));
722 None
723 }
724 }
725
726 pub(super) fn parse_with_clause(&mut self) -> Option<WithClause> {
728 let token = self.cur_token.clone();
729 let mut is_recursive = false;
730
731 if self.peek_token_is_keyword("RECURSIVE") {
733 self.next_token();
734 is_recursive = true;
735 }
736
737 let mut ctes = Vec::new();
738
739 self.next_token();
741 if let Some(cte) = self.parse_common_table_expression(is_recursive) {
742 ctes.push(cte);
743 }
744
745 while self.peek_token_is_punctuator(",") {
747 self.next_token(); self.next_token(); if let Some(cte) = self.parse_common_table_expression(is_recursive) {
750 ctes.push(cte);
751 }
752 }
753
754 Some(WithClause {
755 token,
756 ctes,
757 is_recursive,
758 })
759 }
760
761 pub(super) fn parse_common_table_expression(
763 &mut self,
764 is_recursive: bool,
765 ) -> Option<CommonTableExpression> {
766 if !self.cur_token_is(TokenType::Identifier) && !self.cur_token_is(TokenType::Keyword) {
769 self.add_error(format!("expected CTE name at {}", self.cur_token.position));
770 return None;
771 }
772
773 let token = self.cur_token.clone();
774 let name = Identifier::new(token.clone(), self.cur_token.literal.clone());
775
776 let mut column_names = Vec::new();
778 if self.peek_token_is_punctuator("(") {
779 self.next_token(); column_names = self.parse_identifier_list();
781 if !self.expect_peek(TokenType::Punctuator) || self.cur_token.literal != ")" {
782 self.add_error(format!(
783 "expected ')' after column list at {}",
784 self.cur_token.position
785 ));
786 return None;
787 }
788 }
789
790 if !self.expect_keyword("AS") {
792 return None;
793 }
794
795 if !self.expect_peek(TokenType::Punctuator) || self.cur_token.literal != "(" {
797 self.add_error(format!(
798 "expected '(' after AS at {}",
799 self.cur_token.position
800 ));
801 return None;
802 }
803
804 self.next_token();
806 if !self.cur_token_is_keyword("SELECT") {
807 self.add_error(format!(
808 "expected SELECT in CTE at {}",
809 self.cur_token.position
810 ));
811 return None;
812 }
813
814 let query = self.parse_select_statement()?;
815
816 if !self.expect_peek(TokenType::Punctuator) || self.cur_token.literal != ")" {
818 self.add_error(format!(
819 "expected ')' after CTE query at {}",
820 self.cur_token.position
821 ));
822 return None;
823 }
824
825 Some(CommonTableExpression {
826 token,
827 name,
828 column_names,
829 query: Box::new(query),
830 is_recursive,
831 })
832 }
833
834 pub(super) fn parse_distinct_on(&mut self, stmt: &mut SelectStatement) {
836 if self.peek_token_is_keyword("ON") {
837 self.next_token(); if self.peek_token_is_punctuator("(") {
839 self.next_token(); stmt.distinct_on = self.parse_distinct_on_columns();
841 if !self.peek_token_is_punctuator(")") {
842 self.add_error(format!(
843 "expected ')' after DISTINCT ON columns at {}",
844 self.peek_token.position
845 ));
846 return;
847 }
848 self.next_token(); } else {
850 self.add_error(format!(
851 "expected '(' after DISTINCT ON at {}",
852 self.peek_token.position
853 ));
854 }
855 }
856 }
857
858 pub(super) fn parse_distinct_on_columns(&mut self) -> Vec<Expression> {
860 let mut exprs = Vec::new();
861 self.next_token();
862 if let Some(expr) = self.parse_expression(Precedence::Lowest) {
863 exprs.push(expr);
864 }
865 while self.peek_token_is_punctuator(",") {
866 self.next_token(); self.next_token(); if let Some(expr) = self.parse_expression(Precedence::Lowest) {
869 exprs.push(expr);
870 }
871 }
872 exprs
873 }
874
875 pub(super) fn parse_values_table_source(&mut self) -> Option<Expression> {
877 let token = self.cur_token.clone(); let rows = self.parse_value_lists()?;
881
882 if !self.expect_peek(TokenType::Punctuator) || self.cur_token.literal != ")" {
884 self.add_error(format!(
885 "expected ')' after VALUES at {}",
886 self.cur_token.position
887 ));
888 return None;
889 }
890
891 let mut alias = None;
893 let mut column_aliases = Vec::new();
894
895 if self.peek_token_is_keyword("AS") {
896 self.next_token(); if !is_table_alias_token(&self.peek_token) {
898 self.add_error(format!(
899 "expected alias after AS at {}",
900 self.peek_token.position
901 ));
902 return None;
903 }
904 self.next_token();
905 alias = Some(Identifier::new(
906 self.cur_token.clone(),
907 self.cur_token.literal.clone(),
908 ));
909
910 if self.peek_token_is_punctuator("(") {
912 self.next_token(); column_aliases = self.parse_identifier_list();
914 if !self.expect_peek(TokenType::Punctuator) || self.cur_token.literal != ")" {
915 self.add_error(format!(
916 "expected ')' after column aliases at {}",
917 self.cur_token.position
918 ));
919 return None;
920 }
921 }
922 } else if is_table_alias_token(&self.peek_token) {
923 self.next_token();
925 alias = Some(Identifier::new(
926 self.cur_token.clone(),
927 self.cur_token.literal.clone(),
928 ));
929
930 if self.peek_token_is_punctuator("(") {
932 self.next_token(); column_aliases = self.parse_identifier_list();
934 if !self.expect_peek(TokenType::Punctuator) || self.cur_token.literal != ")" {
935 self.add_error(format!(
936 "expected ')' after column aliases at {}",
937 self.cur_token.position
938 ));
939 return None;
940 }
941 }
942 }
943
944 Some(Expression::ValuesSource(Box::new(ValuesTableSource {
945 token,
946 rows,
947 alias,
948 column_aliases,
949 })))
950 }
951
952 pub(super) fn parse_function_table_source(
955 &mut self,
956 token: Token,
957 name: Identifier,
958 ) -> Option<Expression> {
959 self.next_token(); self.next_token(); let mut arguments = Vec::new();
963
964 if !self.cur_token_is_punctuator(")") {
966 if let Some(arg) = self.parse_expression(Precedence::Lowest) {
967 arguments.push(arg);
968 }
969 while self.peek_token_is_punctuator(",") {
970 self.next_token(); self.next_token(); if let Some(arg) = self.parse_expression(Precedence::Lowest) {
973 arguments.push(arg);
974 } else {
975 self.add_error(format!(
976 "expected expression after ',' at {}",
977 self.cur_token.position
978 ));
979 return None;
980 }
981 }
982 }
983
984 if !self.cur_token_is_punctuator(")")
987 && (!self.expect_peek(TokenType::Punctuator) || self.cur_token.literal != ")")
988 {
989 self.add_error(format!(
990 "expected ')' after function arguments at {}",
991 self.cur_token.position
992 ));
993 return None;
994 }
995
996 let mut alias = None;
998 let mut column_aliases = Vec::new();
999
1000 if self.peek_token_is_keyword("AS") {
1001 self.next_token(); if !is_table_alias_token(&self.peek_token) {
1003 self.add_error(format!(
1004 "expected alias after AS at {}",
1005 self.peek_token.position
1006 ));
1007 return None;
1008 }
1009 self.next_token();
1010 alias = Some(Identifier::new(
1011 self.cur_token.clone(),
1012 self.cur_token.literal.clone(),
1013 ));
1014
1015 if self.peek_token_is_punctuator("(") {
1017 self.next_token(); column_aliases = self.parse_identifier_list();
1019 if !self.expect_peek(TokenType::Punctuator) || self.cur_token.literal != ")" {
1020 self.add_error(format!(
1021 "expected ')' after column aliases at {}",
1022 self.cur_token.position
1023 ));
1024 return None;
1025 }
1026 }
1027 } else if is_table_alias_token(&self.peek_token) {
1028 self.next_token();
1030 alias = Some(Identifier::new(
1031 self.cur_token.clone(),
1032 self.cur_token.literal.clone(),
1033 ));
1034
1035 if self.peek_token_is_punctuator("(") {
1037 self.next_token(); column_aliases = self.parse_identifier_list();
1039 if !self.expect_peek(TokenType::Punctuator) || self.cur_token.literal != ")" {
1040 self.add_error(format!(
1041 "expected ')' after column aliases at {}",
1042 self.cur_token.position
1043 ));
1044 return None;
1045 }
1046 }
1047 }
1048
1049 Some(Expression::FunctionTableSource(Box::new(
1050 FunctionTableSource {
1051 token,
1052 function: name,
1053 arguments,
1054 alias,
1055 column_aliases,
1056 },
1057 )))
1058 }
1059}