File tree 5 files changed +77
-10
lines changed
5 files changed +77
-10
lines changed Original file line number Diff line number Diff line change @@ -786,7 +786,11 @@ pub enum Statement {
786
786
/// `{ BEGIN [ TRANSACTION | WORK ] | START TRANSACTION } ...`
787
787
StartTransaction { modes : Vec < TransactionMode > } ,
788
788
/// `SET TRANSACTION ...`
789
- SetTransaction { modes : Vec < TransactionMode > } ,
789
+ SetTransaction {
790
+ modes : Vec < TransactionMode > ,
791
+ snapshot : Option < Value > ,
792
+ session : bool ,
793
+ } ,
790
794
/// `COMMIT [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]`
791
795
Commit { chain : bool } ,
792
796
/// `ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]`
@@ -1369,11 +1373,22 @@ impl fmt::Display for Statement {
1369
1373
}
1370
1374
Ok ( ( ) )
1371
1375
}
1372
- Statement :: SetTransaction { modes } => {
1373
- write ! ( f, "SET TRANSACTION" ) ?;
1376
+ Statement :: SetTransaction {
1377
+ modes,
1378
+ snapshot,
1379
+ session,
1380
+ } => {
1381
+ if * session {
1382
+ write ! ( f, "SET SESSION CHARACTERISTICS AS TRANSACTION" ) ?;
1383
+ } else {
1384
+ write ! ( f, "SET TRANSACTION" ) ?;
1385
+ }
1374
1386
if !modes. is_empty ( ) {
1375
1387
write ! ( f, " {}" , display_comma_separated( modes) ) ?;
1376
1388
}
1389
+ if let Some ( snapshot_id) = snapshot {
1390
+ write ! ( f, " SNAPSHOT {}" , snapshot_id) ?;
1391
+ }
1377
1392
Ok ( ( ) )
1378
1393
}
1379
1394
Statement :: Commit { chain } => {
Original file line number Diff line number Diff line change @@ -412,6 +412,7 @@ define_keywords!(
412
412
SHOW ,
413
413
SIMILAR ,
414
414
SMALLINT ,
415
+ SNAPSHOT ,
415
416
SOME ,
416
417
SORT ,
417
418
SPECIFIC ,
Original file line number Diff line number Diff line change @@ -2670,9 +2670,26 @@ impl<'a> Parser<'a> {
2670
2670
value : values,
2671
2671
} ) ;
2672
2672
}
2673
+ } else if variable. value == "CHARACTERISTICS" {
2674
+ self . expect_keywords ( & [ Keyword :: AS , Keyword :: TRANSACTION ] ) ?;
2675
+ Ok ( Statement :: SetTransaction {
2676
+ modes : self . parse_transaction_modes ( ) ?,
2677
+ snapshot : None ,
2678
+ session : true ,
2679
+ } )
2673
2680
} else if variable. value == "TRANSACTION" && modifier. is_none ( ) {
2681
+ if self . parse_keyword ( Keyword :: SNAPSHOT ) {
2682
+ let snaphot_id = self . parse_value ( ) ?;
2683
+ return Ok ( Statement :: SetTransaction {
2684
+ modes : vec ! [ ] ,
2685
+ snapshot : Some ( snaphot_id) ,
2686
+ session : false ,
2687
+ } ) ;
2688
+ }
2674
2689
Ok ( Statement :: SetTransaction {
2675
2690
modes : self . parse_transaction_modes ( ) ?,
2691
+ snapshot : None ,
2692
+ session : false ,
2676
2693
} )
2677
2694
} else {
2678
2695
self . expected ( "equals sign or TO" , self . peek_token ( ) )
Original file line number Diff line number Diff line change @@ -3586,14 +3586,22 @@ fn parse_set_transaction() {
3586
3586
// TRANSACTION, so no need to duplicate the tests here. We just do a quick
3587
3587
// sanity check.
3588
3588
match verified_stmt ( "SET TRANSACTION READ ONLY, READ WRITE, ISOLATION LEVEL SERIALIZABLE" ) {
3589
- Statement :: SetTransaction { modes } => assert_eq ! (
3589
+ Statement :: SetTransaction {
3590
3590
modes,
3591
- vec![
3592
- TransactionMode :: AccessMode ( TransactionAccessMode :: ReadOnly ) ,
3593
- TransactionMode :: AccessMode ( TransactionAccessMode :: ReadWrite ) ,
3594
- TransactionMode :: IsolationLevel ( TransactionIsolationLevel :: Serializable ) ,
3595
- ]
3596
- ) ,
3591
+ session,
3592
+ snapshot,
3593
+ } => {
3594
+ assert_eq ! (
3595
+ modes,
3596
+ vec![
3597
+ TransactionMode :: AccessMode ( TransactionAccessMode :: ReadOnly ) ,
3598
+ TransactionMode :: AccessMode ( TransactionAccessMode :: ReadWrite ) ,
3599
+ TransactionMode :: IsolationLevel ( TransactionIsolationLevel :: Serializable ) ,
3600
+ ]
3601
+ ) ;
3602
+ assert ! ( !session) ;
3603
+ assert_eq ! ( snapshot, None ) ;
3604
+ }
3597
3605
_ => unreachable ! ( ) ,
3598
3606
}
3599
3607
}
Original file line number Diff line number Diff line change @@ -723,6 +723,32 @@ fn parse_map_access_expr() {
723
723
) ;
724
724
}
725
725
726
+ #[ test]
727
+ fn test_transaction_statement ( ) {
728
+ let statement = pg ( ) . verified_stmt ( "SET TRANSACTION SNAPSHOT '000003A1-1'" ) ;
729
+ assert_eq ! (
730
+ statement,
731
+ Statement :: SetTransaction {
732
+ modes: vec![ ] ,
733
+ snapshot: Some ( Value :: SingleQuotedString ( String :: from( "000003A1-1" ) ) ) ,
734
+ session: false
735
+ }
736
+ ) ;
737
+ let statement = pg ( ) . verified_stmt ( "SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY, READ WRITE, ISOLATION LEVEL SERIALIZABLE" ) ;
738
+ assert_eq ! (
739
+ statement,
740
+ Statement :: SetTransaction {
741
+ modes: vec![
742
+ TransactionMode :: AccessMode ( TransactionAccessMode :: ReadOnly ) ,
743
+ TransactionMode :: AccessMode ( TransactionAccessMode :: ReadWrite ) ,
744
+ TransactionMode :: IsolationLevel ( TransactionIsolationLevel :: Serializable ) ,
745
+ ] ,
746
+ snapshot: None ,
747
+ session: true
748
+ }
749
+ ) ;
750
+ }
751
+
726
752
fn pg ( ) -> TestedDialects {
727
753
TestedDialects {
728
754
dialects : vec ! [ Box :: new( PostgreSqlDialect { } ) ] ,
You can’t perform that action at this time.
0 commit comments