1
1
use crate :: parser:: errors:: ParsingError ;
2
2
use crate :: {
3
- parser:: select:: SelectStatementParser , BinaryMatchingExpression , Expression , Identifier ,
4
- InExpression , Keyword , Parser , TokenType ,
3
+ parser:: select:: SelectStatementParser , Expression , InExpression , Keyword , Parser , TokenType ,
5
4
} ;
5
+ use crate :: { IdentifierParser , InExpressionType } ;
6
6
7
7
use super :: ExpressionParser ;
8
8
@@ -13,6 +13,11 @@ pub trait InExpressionParser {
13
13
expression : Expression ,
14
14
is_not : bool ,
15
15
) -> Result < Expression , ParsingError > ;
16
+
17
+ fn parse_in_expression_within_parenthesis ( & mut self ) -> Result < InExpressionType , ParsingError > ;
18
+
19
+ fn parse_in_expression_without_parenthesis ( & mut self )
20
+ -> Result < InExpressionType , ParsingError > ;
16
21
}
17
22
18
23
impl InExpressionParser for Parser < ' _ > {
@@ -24,61 +29,57 @@ impl InExpressionParser for Parser<'_> {
24
29
self . consume_as_keyword ( Keyword :: In ) ?;
25
30
26
31
let in_expression = if self . peek_as ( TokenType :: LeftParen ) . is_ok ( ) {
27
- // Consume the left parenthesis
28
- self . consume_as ( TokenType :: LeftParen ) ?;
32
+ self . parse_in_expression_within_parenthesis ( ) ?
33
+ } else {
34
+ self . parse_in_expression_without_parenthesis ( ) ?
35
+ } ;
29
36
30
- let result = if self . peek_as ( TokenType :: RightParen ) . is_ok ( ) {
31
- BinaryMatchingExpression :: In ( InExpression :: Empty )
32
- } else if let Ok ( Keyword :: Select ) = self . peek_as_keyword ( ) {
33
- // The IN expression is a subquery
34
- let select_statement = self . parse_select_statement ( ) ?;
35
- BinaryMatchingExpression :: In ( InExpression :: Select ( select_statement) )
36
- } else {
37
- let expressions = self . parse_comma_separated_expressions ( ) ?;
38
- BinaryMatchingExpression :: In ( InExpression :: Expression ( expressions) )
39
- } ;
37
+ Ok ( Expression :: InExpression ( InExpression {
38
+ expression : Box :: new ( expression) ,
39
+ in_expression,
40
+ is_not,
41
+ } ) )
42
+ }
40
43
41
- // Consume the enclosing right parenthesis
42
- self . consume_as ( TokenType :: RightParen ) ?;
43
- result
44
- } else {
45
- // Parse expressions like $expr IN $schema.table or schema.function(*args)
46
- let id1 = self . peek_as_id ( ) ?;
47
- self . consume_as_id ( ) ?;
44
+ fn parse_in_expression_within_parenthesis ( & mut self ) -> Result < InExpressionType , ParsingError > {
45
+ // Consume the left parenthesis
46
+ self . consume_as ( TokenType :: LeftParen ) ?;
48
47
49
- let identifier = if self . consume_as ( TokenType :: Dot ) . is_ok ( ) {
50
- let id2 = self . peek_as_id ( ) ?;
51
- self . consume_as_id ( ) ?;
52
- Identifier :: Compound ( vec ! [ id1. to_string( ) , id2. to_string( ) ] )
53
- } else {
54
- Identifier :: Single ( id1. to_string ( ) )
55
- } ;
48
+ let result = if self . peek_as ( TokenType :: RightParen ) . is_ok ( ) {
49
+ InExpressionType :: Empty
50
+ } else if let Ok ( Keyword :: Select ) = self . peek_as_keyword ( ) {
51
+ // The IN expression is a subquery
52
+ let select_statement = self . parse_select_statement ( ) ?;
53
+ InExpressionType :: Select ( select_statement)
54
+ } else {
55
+ let expressions = self . parse_comma_separated_expressions ( ) ?;
56
+ InExpressionType :: Expression ( expressions)
57
+ } ;
56
58
57
- if self . consume_as ( TokenType :: LeftParen ) . is_ok ( ) {
58
- if self . consume_as ( TokenType :: RightParen ) . is_ok ( ) {
59
- BinaryMatchingExpression :: In ( InExpression :: TableFunction ( identifier, vec ! [ ] ) )
60
- } else {
61
- let args = self . parse_comma_separated_expressions ( ) ?;
59
+ // Consume the enclosing right parenthesis
60
+ self . consume_as ( TokenType :: RightParen ) ?;
61
+ Ok ( result)
62
+ }
62
63
63
- self . consume_as ( TokenType :: RightParen ) ?;
64
+ fn parse_in_expression_without_parenthesis (
65
+ & mut self ,
66
+ ) -> Result < InExpressionType , ParsingError > {
67
+ // Parse expressions like $expr IN $schema.table or $schema.function(*args)
68
+ let identifier = self . parse_identifier ( ) ?;
64
69
65
- BinaryMatchingExpression :: In ( InExpression :: TableFunction ( identifier, args) )
66
- }
70
+ if self . consume_as ( TokenType :: LeftParen ) . is_ok ( ) {
71
+ if self . consume_as ( TokenType :: RightParen ) . is_ok ( ) {
72
+ Ok ( InExpressionType :: TableFunction ( identifier, vec ! [ ] ) )
67
73
} else {
68
- BinaryMatchingExpression :: In ( InExpression :: Identity ( identifier) )
69
- }
70
- } ;
74
+ let args = self . parse_comma_separated_expressions ( ) ?;
71
75
72
- let in_expression = if is_not {
73
- BinaryMatchingExpression :: Not ( Box :: new ( in_expression) )
74
- } else {
75
- in_expression
76
- } ;
76
+ self . consume_as ( TokenType :: RightParen ) ?;
77
77
78
- Ok ( Expression :: BinaryMatchingExpression (
79
- Box :: new ( expression) ,
80
- in_expression,
81
- ) )
78
+ Ok ( InExpressionType :: TableFunction ( identifier, args) )
79
+ }
80
+ } else {
81
+ Ok ( InExpressionType :: Identity ( identifier) )
82
+ }
82
83
}
83
84
}
84
85
@@ -87,50 +88,53 @@ mod expression_with_in_statement_tests {
87
88
use crate :: parser:: test_utils:: run_sunny_day_test;
88
89
use crate :: select:: test_utils:: select_expr;
89
90
use crate :: {
90
- BinaryMatchingExpression , BinaryOp , Expression , Identifier , InExpression , Select ,
91
- SelectBody , SelectItem , SelectStatement ,
91
+ BinaryOp , Expression , Identifier , InExpression , InExpressionType , Select , SelectBody ,
92
+ SelectItem , SelectStatement ,
92
93
} ;
93
94
94
95
use crate :: parser:: expression:: test_utils:: * ;
95
96
96
- fn in_expr ( expression : Expression , in_expression : InExpression , is_not : bool ) -> Expression {
97
- let in_expression = if is_not {
98
- BinaryMatchingExpression :: Not ( Box :: new ( BinaryMatchingExpression :: In ( in_expression) ) )
99
- } else {
100
- BinaryMatchingExpression :: In ( in_expression)
101
- } ;
102
-
103
- Expression :: BinaryMatchingExpression ( Box :: new ( expression) , in_expression)
97
+ fn in_expr (
98
+ expression : Expression ,
99
+ in_expression : InExpressionType ,
100
+ is_not : bool ,
101
+ ) -> Expression {
102
+ Expression :: InExpression ( InExpression {
103
+ expression : Box :: new ( expression) ,
104
+ in_expression,
105
+ is_not,
106
+ } )
104
107
}
105
108
106
109
#[ test]
107
110
fn in_empty ( ) {
108
111
run_sunny_day_test (
109
112
"SELECT 1 IN ();" ,
110
- select_expr ( in_expr ( numeric_expr ( "1" ) , InExpression :: Empty , false ) ) . into ( ) ,
113
+ select_expr ( in_expr ( numeric_expr ( "1" ) , InExpressionType :: Empty , false ) ) . into ( ) ,
111
114
) ;
112
115
113
116
run_sunny_day_test (
114
117
"SELECT 1 NOT IN ();" ,
115
- select_expr ( in_expr ( numeric_expr ( "1" ) , InExpression :: Empty , true ) ) . into ( ) ,
118
+ select_expr ( in_expr ( numeric_expr ( "1" ) , InExpressionType :: Empty , true ) ) . into ( ) ,
116
119
) ;
117
120
}
118
121
119
122
#[ test]
120
123
fn in_select ( ) {
121
- let mut select_statement = Select :: default ( ) ;
122
- select_statement. columns = vec ! [ SelectItem :: Expression ( numeric_expr( "2" ) ) ] ;
124
+ let mut select = Select :: default ( ) ;
125
+ select. columns = vec ! [ SelectItem :: Expression ( numeric_expr( "2" ) ) ] ;
126
+ let select_statement = SelectStatement {
127
+ with_cte : None ,
128
+ select : SelectBody :: Select ( select) ,
129
+ order_by : None ,
130
+ limit : None ,
131
+ } ;
123
132
124
133
run_sunny_day_test (
125
134
"SELECT 1 IN (SELECT 2);" ,
126
135
select_expr ( in_expr (
127
136
numeric_expr ( "1" ) ,
128
- InExpression :: Select ( SelectStatement {
129
- with_cte : None ,
130
- select : SelectBody :: Select ( select_statement) ,
131
- order_by : None ,
132
- limit : None ,
133
- } ) ,
137
+ InExpressionType :: Select ( select_statement) ,
134
138
false ,
135
139
) )
136
140
. into ( ) ,
@@ -143,7 +147,7 @@ mod expression_with_in_statement_tests {
143
147
"SELECT 1 IN (2, 3, 4 + 5);" ,
144
148
select_expr ( in_expr (
145
149
numeric_expr ( "1" ) ,
146
- InExpression :: Expression ( vec ! [
150
+ InExpressionType :: Expression ( vec ! [
147
151
numeric_expr( "2" ) ,
148
152
numeric_expr( "3" ) ,
149
153
binary_op( BinaryOp :: Plus , numeric_expr( "4" ) , numeric_expr( "5" ) ) ,
@@ -156,19 +160,21 @@ mod expression_with_in_statement_tests {
156
160
157
161
#[ test]
158
162
fn not_in_select ( ) {
159
- let mut select_statement = Select :: default ( ) ;
160
- select_statement. columns = vec ! [ SelectItem :: Expression ( numeric_expr( "2" ) ) ] ;
163
+ let mut select = Select :: default ( ) ;
164
+ select. columns = vec ! [ SelectItem :: Expression ( numeric_expr( "2" ) ) ] ;
165
+
166
+ let select_statement = SelectStatement {
167
+ with_cte : None ,
168
+ select : SelectBody :: Select ( select) ,
169
+ order_by : None ,
170
+ limit : None ,
171
+ } ;
161
172
162
173
run_sunny_day_test (
163
174
"SELECT 1 NOT IN (SELECT 2);" ,
164
175
select_expr ( in_expr (
165
176
numeric_expr ( "1" ) ,
166
- InExpression :: Select ( SelectStatement {
167
- with_cte : None ,
168
- select : SelectBody :: Select ( select_statement) ,
169
- order_by : None ,
170
- limit : None ,
171
- } ) ,
177
+ InExpressionType :: Select ( select_statement) ,
172
178
true ,
173
179
) )
174
180
. into ( ) ,
@@ -181,7 +187,7 @@ mod expression_with_in_statement_tests {
181
187
"SELECT 1 NOT IN table_name;" ,
182
188
select_expr ( in_expr (
183
189
numeric_expr ( "1" ) ,
184
- InExpression :: Identity ( Identifier :: Single ( "table_name" . to_string ( ) ) ) ,
190
+ InExpressionType :: Identity ( Identifier :: Single ( "table_name" . to_string ( ) ) ) ,
185
191
true ,
186
192
) )
187
193
. into ( ) ,
@@ -194,7 +200,7 @@ mod expression_with_in_statement_tests {
194
200
"SELECT 1 NOT IN schema_name.table_name;" ,
195
201
select_expr ( in_expr (
196
202
numeric_expr ( "1" ) ,
197
- InExpression :: Identity ( Identifier :: Compound ( vec ! [
203
+ InExpressionType :: Identity ( Identifier :: Compound ( vec ! [
198
204
"schema_name" . to_string( ) ,
199
205
"table_name" . to_string( ) ,
200
206
] ) ) ,
@@ -210,7 +216,7 @@ mod expression_with_in_statement_tests {
210
216
"SELECT 1 NOT IN schema_name.table_function();" ,
211
217
select_expr ( in_expr (
212
218
numeric_expr ( "1" ) ,
213
- InExpression :: TableFunction (
219
+ InExpressionType :: TableFunction (
214
220
Identifier :: Compound ( vec ! [
215
221
"schema_name" . to_string( ) ,
216
222
"table_function" . to_string( ) ,
@@ -229,7 +235,7 @@ mod expression_with_in_statement_tests {
229
235
"SELECT 1 NOT IN schema_name.table_function(1, 2, 3);" ,
230
236
select_expr ( in_expr (
231
237
numeric_expr ( "1" ) ,
232
- InExpression :: TableFunction (
238
+ InExpressionType :: TableFunction (
233
239
Identifier :: Compound ( vec ! [
234
240
"schema_name" . to_string( ) ,
235
241
"table_function" . to_string( ) ,
@@ -248,7 +254,7 @@ mod expression_with_in_statement_tests {
248
254
"SELECT 1 NOT IN table_function(1+2, 3*4);" ,
249
255
select_expr ( in_expr (
250
256
numeric_expr ( "1" ) ,
251
- InExpression :: TableFunction (
257
+ InExpressionType :: TableFunction (
252
258
Identifier :: Single ( "table_function" . to_string ( ) ) ,
253
259
vec ! [
254
260
binary_op( BinaryOp :: Plus , numeric_expr( "1" ) , numeric_expr( "2" ) ) ,
0 commit comments