Skip to content

Commit f42952e

Browse files
committed
Parse the MSSQL DECLARE statement in a more rustc-like manner
1 parent 258645a commit f42952e

File tree

1 file changed

+50
-44
lines changed

1 file changed

+50
-44
lines changed

src/parser/mod.rs

+50-44
Original file line numberDiff line numberDiff line change
@@ -5311,55 +5311,61 @@ impl<'a> Parser<'a> {
53115311
/// ```
53125312
/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-local-variable-transact-sql?view=sql-server-ver16
53135313
pub fn parse_mssql_declare(&mut self) -> Result<Statement, ParserError> {
5314-
let mut stmts = vec![];
5315-
5316-
loop {
5317-
let name = {
5318-
let ident = self.parse_identifier(false)?;
5319-
if !ident.value.starts_with('@') {
5320-
Err(ParserError::TokenizerError(
5321-
"Invalid MsSql variable declaration.".to_string(),
5322-
))
5323-
} else {
5324-
Ok(ident)
5325-
}
5326-
}?;
5314+
let stmts = self.parse_comma_separated(Parser::parse_mssql_declare_stmt)?;
53275315

5328-
let (declare_type, data_type) = match self.peek_token().token {
5329-
Token::Word(w) => match w.keyword {
5330-
Keyword::CURSOR => {
5331-
self.next_token();
5332-
(Some(DeclareType::Cursor), None)
5333-
}
5334-
Keyword::AS => {
5335-
self.next_token();
5336-
(None, Some(self.parse_data_type()?))
5337-
}
5338-
_ => (None, Some(self.parse_data_type()?)),
5339-
},
5340-
_ => (None, Some(self.parse_data_type()?)),
5341-
};
5316+
Ok(Statement::Declare { stmts })
5317+
}
53425318

5343-
let assignment = self.parse_mssql_variable_declaration_expression()?;
5319+
/// Parse the body of a [MsSql] `DECLARE`statement.
5320+
///
5321+
/// Syntax:
5322+
/// ```text
5323+
// {
5324+
// { @local_variable [AS] data_type [ = value ] }
5325+
// | { @cursor_variable_name CURSOR }
5326+
// } [ ,...n ]
5327+
/// ```
5328+
/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-local-variable-transact-sql?view=sql-server-ver16
5329+
pub fn parse_mssql_declare_stmt(&mut self) -> Result<Declare, ParserError> {
5330+
let name = {
5331+
let ident = self.parse_identifier(false)?;
5332+
if !ident.value.starts_with('@') {
5333+
Err(ParserError::TokenizerError(
5334+
"Invalid MsSql variable declaration.".to_string(),
5335+
))
5336+
} else {
5337+
Ok(ident)
5338+
}
5339+
}?;
53445340

5345-
stmts.push(Declare {
5346-
names: vec![name],
5347-
data_type,
5348-
assignment,
5349-
declare_type,
5350-
binary: None,
5351-
sensitive: None,
5352-
scroll: None,
5353-
hold: None,
5354-
for_query: None,
5355-
});
5341+
let (declare_type, data_type) = match self.peek_token().token {
5342+
Token::Word(w) => match w.keyword {
5343+
Keyword::CURSOR => {
5344+
self.next_token();
5345+
(Some(DeclareType::Cursor), None)
5346+
}
5347+
Keyword::AS => {
5348+
self.next_token();
5349+
(None, Some(self.parse_data_type()?))
5350+
}
5351+
_ => (None, Some(self.parse_data_type()?)),
5352+
},
5353+
_ => (None, Some(self.parse_data_type()?)),
5354+
};
53565355

5357-
if self.peek_token().token == Token::SemiColon || self.next_token() != Token::Comma {
5358-
break;
5359-
}
5360-
}
5356+
let assignment = self.parse_mssql_variable_declaration_expression()?;
53615357

5362-
Ok(Statement::Declare { stmts })
5358+
Ok(Declare {
5359+
names: vec![name],
5360+
data_type,
5361+
assignment,
5362+
declare_type,
5363+
binary: None,
5364+
sensitive: None,
5365+
scroll: None,
5366+
hold: None,
5367+
for_query: None,
5368+
})
53635369
}
53645370

53655371
/// Parses the assigned expression in a variable declaration.

0 commit comments

Comments
 (0)