Skip to content

Commit f18740a

Browse files
committed
sql-parser: select ast (2)
1 parent ce50f40 commit f18740a

File tree

12 files changed

+261
-103
lines changed

12 files changed

+261
-103
lines changed

README.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,18 @@ The items were taken from the official SQLite documentation
5858

5959
### Advanced statements
6060

61-
#### SELECT Statement ![progress](https://progress-bar.xyz/0/?scale=8&suffix=%%%20(0%20of%208)&width=140)
61+
#### SELECT Statement ![progress](https://progress-bar.xyz/0/?scale=9&suffix=%%%20(0%20of%209)&width=140)
6262

6363
1. [result-columns](https://www.sqlite.org/syntax/result-column.html)
6464
1. [table-or-subquery](https://www.sqlite.org/lang_select.html#tablename)
6565
1. [join-clauses](https://www.sqlite.org/syntax/join-clause.html)
6666
1. [where-group-by-having-clause](https://www.sqlite.org/lang_select.html#where)
67-
1. [window-functions-part](https://www.sqlite.org/syntax/window-defn.html)
67+
1. [window-functions](https://www.sqlite.org/syntax/window-defn.html)
68+
1. [select-core-stmt](https://www.sqlite.org/syntax/select-core.html)
69+
1. [values-stmt](https://www.sqlite.org/syntax/select-core.html)
70+
1. [with-compound-stmt](https://www.sqlite.org/syntax/factored-select-stmt.html)
6871
1. [order-by-and-limit-clause](https://www.sqlite.org/lang_select.html#orderby)
6972
1. [common-table-expressions](https://www.sqlite.org/syntax/common-table-expression.html)
70-
1. [select-stmt](https://www.sqlite.org/syntax/select-stmt.html)
7173

7274
#### DELETE Statements ![progress](https://progress-bar.xyz/0/?scale=2&suffix=%%%20(0%20of%202)&width=140)
7375
1. [delete-stmt](https://www.sqlite.org/syntax/delete-stmt.html)

src/ast/cte.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use super::{Identifier, SelectStatement, Statement};
2+
3+
/// An AST for [WITH](https://www.sqlite.org/lang_with.html) SQL statement.
4+
/// The WITH statement is used in SELECT, INSERT, UPDATE, and DELETE
5+
/// statements to define Common Table Expressions (CTEs).
6+
#[derive(Debug, PartialEq)]
7+
pub struct WithCteStatement {
8+
pub cte_name: String,
9+
10+
pub recursive: bool,
11+
12+
pub cte_expressions: Vec<CteExpression>,
13+
14+
pub statement: Statement,
15+
}
16+
17+
/// An AST for a single CTE expression.
18+
#[derive(Debug, PartialEq)]
19+
pub struct CteExpression {
20+
pub name: Identifier,
21+
22+
pub column_names: Vec<Identifier>,
23+
24+
pub materialized: Option<bool>,
25+
26+
pub select: Vec<SelectStatement>,
27+
}

src/ast/expression.rs

+6-19
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::fmt::Display;
22

33
use crate::{ParsingError, TokenType};
44

5-
use super::{Ordering, SelectStatement};
5+
use super::{OrderingTerm, SelectStatementType};
66

77
/// An SQLite3 [expr](https://www.sqlite.org/lang_expr.html) expression
88
#[derive(Debug, PartialEq, Clone)]
@@ -206,7 +206,7 @@ pub struct Function {
206206
/// The filter clause of the function
207207
pub filter_clause: Option<Box<Expression>>,
208208
/// The over clause of the function
209-
pub over_clause: Option<OverClause>,
209+
pub over_clause: Option<WindowDefinition>,
210210
}
211211

212212
/// A function argument
@@ -231,7 +231,7 @@ pub enum FunctionArgType {
231231

232232
/// An over clause
233233
#[derive(Debug, PartialEq, Clone, Default)]
234-
pub struct OverClause {
234+
pub struct WindowDefinition {
235235
/// The window name
236236
pub window_name: Option<String>,
237237
/// The partition by clause
@@ -242,19 +242,6 @@ pub struct OverClause {
242242
pub frame_spec: Option<FrameSpec>,
243243
}
244244

245-
/// An ordering term
246-
/// Possible collation name will be parsed, and will be stored in the
247-
/// expression field
248-
#[derive(Debug, PartialEq, Clone)]
249-
pub struct OrderingTerm {
250-
/// The expression to order by
251-
pub expression: Box<Expression>,
252-
/// The ordering
253-
pub ordering: Option<Ordering>,
254-
/// The nulls ordering
255-
pub nulls_ordering: Option<NullsOrdering>,
256-
}
257-
258245
/// Nulls ordering
259246
#[derive(Debug, PartialEq, Clone)]
260247
pub enum NullsOrdering {
@@ -430,7 +417,7 @@ pub enum InExpression {
430417
Empty,
431418

432419
/// Select
433-
Select(SelectStatement),
420+
Select(SelectStatementType),
434421

435422
/// Expressions
436423
Expression(Vec<Expression>),
@@ -446,10 +433,10 @@ pub enum InExpression {
446433
#[derive(Debug, PartialEq, Clone)]
447434
pub enum ExistsStatement {
448435
/// Exists
449-
Exists(SelectStatement),
436+
Exists(SelectStatementType),
450437

451438
/// Not Exists
452-
NotExists(SelectStatement),
439+
NotExists(SelectStatementType),
453440
}
454441

455442
/// A case expression

src/ast/mod.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod alter;
22
mod create;
3+
mod cte;
34
mod delete;
45
mod drop;
56
mod explain;
@@ -39,7 +40,7 @@ pub use update::UpdateStatement;
3940
#[derive(Debug, PartialEq)]
4041
pub enum Statement {
4142
/// Data Query Language (DQL), see [SelectStatement]
42-
Select(SelectStatement),
43+
Select(SelectStatementType),
4344

4445
/// Data Manipulation Language (DML), see [InsertStatement]
4546
Insert(InsertStatement),
@@ -97,6 +98,17 @@ pub enum Statement {
9798
Explain(ExplainStatement),
9899
}
99100

101+
/// An ordering term, used in the ORDER BY clause
102+
#[derive(Debug, PartialEq, Clone)]
103+
pub struct OrderingTerm {
104+
/// The expression to order by
105+
pub expression: Box<Expression>,
106+
/// The ordering
107+
pub ordering: Option<Ordering>,
108+
/// The nulls ordering
109+
pub nulls_ordering: Option<NullsOrdering>,
110+
}
111+
100112
/// An ordering
101113
#[derive(Debug, PartialEq, Clone)]
102114
pub enum Ordering {

src/ast/select.rs

+77-21
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
1-
use super::Expression;
1+
use super::{Expression, Identifier, OrderingTerm, WindowDefinition};
2+
3+
/// An enum representing the possible types of SELECT statements
4+
#[derive(Debug, PartialEq, Clone)]
5+
pub enum SelectStatementType {
6+
/// A normal SELECT statement
7+
Select(SelectStatement),
8+
/// A VALUES statement
9+
Values(ValuesStatement),
10+
}
211

312
/// An AST for [SELECT](https://www.sqlite.org/lang_select.html) SQL statement.
413
#[derive(Debug, PartialEq, Default, Clone)]
514
pub struct SelectStatement {
15+
/// Whether the SELECT statement is a VALUES statement
16+
pub values: bool,
17+
618
/// Whether the SELECT statement is distinct
719
pub distinct: bool,
820

@@ -14,10 +26,24 @@ pub struct SelectStatement {
1426

1527
/// The FROM clause
1628
pub from: Option<SelectFrom>,
17-
// pub where_clause: Option<Expression>,
18-
// pub order_by: Option<OrderBy>,
19-
// pub limit: Option<Expression>,
20-
// pub offset: Option<Expression>,
29+
30+
/// The WHERE clause
31+
pub where_clause: Option<Box<Expression>>,
32+
33+
/// The GROUP BY clause
34+
pub group_by: Option<Vec<Box<Expression>>>,
35+
36+
/// The HAVING clause
37+
pub having: Option<Box<Expression>>,
38+
39+
/// The WINDOW clause
40+
pub window: Option<Vec<WindowDefinition>>,
41+
42+
/// The ORDER BY clause
43+
pub order_by: Option<OrderingTerm>,
44+
45+
/// The LIMIT clause
46+
pub limit: Option<LimitClause>,
2147
}
2248

2349
/// An enum representing the possible items in a SELECT statement
@@ -53,19 +79,26 @@ pub enum SelectFrom {
5379
/// A table in a FROM clause
5480
#[derive(Debug, PartialEq, Clone)]
5581
pub struct SelectFromTable {
56-
pub schema: Option<String>,
57-
pub table_name: String,
82+
pub table_id: Identifier,
83+
5884
pub alias: Option<String>,
5985

60-
pub indexed_by: Option<String>,
61-
pub not_indexed: Option<bool>,
86+
pub indexed_type: Option<IndexedType>,
87+
}
88+
89+
/// An enum representing the possible indexed types
90+
#[derive(Debug, PartialEq, Clone)]
91+
pub enum IndexedType {
92+
/// Indexed by a specific index
93+
Indexed(String),
94+
/// Not indexed
95+
NotIndexed,
6296
}
6397

6498
/// A function in a FROM clause
6599
#[derive(Debug, PartialEq, Clone)]
66100
pub struct SelectFromFunction {
67-
pub schema: Option<String>,
68-
pub function_name: String,
101+
pub function_name: Identifier,
69102
pub arguments: Vec<Expression>,
70103
pub alias: Option<String>,
71104
}
@@ -81,24 +114,32 @@ pub struct SelectFromSubquery {
81114
#[derive(Debug, PartialEq, Clone)]
82115
pub struct JoinClause {
83116
pub lhs_table: Box<SelectFrom>,
117+
118+
pub join_tables: Vec<JoinTable>,
119+
}
120+
121+
/// A table in a JOIN clause
122+
#[derive(Debug, PartialEq, Clone)]
123+
pub struct JoinTable {
84124
pub join_type: JoinType,
85-
pub rhs_table: Box<SelectFrom>,
86-
pub join_constraints: Vec<JoinConstraint>,
125+
pub table: Box<SelectFrom>,
126+
pub constraints: JoinConstraint,
87127
}
88128

129+
/// A type alias for the `NATURAL` keyword in a JOIN clause
130+
pub type IsNaturalJoin = bool;
131+
89132
/// A type of JOIN clause
90133
#[derive(Debug, PartialEq, Clone)]
91134
pub enum JoinType {
92-
/// INNER JOIN
93-
Inner,
94135
/// LEFT JOIN
95-
Left,
136+
Left(IsNaturalJoin),
96137
/// RIGHT JOIN
97-
Right,
98-
/// NATURAL JOIN
99-
Natural(Box<JoinType>),
100-
/// OUTER JOIN (LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN)
101-
Outer(Box<JoinType>),
138+
Right(IsNaturalJoin),
139+
/// FULL JOIN
140+
Full(IsNaturalJoin),
141+
/// INNER JOIN
142+
Inner(IsNaturalJoin),
102143
/// CROSS JOIN
103144
Cross,
104145
}
@@ -111,3 +152,18 @@ pub enum JoinConstraint {
111152
/// USING clause
112153
Using(Vec<String>),
113154
}
155+
156+
/// A clause for a LIMIT statement
157+
#[derive(Debug, PartialEq, Clone)]
158+
pub struct LimitClause {
159+
pub limit: Box<Expression>,
160+
pub offset: Option<Box<Expression>>,
161+
pub additional_limit: Option<Box<Expression>>,
162+
}
163+
164+
/// A VALUES statement
165+
#[derive(Debug, PartialEq, Clone)]
166+
pub struct ValuesStatement {
167+
/// The list of values in a VALUES statement grouped by parenthesis
168+
pub values: Vec<Vec<Expression>>,
169+
}

src/parser/expression/exists_expr.rs

+19-19
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,28 @@ impl<'a> ExistsExpressionParser for Parser<'a> {
3333

3434
#[cfg(test)]
3535
mod exists_expression_tests {
36-
use crate::{SelectItem, SelectStatement};
36+
use crate::{SelectItem, SelectStatement, SelectStatementType};
3737

3838
use crate::parser::expression::test_utils::*;
3939

40+
fn select_statement(columns: Vec<SelectItem>) -> SelectStatementType {
41+
SelectStatementType::Select(SelectStatement {
42+
distinct: false,
43+
all: false,
44+
columns,
45+
..Default::default()
46+
})
47+
}
48+
4049
#[test]
4150
fn test_expression_exists() {
4251
run_sunny_day_test(
4352
"SELECT EXISTS (SELECT 1);",
4453
&exist_expression(
4554
false,
46-
SelectStatement {
47-
distinct: false,
48-
all: false,
49-
columns: vec![SelectItem::Expression(numeric_literal_expression("1"))],
50-
from: None,
51-
},
55+
select_statement(vec![SelectItem::Expression(numeric_literal_expression(
56+
"1",
57+
))]),
5258
),
5359
);
5460
}
@@ -59,12 +65,9 @@ mod exists_expression_tests {
5965
"SELECT NOT EXISTS (SELECT 1);",
6066
&exist_expression(
6167
true,
62-
SelectStatement {
63-
distinct: false,
64-
all: false,
65-
columns: vec![SelectItem::Expression(numeric_literal_expression("1"))],
66-
from: None,
67-
},
68+
select_statement(vec![SelectItem::Expression(numeric_literal_expression(
69+
"1",
70+
))]),
6871
),
6972
);
7073
}
@@ -75,12 +78,9 @@ mod exists_expression_tests {
7578
"SELECT NOT (SELECT 21);",
7679
&exist_expression(
7780
true,
78-
SelectStatement {
79-
distinct: false,
80-
all: false,
81-
columns: vec![SelectItem::Expression(numeric_literal_expression("21"))],
82-
from: None,
83-
},
81+
select_statement(vec![SelectItem::Expression(numeric_literal_expression(
82+
"21",
83+
))]),
8484
),
8585
);
8686
}

0 commit comments

Comments
 (0)