1
1
use crate :: {
2
- parser:: select:: SelectStatementParser , ConflictClause , Identifier , InsertStatement ,
3
- InsertValues , Keyword , QualifiedTableName , TokenType , UpsertAction , UpsertClause ,
4
- UpsertConflictTarget , UpsertUpdate ,
2
+ parser:: select:: SelectStatementParser , ConflictClause , Identifier , IndexedColumn ,
3
+ InsertStatement , InsertValues , Keyword , Ordering , QualifiedTableName , TokenType , UpsertAction ,
4
+ UpsertClause , UpsertConflictTarget , UpsertUpdate ,
5
5
} ;
6
6
7
7
use super :: {
@@ -29,6 +29,10 @@ pub trait InsertStatementParser {
29
29
) -> Result < Option < UpsertConflictTarget > , ParsingError > ;
30
30
31
31
fn parse_upsert_action ( & mut self ) -> Result < UpsertAction , ParsingError > ;
32
+
33
+ fn parse_indexed_column ( & mut self ) -> Result < IndexedColumn , ParsingError > ;
34
+
35
+ fn parse_ordering ( & mut self ) -> Result < Option < Ordering > , ParsingError > ;
32
36
}
33
37
34
38
impl < ' a > InsertStatementParser for Parser < ' a > {
@@ -154,7 +158,7 @@ impl<'a> InsertStatementParser for Parser<'a> {
154
158
if self . consume_as ( TokenType :: LeftParen ) . is_ok ( ) {
155
159
let mut columns = vec ! [ ] ;
156
160
loop {
157
- columns. push ( self . parse_identifier ( ) ?) ;
161
+ columns. push ( self . parse_indexed_column ( ) ?) ;
158
162
if self . consume_as ( TokenType :: Comma ) . is_err ( ) {
159
163
break ;
160
164
}
@@ -194,6 +198,21 @@ impl<'a> InsertStatementParser for Parser<'a> {
194
198
self . peek_token ( ) ?. to_string ( ) ,
195
199
) )
196
200
}
201
+
202
+ fn parse_indexed_column ( & mut self ) -> Result < IndexedColumn , ParsingError > {
203
+ let column = self . parse_expression ( ) ?;
204
+ let ordering = self . parse_ordering ( ) ?;
205
+ Ok ( IndexedColumn { column, ordering } )
206
+ }
207
+
208
+ fn parse_ordering ( & mut self ) -> Result < Option < Ordering > , ParsingError > {
209
+ if self . consume_as_keyword ( Keyword :: Asc ) . is_ok ( ) {
210
+ return Ok ( Some ( Ordering :: Asc ) ) ;
211
+ } else if self . consume_as_keyword ( Keyword :: Desc ) . is_ok ( ) {
212
+ return Ok ( Some ( Ordering :: Desc ) ) ;
213
+ }
214
+ Ok ( None )
215
+ }
197
216
}
198
217
199
218
#[ cfg( test) ]
@@ -212,29 +231,23 @@ mod test_utils {
212
231
returning_clause : vec ! [ ] ,
213
232
}
214
233
}
215
-
216
- // pub fn insert_statement_with_values(values: InsertValues) -> InsertStatement {
217
- // let mut statement = insert_statement();
218
- // statement.values = values;
219
- // statement
220
- // }
221
234
}
222
235
223
236
#[ cfg( test) ]
224
237
mod tests_insert_statement {
225
238
use super :: test_utils:: * ;
226
239
use crate :: {
227
240
expression:: test_utils:: {
228
- binary_op_expression, expression_list, identifier_expression,
241
+ binary_op_expression, collate_expression , expression_list, identifier_expression,
229
242
numeric_literal_expression,
230
243
} ,
231
244
parser:: {
232
245
cte:: test_utils:: cte_expression, select:: test_utils:: select_from,
233
246
test_utils:: run_sunny_day_test,
234
247
} ,
235
- BinaryOp , ConflictClause , CteExpression , FromClause , Identifier , InsertValues ,
236
- QualifiedTableName , ReturningClause , SetClause , Statement , UpsertAction , UpsertClause ,
237
- UpsertConflictTarget , UpsertUpdate , WithCteStatement ,
248
+ BinaryOp , ConflictClause , CteExpression , FromClause , Identifier , IndexedColumn ,
249
+ InsertValues , QualifiedTableName , ReturningClause , SetClause , Statement , UpsertAction ,
250
+ UpsertClause , UpsertConflictTarget , UpsertUpdate , WithCteStatement ,
238
251
} ;
239
252
240
253
#[ test]
@@ -299,6 +312,7 @@ mod tests_insert_statement {
299
312
Identifier :: Single ( "col1" . to_string( ) ) ,
300
313
Identifier :: Single ( "col2" . to_string( ) ) ,
301
314
] ;
315
+
302
316
statement. values = InsertValues :: Values ( vec ! [
303
317
vec![
304
318
numeric_literal_expression( "1" ) ,
@@ -352,7 +366,7 @@ mod tests_insert_statement {
352
366
let sql = r#"
353
367
INSERT INTO table1 DEFAULT VALUES
354
368
ON CONFLICT (col1) DO NOTHING
355
- ON CONFLICT (col2)
369
+ ON CONFLICT (col2 COLLATE utf8 )
356
370
WHERE col2 > 10
357
371
DO UPDATE SET col2 = col2 + 1
358
372
ON CONFLICT (col3, col4)
@@ -365,14 +379,23 @@ mod tests_insert_statement {
365
379
expected_statement. upsert_clause = Some ( vec ! [
366
380
UpsertClause {
367
381
conflict_target: Some ( UpsertConflictTarget {
368
- columns: vec![ Identifier :: Single ( "col1" . to_string( ) ) ] ,
382
+ columns: vec![ IndexedColumn {
383
+ column: identifier_expression( & [ "col1" ] ) ,
384
+ ordering: None ,
385
+ } ] ,
369
386
where_clause: None ,
370
387
} ) ,
371
388
action: UpsertAction :: Nothing ,
372
389
} ,
373
390
UpsertClause {
374
391
conflict_target: Some ( UpsertConflictTarget {
375
- columns: vec![ Identifier :: Single ( "col2" . to_string( ) ) ] ,
392
+ columns: vec![ IndexedColumn {
393
+ column: collate_expression(
394
+ identifier_expression( & [ "col2" ] ) ,
395
+ "utf8" . to_string( ) ,
396
+ ) ,
397
+ ordering: None ,
398
+ } ] ,
376
399
where_clause: Some ( Box :: new( binary_op_expression(
377
400
BinaryOp :: GreaterThan ,
378
401
identifier_expression( & [ "col2" ] ) ,
@@ -394,8 +417,14 @@ mod tests_insert_statement {
394
417
UpsertClause {
395
418
conflict_target: Some ( UpsertConflictTarget {
396
419
columns: vec![
397
- Identifier :: Single ( "col3" . to_string( ) ) ,
398
- Identifier :: Single ( "col4" . to_string( ) ) ,
420
+ IndexedColumn {
421
+ column: identifier_expression( & [ "col3" ] ) ,
422
+ ordering: None ,
423
+ } ,
424
+ IndexedColumn {
425
+ column: identifier_expression( & [ "col4" ] ) ,
426
+ ordering: None ,
427
+ } ,
399
428
] ,
400
429
where_clause: Some ( Box :: new( binary_op_expression(
401
430
BinaryOp :: EqualsEquals ,
0 commit comments