Skip to content

Commit 749dd24

Browse files
committed
sql-parser: select from clause (sub select query)
1 parent f2b8e98 commit 749dd24

File tree

2 files changed

+167
-32
lines changed

2 files changed

+167
-32
lines changed

src/ast/select.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub struct SelectFromFunction {
103103
/// A subquery in a FROM clause
104104
#[derive(Debug, PartialEq, Clone)]
105105
pub struct SelectFromSubquery {
106-
pub subquery: Box<SelectStatement>,
106+
pub subquery: Box<SelectStatementType>,
107107
pub alias: Option<String>,
108108
}
109109

src/parser/select/mod.rs

+166-31
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
mod values;
22

3-
use crate::{DistinctType, Expression, Identifier, Keyword, TokenType};
3+
use crate::{
4+
DistinctType, Expression, Identifier, Keyword, SelectFrom, SelectFromSubquery, TokenType,
5+
};
46

57
use super::expression::ExpressionParser;
68
use super::{Parser, ParsingError};
@@ -16,6 +18,8 @@ pub trait SelectStatementParser {
1618
fn parse_select_columns(&mut self) -> Result<Vec<SelectItem>, ParsingError>;
1719

1820
fn parse_select_column(&mut self) -> Result<SelectItem, ParsingError>;
21+
22+
fn parse_select_from_clause(&mut self) -> Result<Option<SelectFrom>, ParsingError>;
1923
}
2024

2125
impl<'a> SelectStatementParser for Parser<'a> {
@@ -38,6 +42,7 @@ impl<'a> SelectStatementParser for Parser<'a> {
3842
let select_statement = SelectStatement {
3943
distinct_type,
4044
columns: self.parse_select_columns()?,
45+
from: self.parse_select_from_clause()?,
4146
..Default::default()
4247
};
4348

@@ -89,27 +94,90 @@ impl<'a> SelectStatementParser for Parser<'a> {
8994
self.peek_token()?.to_string(),
9095
))
9196
}
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+
}
92143
}
93144

94145
#[cfg(test)]
95146
mod test_utils {
96-
use crate::{DistinctType, SelectItem, SelectStatement, SelectStatementType, Statement};
147+
use crate::{
148+
DistinctType, Expression, Identifier, SelectFrom, SelectItem, SelectStatement,
149+
SelectStatementType,
150+
};
97151

98-
pub fn create_select_statement(
152+
pub fn select_statement_with_columns(
99153
distinct_type: DistinctType,
100154
columns: Vec<SelectItem>,
101-
) -> Statement {
102-
Statement::Select(SelectStatementType::Select(SelectStatement {
155+
) -> SelectStatement {
156+
SelectStatement {
103157
distinct_type,
104158
columns,
105159
..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+
})
107172
}
108173
}
109174

110175
#[cfg(test)]
111176
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+
};
113181

114182
use super::test_utils::*;
115183
use crate::parser::expression::test_utils::*;
@@ -119,21 +187,21 @@ mod test_select_result_columns {
119187
fn test_select_distinct() {
120188
run_sunny_day_test(
121189
"SELECT DISTINCT column1",
122-
create_select_statement(
190+
Statement::Select(SelectStatementType::Select(select_statement_with_columns(
123191
DistinctType::Distinct,
124192
vec![SelectItem::Expression(identifier_expression(&["column1"]))],
125-
),
193+
))),
126194
);
127195
}
128196

129197
#[test]
130198
fn test_select_all() {
131199
run_sunny_day_test(
132200
"SELECT ALL column1",
133-
create_select_statement(
201+
Statement::Select(SelectStatementType::Select(select_statement_with_columns(
134202
DistinctType::All,
135203
vec![SelectItem::Expression(identifier_expression(&["column1"]))],
136-
),
204+
))),
137205
);
138206
}
139207

@@ -154,77 +222,77 @@ mod test_select_result_columns {
154222
fn test_select_statement_parser_with_single_literal_value() {
155223
run_sunny_day_test(
156224
"SELECT 1",
157-
create_select_statement(
225+
Statement::Select(SelectStatementType::Select(select_statement_with_columns(
158226
DistinctType::None,
159227
vec![SelectItem::Expression(numeric_literal_expression("1"))],
160-
),
228+
))),
161229
);
162230
}
163231

164232
#[test]
165233
fn test_select_statement_parser_with_single_identifier() {
166234
run_sunny_day_test(
167235
"SELECT id",
168-
create_select_statement(
236+
Statement::Select(SelectStatementType::Select(select_statement_with_columns(
169237
DistinctType::None,
170238
vec![SelectItem::Expression(identifier_expression(&["id"]))],
171-
),
239+
))),
172240
);
173241
}
174242

175243
#[test]
176244
fn test_select_statement_parser_with_multiple_literal_values() {
177245
run_sunny_day_test(
178246
"SELECT 1, 2, 3",
179-
create_select_statement(
247+
Statement::Select(SelectStatementType::Select(select_statement_with_columns(
180248
DistinctType::None,
181249
vec![
182250
SelectItem::Expression(numeric_literal_expression("1")),
183251
SelectItem::Expression(numeric_literal_expression("2")),
184252
SelectItem::Expression(numeric_literal_expression("3")),
185253
],
186-
),
254+
))),
187255
);
188256
}
189257

190258
#[test]
191259
fn test_select_statement_parser_with_multiple_identifiers() {
192260
run_sunny_day_test(
193261
"SELECT id, name, age",
194-
create_select_statement(
262+
Statement::Select(SelectStatementType::Select(select_statement_with_columns(
195263
DistinctType::None,
196264
vec![
197265
SelectItem::Expression(identifier_expression(&["id"])),
198266
SelectItem::Expression(identifier_expression(&["name"])),
199267
SelectItem::Expression(identifier_expression(&["age"])),
200268
],
201-
),
269+
))),
202270
);
203271
}
204272

205273
#[test]
206274
fn test_select_statement_parser_with_wildcard() {
207275
run_sunny_day_test(
208276
"SELECT *",
209-
create_select_statement(
277+
Statement::Select(SelectStatementType::Select(select_statement_with_columns(
210278
DistinctType::None,
211279
vec![SelectItem::Expression(Expression::Identifier(
212280
Identifier::Wildcard,
213281
))],
214-
),
282+
))),
215283
);
216284
}
217285

218286
#[test]
219287
fn test_select_statement_parser_with_table_name_and_wildcard() {
220288
run_sunny_day_test(
221289
"SELECT table_1.*",
222-
create_select_statement(
290+
Statement::Select(SelectStatementType::Select(select_statement_with_columns(
223291
DistinctType::None,
224292
vec![SelectItem::Expression(Expression::Identifier(
225293
Identifier::NameWithWildcard("table_1".to_string()),
226294
))],
227-
),
295+
))),
228296
);
229297
}
230298

@@ -240,35 +308,35 @@ mod test_select_result_columns {
240308
fn test_select_statement_parser_with_alias() {
241309
run_sunny_day_test(
242310
"SELECT column1 AS alias",
243-
create_select_statement(
311+
Statement::Select(SelectStatementType::Select(select_statement_with_columns(
244312
DistinctType::None,
245313
vec![SelectItem::ExpressionWithAlias(
246314
identifier_expression(&["column1"]),
247315
"alias".to_string(),
248316
)],
249-
),
317+
))),
250318
);
251319
}
252320

253321
#[test]
254322
fn test_select_statement_parser_with_alias_without_as_keyword() {
255323
run_sunny_day_test(
256324
"SELECT column1 alias",
257-
create_select_statement(
325+
Statement::Select(SelectStatementType::Select(select_statement_with_columns(
258326
DistinctType::None,
259327
vec![SelectItem::ExpressionWithAlias(
260328
identifier_expression(&["column1"]),
261329
"alias".to_string(),
262330
)],
263-
),
331+
))),
264332
);
265333
}
266334

267335
#[test]
268336
fn test_select_statement_parser_with_multiple_columns_and_aliases() {
269337
run_sunny_day_test(
270338
"SELECT column1, column2 AS alias2",
271-
create_select_statement(
339+
Statement::Select(SelectStatementType::Select(select_statement_with_columns(
272340
DistinctType::None,
273341
vec![
274342
SelectItem::Expression(identifier_expression(&["column1"])),
@@ -277,15 +345,15 @@ mod test_select_result_columns {
277345
"alias2".to_string(),
278346
),
279347
],
280-
),
348+
))),
281349
);
282350
}
283351

284352
#[test]
285353
fn test_select_statement_parser_with_expression_and_alias() {
286354
run_sunny_day_test(
287355
"SELECT 1 + col1 as incremented, column2 * 2 - 1 as doubled",
288-
create_select_statement(
356+
Statement::Select(SelectStatementType::Select(select_statement_with_columns(
289357
DistinctType::None,
290358
vec![
291359
SelectItem::ExpressionWithAlias(
@@ -309,7 +377,74 @@ mod test_select_result_columns {
309377
"doubled".to_string(),
310378
),
311379
],
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),
313448
);
314449
}
315450
}

0 commit comments

Comments
 (0)