@@ -2,8 +2,8 @@ mod values;
2
2
3
3
use crate :: expression:: IdentifierParser ;
4
4
use crate :: {
5
- DistinctType , Expression , Identifier , IndexedType , Keyword , SelectFrom , SelectFromSubquery ,
6
- SelectFromTable , TokenType ,
5
+ DistinctType , Expression , Identifier , IndexedType , Keyword , SelectFrom , SelectFromFunction ,
6
+ SelectFromSubquery , SelectFromTable , TokenType ,
7
7
} ;
8
8
9
9
use super :: expression:: ExpressionParser ;
@@ -22,6 +22,8 @@ pub trait SelectStatementParser {
22
22
fn parse_select_column ( & mut self ) -> Result < SelectItem , ParsingError > ;
23
23
24
24
fn parse_select_from_clause ( & mut self ) -> Result < Option < SelectFrom > , ParsingError > ;
25
+
26
+ fn parse_alias_if_exists ( & mut self ) -> Result < Option < String > , ParsingError > ;
25
27
}
26
28
27
29
impl < ' a > SelectStatementParser for Parser < ' a > {
@@ -138,40 +140,57 @@ impl<'a> SelectStatementParser for Parser<'a> {
138
140
}
139
141
140
142
if let Ok ( id) = self . parse_identifier ( ) {
141
- let alias = {
142
- if self . consume_as_keyword ( Keyword :: As ) . is_ok ( ) {
143
- Some ( self . consume_as_id ( ) ?)
144
- } else if let Ok ( value) = self . consume_as_id ( ) {
145
- Some ( value. to_string ( ) )
146
- } else {
147
- None
148
- }
149
- } ;
150
-
151
- let indexed_type = {
152
- if self . consume_as_keyword ( Keyword :: Indexed ) . is_ok ( ) {
153
- self . consume_as_keyword ( Keyword :: By ) ?;
154
- Some ( IndexedType :: Indexed ( self . consume_as_id ( ) ?) )
155
- } else if self . consume_as_keyword ( Keyword :: Not ) . is_ok ( ) {
156
- self . consume_as_keyword ( Keyword :: Indexed ) ?;
157
- Some ( IndexedType :: NotIndexed )
158
- } else {
159
- None
160
- }
161
- } ;
143
+ dbg ! ( "parse_select_from_clause" ) ;
144
+ if self . peek_as ( TokenType :: LeftParen ) . is_ok ( ) {
145
+ self . consume_as ( TokenType :: LeftParen ) ?;
146
+
147
+ let arguments = self . parse_comma_separated_expressions ( ) ?;
162
148
163
- return Ok ( Some ( SelectFrom :: Table ( SelectFromTable {
164
- table_id : id,
165
- alias,
166
- indexed_type,
167
- } ) ) ) ;
149
+ self . consume_as ( TokenType :: RightParen ) ?;
150
+ let alias = self . parse_alias_if_exists ( ) ?;
151
+ return Ok ( Some ( SelectFrom :: Function ( SelectFromFunction {
152
+ function_name : id,
153
+ arguments,
154
+ alias,
155
+ } ) ) ) ;
156
+ } else {
157
+ let alias = self . parse_alias_if_exists ( ) ?;
158
+
159
+ let indexed_type = {
160
+ if self . consume_as_keyword ( Keyword :: Indexed ) . is_ok ( ) {
161
+ self . consume_as_keyword ( Keyword :: By ) ?;
162
+ Some ( IndexedType :: Indexed ( self . consume_as_id ( ) ?) )
163
+ } else if self . consume_as_keyword ( Keyword :: Not ) . is_ok ( ) {
164
+ self . consume_as_keyword ( Keyword :: Indexed ) ?;
165
+ Some ( IndexedType :: NotIndexed )
166
+ } else {
167
+ None
168
+ }
169
+ } ;
170
+
171
+ return Ok ( Some ( SelectFrom :: Table ( SelectFromTable {
172
+ table_id : id,
173
+ alias,
174
+ indexed_type,
175
+ } ) ) ) ;
176
+ }
168
177
}
169
178
170
179
// TODO: Parse table-or-subquery
171
180
return Ok ( None ) ;
172
181
}
173
182
Ok ( None )
174
183
}
184
+
185
+ fn parse_alias_if_exists ( & mut self ) -> Result < Option < String > , ParsingError > {
186
+ if self . consume_as_keyword ( Keyword :: As ) . is_ok ( ) {
187
+ Ok ( Some ( self . consume_as_id ( ) ?) )
188
+ } else if let Ok ( value) = self . consume_as_id ( ) {
189
+ Ok ( Some ( value. to_string ( ) ) )
190
+ } else {
191
+ Ok ( None )
192
+ }
193
+ }
175
194
}
176
195
177
196
#[ cfg( test) ]
@@ -545,26 +564,109 @@ mod test_select_from_subquery {
545
564
546
565
run_sunny_day_test (
547
566
"SELECT * FROM (SELECT t.* ) as alias" ,
567
+ Statement :: Select ( expected_statement. clone ( ) ) ,
568
+ ) ;
569
+
570
+ // without the as keyword
571
+ run_sunny_day_test (
572
+ "SELECT * FROM (SELECT t.* ) alias" ,
573
+ Statement :: Select ( expected_statement. clone ( ) ) ,
574
+ ) ;
575
+ }
576
+ }
577
+
578
+ #[ cfg( test) ]
579
+ mod test_select_from_table_function {
580
+ use super :: test_utils:: select_statement_with_from;
581
+ use crate :: expression:: test_utils:: {
582
+ binary_op_expression, identifier_expression, numeric_literal_expression,
583
+ } ;
584
+ use crate :: parser:: test_utils:: * ;
585
+ use crate :: { BinaryOp , Identifier , SelectFrom , SelectFromFunction , Statement } ;
586
+
587
+ #[ test]
588
+ fn test_select_from_table_function ( ) {
589
+ let expected_statement =
590
+ select_statement_with_from ( SelectFrom :: Function ( SelectFromFunction {
591
+ function_name : Identifier :: Single ( "function_1" . to_string ( ) ) ,
592
+ arguments : vec ! [ numeric_literal_expression( "1" ) ] ,
593
+ alias : None ,
594
+ } ) ) ;
595
+
596
+ run_sunny_day_test (
597
+ "SELECT * FROM function_1(1)" ,
548
598
Statement :: Select ( expected_statement) ,
549
599
) ;
550
600
}
551
601
552
602
#[ test]
553
- fn test_select_from_subquery_aliased_without_as_keyword ( ) {
603
+ fn test_select_from_table_function_with_schema ( ) {
554
604
let expected_statement =
555
- select_statement_with_from ( SelectFrom :: Subquery ( SelectFromSubquery {
556
- subquery : Box :: new ( SelectStatementType :: Select ( select_statement_with_columns (
557
- DistinctType :: None ,
558
- vec ! [ SelectItem :: Expression ( Expression :: Identifier (
559
- Identifier :: Single ( "t1" . to_string( ) ) ,
560
- ) ) ] ,
561
- ) ) ) ,
562
- alias : Some ( "alias" . to_string ( ) ) ,
605
+ select_statement_with_from ( SelectFrom :: Function ( SelectFromFunction {
606
+ function_name : Identifier :: Compound ( vec ! [
607
+ "schema_1" . to_string( ) ,
608
+ "function_1" . to_string( ) ,
609
+ ] ) ,
610
+ arguments : vec ! [ binary_op_expression(
611
+ BinaryOp :: Plus ,
612
+ numeric_literal_expression( "1" ) ,
613
+ numeric_literal_expression( "2" ) ,
614
+ ) ] ,
615
+ alias : None ,
563
616
} ) ) ;
564
617
565
618
run_sunny_day_test (
566
- "SELECT * FROM (SELECT t1) alias " ,
619
+ "SELECT * FROM schema_1.function_1(1+2) " ,
567
620
Statement :: Select ( expected_statement) ,
568
621
) ;
569
622
}
623
+
624
+ #[ test]
625
+ fn test_select_from_table_function_with_multiple_arguments ( ) {
626
+ let expected_statement =
627
+ select_statement_with_from ( SelectFrom :: Function ( SelectFromFunction {
628
+ function_name : Identifier :: Compound ( vec ! [
629
+ "schema_1" . to_string( ) ,
630
+ "function_1" . to_string( ) ,
631
+ ] ) ,
632
+ arguments : vec ! [
633
+ numeric_literal_expression( "1" ) ,
634
+ identifier_expression( & [ "col1" ] ) ,
635
+ numeric_literal_expression( "3" ) ,
636
+ ] ,
637
+ alias : None ,
638
+ } ) ) ;
639
+
640
+ run_sunny_day_test (
641
+ "SELECT * FROM schema_1.function_1(1, col1, 3)" ,
642
+ Statement :: Select ( expected_statement) ,
643
+ ) ;
644
+ }
645
+
646
+ #[ test]
647
+ fn test_select_from_table_function_with_alias ( ) {
648
+ let expected_statement =
649
+ select_statement_with_from ( SelectFrom :: Function ( SelectFromFunction {
650
+ function_name : Identifier :: Compound ( vec ! [
651
+ "schema_1" . to_string( ) ,
652
+ "function_1" . to_string( ) ,
653
+ ] ) ,
654
+ arguments : vec ! [
655
+ numeric_literal_expression( "1" ) ,
656
+ numeric_literal_expression( "2" ) ,
657
+ numeric_literal_expression( "3" ) ,
658
+ ] ,
659
+ alias : Some ( "alias" . to_string ( ) ) ,
660
+ } ) ) ;
661
+
662
+ run_sunny_day_test (
663
+ "SELECT * FROM schema_1.function_1(1, 2, 3) AS alias" ,
664
+ Statement :: Select ( expected_statement. clone ( ) ) ,
665
+ ) ;
666
+
667
+ run_sunny_day_test (
668
+ "SELECT * FROM schema_1.function_1(1, 2, 3) alias" ,
669
+ Statement :: Select ( expected_statement. clone ( ) ) ,
670
+ ) ;
671
+ }
570
672
}
0 commit comments