1
1
mod values;
2
2
3
- use crate :: { DistinctType , Expression , Identifier , Keyword , TokenType } ;
3
+ use crate :: {
4
+ DistinctType , Expression , Identifier , Keyword , SelectFrom , SelectFromSubquery , TokenType ,
5
+ } ;
4
6
5
7
use super :: expression:: ExpressionParser ;
6
8
use super :: { Parser , ParsingError } ;
@@ -16,6 +18,8 @@ pub trait SelectStatementParser {
16
18
fn parse_select_columns ( & mut self ) -> Result < Vec < SelectItem > , ParsingError > ;
17
19
18
20
fn parse_select_column ( & mut self ) -> Result < SelectItem , ParsingError > ;
21
+
22
+ fn parse_select_from_clause ( & mut self ) -> Result < Option < SelectFrom > , ParsingError > ;
19
23
}
20
24
21
25
impl < ' a > SelectStatementParser for Parser < ' a > {
@@ -38,6 +42,7 @@ impl<'a> SelectStatementParser for Parser<'a> {
38
42
let select_statement = SelectStatement {
39
43
distinct_type,
40
44
columns : self . parse_select_columns ( ) ?,
45
+ from : self . parse_select_from_clause ( ) ?,
41
46
..Default :: default ( )
42
47
} ;
43
48
@@ -89,27 +94,90 @@ impl<'a> SelectStatementParser for Parser<'a> {
89
94
self . peek_token ( ) ?. to_string ( ) ,
90
95
) )
91
96
}
97
+
98
+ fn parse_select_from_clause ( & mut self ) -> Result < Option < SelectFrom > , ParsingError > {
99
+ if let Ok ( Keyword :: From ) = self . peek_as_keyword ( ) {
100
+ dbg ! ( "parse_select_from_clause" ) ;
101
+ self . consume_as_keyword ( Keyword :: From ) ?;
102
+
103
+ dbg ! ( & self . peek_token( ) ) ;
104
+ if self . peek_as ( TokenType :: LeftParen ) . is_ok ( ) {
105
+ self . consume_as ( TokenType :: LeftParen ) ?;
106
+ dbg ! ( & self . peek_token( ) ) ;
107
+
108
+ if let Ok ( Keyword :: Select ) = self . peek_as_keyword ( ) {
109
+ dbg ! ( & self . peek_token( ) ) ;
110
+ let subquery = self . parse_select_statement ( ) ?;
111
+ dbg ! ( & subquery) ;
112
+
113
+ // Here the right parenthesis is mandatory
114
+ self . consume_as ( TokenType :: RightParen ) ?;
115
+ if let Ok ( Keyword :: As ) = self . peek_as_keyword ( ) {
116
+ self . consume_as_keyword ( Keyword :: As ) ?;
117
+ let alias = self . consume_as_id ( ) ?;
118
+ return Ok ( Some ( SelectFrom :: Subquery ( SelectFromSubquery {
119
+ subquery : Box :: new ( subquery) ,
120
+ alias : Some ( alias. to_string ( ) ) ,
121
+ } ) ) ) ;
122
+ }
123
+
124
+ if let Ok ( value) = self . peek_as_id ( ) {
125
+ return Ok ( Some ( SelectFrom :: Subquery ( SelectFromSubquery {
126
+ subquery : Box :: new ( subquery) ,
127
+ alias : Some ( value. to_string ( ) ) ,
128
+ } ) ) ) ;
129
+ }
130
+
131
+ return Ok ( Some ( SelectFrom :: Subquery ( SelectFromSubquery {
132
+ subquery : Box :: new ( subquery) ,
133
+ alias : None ,
134
+ } ) ) ) ;
135
+ }
136
+ }
137
+
138
+ // TODO: Parse table-or-subquery
139
+ return Ok ( None ) ;
140
+ }
141
+ Ok ( None )
142
+ }
92
143
}
93
144
94
145
#[ cfg( test) ]
95
146
mod test_utils {
96
- use crate :: { DistinctType , SelectItem , SelectStatement , SelectStatementType , Statement } ;
147
+ use crate :: {
148
+ DistinctType , Expression , Identifier , SelectFrom , SelectItem , SelectStatement ,
149
+ SelectStatementType ,
150
+ } ;
97
151
98
- pub fn create_select_statement (
152
+ pub fn select_statement_with_columns (
99
153
distinct_type : DistinctType ,
100
154
columns : Vec < SelectItem > ,
101
- ) -> Statement {
102
- Statement :: Select ( SelectStatementType :: Select ( SelectStatement {
155
+ ) -> SelectStatement {
156
+ SelectStatement {
103
157
distinct_type,
104
158
columns,
105
159
..Default :: default ( )
106
- } ) )
160
+ }
161
+ }
162
+
163
+ pub fn select_statement_with_from ( from : SelectFrom ) -> SelectStatementType {
164
+ SelectStatementType :: Select ( SelectStatement {
165
+ distinct_type : DistinctType :: None ,
166
+ columns : vec ! [ SelectItem :: Expression ( Expression :: Identifier (
167
+ Identifier :: Wildcard ,
168
+ ) ) ] ,
169
+ from : Some ( from) ,
170
+ ..Default :: default ( )
171
+ } )
107
172
}
108
173
}
109
174
110
175
#[ cfg( test) ]
111
176
mod test_select_result_columns {
112
- use crate :: { BinaryOp , DistinctType , Expression , Identifier , ParsingError , SelectItem } ;
177
+ use crate :: {
178
+ BinaryOp , DistinctType , Expression , Identifier , ParsingError , SelectItem ,
179
+ SelectStatementType , Statement ,
180
+ } ;
113
181
114
182
use super :: test_utils:: * ;
115
183
use crate :: parser:: expression:: test_utils:: * ;
@@ -119,21 +187,21 @@ mod test_select_result_columns {
119
187
fn test_select_distinct ( ) {
120
188
run_sunny_day_test (
121
189
"SELECT DISTINCT column1" ,
122
- create_select_statement (
190
+ Statement :: Select ( SelectStatementType :: Select ( select_statement_with_columns (
123
191
DistinctType :: Distinct ,
124
192
vec ! [ SelectItem :: Expression ( identifier_expression( & [ "column1" ] ) ) ] ,
125
- ) ,
193
+ ) ) ) ,
126
194
) ;
127
195
}
128
196
129
197
#[ test]
130
198
fn test_select_all ( ) {
131
199
run_sunny_day_test (
132
200
"SELECT ALL column1" ,
133
- create_select_statement (
201
+ Statement :: Select ( SelectStatementType :: Select ( select_statement_with_columns (
134
202
DistinctType :: All ,
135
203
vec ! [ SelectItem :: Expression ( identifier_expression( & [ "column1" ] ) ) ] ,
136
- ) ,
204
+ ) ) ) ,
137
205
) ;
138
206
}
139
207
@@ -154,77 +222,77 @@ mod test_select_result_columns {
154
222
fn test_select_statement_parser_with_single_literal_value ( ) {
155
223
run_sunny_day_test (
156
224
"SELECT 1" ,
157
- create_select_statement (
225
+ Statement :: Select ( SelectStatementType :: Select ( select_statement_with_columns (
158
226
DistinctType :: None ,
159
227
vec ! [ SelectItem :: Expression ( numeric_literal_expression( "1" ) ) ] ,
160
- ) ,
228
+ ) ) ) ,
161
229
) ;
162
230
}
163
231
164
232
#[ test]
165
233
fn test_select_statement_parser_with_single_identifier ( ) {
166
234
run_sunny_day_test (
167
235
"SELECT id" ,
168
- create_select_statement (
236
+ Statement :: Select ( SelectStatementType :: Select ( select_statement_with_columns (
169
237
DistinctType :: None ,
170
238
vec ! [ SelectItem :: Expression ( identifier_expression( & [ "id" ] ) ) ] ,
171
- ) ,
239
+ ) ) ) ,
172
240
) ;
173
241
}
174
242
175
243
#[ test]
176
244
fn test_select_statement_parser_with_multiple_literal_values ( ) {
177
245
run_sunny_day_test (
178
246
"SELECT 1, 2, 3" ,
179
- create_select_statement (
247
+ Statement :: Select ( SelectStatementType :: Select ( select_statement_with_columns (
180
248
DistinctType :: None ,
181
249
vec ! [
182
250
SelectItem :: Expression ( numeric_literal_expression( "1" ) ) ,
183
251
SelectItem :: Expression ( numeric_literal_expression( "2" ) ) ,
184
252
SelectItem :: Expression ( numeric_literal_expression( "3" ) ) ,
185
253
] ,
186
- ) ,
254
+ ) ) ) ,
187
255
) ;
188
256
}
189
257
190
258
#[ test]
191
259
fn test_select_statement_parser_with_multiple_identifiers ( ) {
192
260
run_sunny_day_test (
193
261
"SELECT id, name, age" ,
194
- create_select_statement (
262
+ Statement :: Select ( SelectStatementType :: Select ( select_statement_with_columns (
195
263
DistinctType :: None ,
196
264
vec ! [
197
265
SelectItem :: Expression ( identifier_expression( & [ "id" ] ) ) ,
198
266
SelectItem :: Expression ( identifier_expression( & [ "name" ] ) ) ,
199
267
SelectItem :: Expression ( identifier_expression( & [ "age" ] ) ) ,
200
268
] ,
201
- ) ,
269
+ ) ) ) ,
202
270
) ;
203
271
}
204
272
205
273
#[ test]
206
274
fn test_select_statement_parser_with_wildcard ( ) {
207
275
run_sunny_day_test (
208
276
"SELECT *" ,
209
- create_select_statement (
277
+ Statement :: Select ( SelectStatementType :: Select ( select_statement_with_columns (
210
278
DistinctType :: None ,
211
279
vec ! [ SelectItem :: Expression ( Expression :: Identifier (
212
280
Identifier :: Wildcard ,
213
281
) ) ] ,
214
- ) ,
282
+ ) ) ) ,
215
283
) ;
216
284
}
217
285
218
286
#[ test]
219
287
fn test_select_statement_parser_with_table_name_and_wildcard ( ) {
220
288
run_sunny_day_test (
221
289
"SELECT table_1.*" ,
222
- create_select_statement (
290
+ Statement :: Select ( SelectStatementType :: Select ( select_statement_with_columns (
223
291
DistinctType :: None ,
224
292
vec ! [ SelectItem :: Expression ( Expression :: Identifier (
225
293
Identifier :: NameWithWildcard ( "table_1" . to_string( ) ) ,
226
294
) ) ] ,
227
- ) ,
295
+ ) ) ) ,
228
296
) ;
229
297
}
230
298
@@ -240,35 +308,35 @@ mod test_select_result_columns {
240
308
fn test_select_statement_parser_with_alias ( ) {
241
309
run_sunny_day_test (
242
310
"SELECT column1 AS alias" ,
243
- create_select_statement (
311
+ Statement :: Select ( SelectStatementType :: Select ( select_statement_with_columns (
244
312
DistinctType :: None ,
245
313
vec ! [ SelectItem :: ExpressionWithAlias (
246
314
identifier_expression( & [ "column1" ] ) ,
247
315
"alias" . to_string( ) ,
248
316
) ] ,
249
- ) ,
317
+ ) ) ) ,
250
318
) ;
251
319
}
252
320
253
321
#[ test]
254
322
fn test_select_statement_parser_with_alias_without_as_keyword ( ) {
255
323
run_sunny_day_test (
256
324
"SELECT column1 alias" ,
257
- create_select_statement (
325
+ Statement :: Select ( SelectStatementType :: Select ( select_statement_with_columns (
258
326
DistinctType :: None ,
259
327
vec ! [ SelectItem :: ExpressionWithAlias (
260
328
identifier_expression( & [ "column1" ] ) ,
261
329
"alias" . to_string( ) ,
262
330
) ] ,
263
- ) ,
331
+ ) ) ) ,
264
332
) ;
265
333
}
266
334
267
335
#[ test]
268
336
fn test_select_statement_parser_with_multiple_columns_and_aliases ( ) {
269
337
run_sunny_day_test (
270
338
"SELECT column1, column2 AS alias2" ,
271
- create_select_statement (
339
+ Statement :: Select ( SelectStatementType :: Select ( select_statement_with_columns (
272
340
DistinctType :: None ,
273
341
vec ! [
274
342
SelectItem :: Expression ( identifier_expression( & [ "column1" ] ) ) ,
@@ -277,15 +345,15 @@ mod test_select_result_columns {
277
345
"alias2" . to_string( ) ,
278
346
) ,
279
347
] ,
280
- ) ,
348
+ ) ) ) ,
281
349
) ;
282
350
}
283
351
284
352
#[ test]
285
353
fn test_select_statement_parser_with_expression_and_alias ( ) {
286
354
run_sunny_day_test (
287
355
"SELECT 1 + col1 as incremented, column2 * 2 - 1 as doubled" ,
288
- create_select_statement (
356
+ Statement :: Select ( SelectStatementType :: Select ( select_statement_with_columns (
289
357
DistinctType :: None ,
290
358
vec ! [
291
359
SelectItem :: ExpressionWithAlias (
@@ -309,7 +377,74 @@ mod test_select_result_columns {
309
377
"doubled" . to_string( ) ,
310
378
) ,
311
379
] ,
312
- ) ,
380
+ ) ) ) ,
381
+ ) ;
382
+ }
383
+ }
384
+
385
+ #[ cfg( test) ]
386
+ mod test_select_from_subquery {
387
+ use super :: test_utils:: { select_statement_with_columns, select_statement_with_from} ;
388
+ use crate :: parser:: test_utils:: * ;
389
+ use crate :: {
390
+ DistinctType , Expression , Identifier , SelectFrom , SelectFromSubquery , SelectItem ,
391
+ SelectStatementType , Statement ,
392
+ } ;
393
+
394
+ #[ test]
395
+ fn test_select_from_subquery ( ) {
396
+ let expected_statement =
397
+ select_statement_with_from ( SelectFrom :: Subquery ( SelectFromSubquery {
398
+ subquery : Box :: new ( SelectStatementType :: Select ( select_statement_with_columns (
399
+ DistinctType :: None ,
400
+ vec ! [ SelectItem :: Expression ( Expression :: Identifier (
401
+ Identifier :: Single ( "col1" . to_string( ) ) ,
402
+ ) ) ] ,
403
+ ) ) ) ,
404
+ alias : None ,
405
+ } ) ) ;
406
+
407
+ run_sunny_day_test (
408
+ "SELECT * FROM (SELECT col1)" ,
409
+ Statement :: Select ( expected_statement) ,
410
+ ) ;
411
+ }
412
+
413
+ #[ test]
414
+ fn test_select_from_subquery_aliased ( ) {
415
+ let expected_statement =
416
+ select_statement_with_from ( SelectFrom :: Subquery ( SelectFromSubquery {
417
+ subquery : Box :: new ( SelectStatementType :: Select ( select_statement_with_columns (
418
+ DistinctType :: None ,
419
+ vec ! [ SelectItem :: Expression ( Expression :: Identifier (
420
+ Identifier :: NameWithWildcard ( "t" . to_string( ) ) ,
421
+ ) ) ] ,
422
+ ) ) ) ,
423
+ alias : Some ( "alias" . to_string ( ) ) ,
424
+ } ) ) ;
425
+
426
+ run_sunny_day_test (
427
+ "SELECT * FROM (SELECT t.* ) as alias" ,
428
+ Statement :: Select ( expected_statement) ,
429
+ ) ;
430
+ }
431
+
432
+ #[ test]
433
+ fn test_select_from_subquery_aliased_without_as_keyword ( ) {
434
+ let expected_statement =
435
+ select_statement_with_from ( SelectFrom :: Subquery ( SelectFromSubquery {
436
+ subquery : Box :: new ( SelectStatementType :: Select ( select_statement_with_columns (
437
+ DistinctType :: None ,
438
+ vec ! [ SelectItem :: Expression ( Expression :: Identifier (
439
+ Identifier :: Single ( "t1" . to_string( ) ) ,
440
+ ) ) ] ,
441
+ ) ) ) ,
442
+ alias : Some ( "alias" . to_string ( ) ) ,
443
+ } ) ) ;
444
+
445
+ run_sunny_day_test (
446
+ "SELECT * FROM (SELECT t1) alias" ,
447
+ Statement :: Select ( expected_statement) ,
313
448
) ;
314
449
}
315
450
}
0 commit comments