@@ -4277,6 +4277,9 @@ impl<'a> Parser<'a> {
4277
4277
if dialect_of ! ( self is SnowflakeDialect ) {
4278
4278
return self . parse_snowflake_declare ( ) ;
4279
4279
}
4280
+ if dialect_of ! ( self is MsSqlDialect ) {
4281
+ return self . parse_mssql_declare ( ) ;
4282
+ }
4280
4283
4281
4284
let name = self . parse_identifier ( false ) ?;
4282
4285
@@ -4490,6 +4493,69 @@ impl<'a> Parser<'a> {
4490
4493
Ok ( Statement :: Declare { stmts } )
4491
4494
}
4492
4495
4496
+ /// Parse a [MsSql] `DECLARE` statement.
4497
+ ///
4498
+ /// Syntax:
4499
+ /// ```text
4500
+ /// DECLARE
4501
+ // {
4502
+ // { @local_variable [AS] data_type [ = value ] }
4503
+ // | { @cursor_variable_name CURSOR }
4504
+ // } [ ,...n ]
4505
+ /// ```
4506
+ /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-local-variable-transact-sql?view=sql-server-ver16
4507
+ pub fn parse_mssql_declare ( & mut self ) -> Result < Statement , ParserError > {
4508
+ let mut stmts = vec ! [ ] ;
4509
+
4510
+ loop {
4511
+ let name = {
4512
+ let ident = self . parse_identifier ( false ) ?;
4513
+ if !ident. value . starts_with ( '@' ) {
4514
+ Err ( ParserError :: TokenizerError (
4515
+ "Invalid MsSql variable declaration." . to_string ( ) ,
4516
+ ) )
4517
+ } else {
4518
+ Ok ( ident)
4519
+ }
4520
+ } ?;
4521
+
4522
+ let ( declare_type, data_type) = match self . peek_token ( ) . token {
4523
+ Token :: Word ( w) => match w. keyword {
4524
+ Keyword :: CURSOR => {
4525
+ self . next_token ( ) ;
4526
+ ( Some ( DeclareType :: Cursor ) , None )
4527
+ }
4528
+ Keyword :: AS => {
4529
+ self . next_token ( ) ;
4530
+ ( None , Some ( self . parse_data_type ( ) ?) )
4531
+ }
4532
+ _ => ( None , Some ( self . parse_data_type ( ) ?) ) ,
4533
+ } ,
4534
+ _ => ( None , Some ( self . parse_data_type ( ) ?) ) ,
4535
+ } ;
4536
+
4537
+ let assignment = self . parse_mssql_variable_declaration_expression ( ) ?;
4538
+
4539
+ stmts. push ( Declare {
4540
+ names : vec ! [ name] ,
4541
+ data_type,
4542
+ assignment,
4543
+ declare_type,
4544
+ binary : None ,
4545
+ sensitive : None ,
4546
+ scroll : None ,
4547
+ hold : None ,
4548
+ for_query : None ,
4549
+ } ) ;
4550
+
4551
+ if self . next_token ( ) != Token :: Comma {
4552
+ break ;
4553
+ }
4554
+ }
4555
+
4556
+ Ok ( Statement :: Declare { stmts } )
4557
+ }
4558
+
4493
4559
/// Parses the assigned expression in a variable declaration.
4494
4560
///
4495
4561
/// Syntax:
@@ -4515,6 +4581,26 @@ impl<'a> Parser<'a> {
4515
4581
} )
4516
4582
}
4517
4583
4584
+ /// Parses the assigned expression in a variable declaration.
4585
+ ///
4586
+ /// Syntax:
4587
+ /// ```text
4588
+ /// [ = <expression>]
4589
+ /// ```
4590
+ pub fn parse_mssql_variable_declaration_expression (
4591
+ & mut self ,
4592
+ ) -> Result < Option < DeclareAssignment > , ParserError > {
4593
+ Ok ( match self . peek_token ( ) . token {
4594
+ Token :: Eq => {
4595
+ self . next_token ( ) ; // Skip `=`
4596
+ Some ( DeclareAssignment :: MsSqlAssignment ( Box :: new (
4597
+ self . parse_expr ( ) ?,
4598
+ ) ) )
4599
+ }
4600
+ _ => None ,
4601
+ } )
4602
+ }
4603
+
4518
4604
// FETCH [ direction { FROM | IN } ] cursor INTO target;
4519
4605
pub fn parse_fetch_statement ( & mut self ) -> Result < Statement , ParserError > {
4520
4606
let direction = if self . parse_keyword ( Keyword :: NEXT ) {
0 commit comments