@@ -1064,19 +1064,27 @@ impl<'a> Parser<'a> {
10641064 }
10651065
10661066 let stmt = if self.peek_keyword(Keyword::LET) {
1067- // LET var [data_type] := expr
10681067 self.next_token(); // consume LET
10691068 let name = self.parse_identifier()?;
1070- let data_type = match self.peek_token().token {
1071- Token::Assignment => None,
1072- _ => Some(self.parse_data_type()?),
1073- };
1074- self.expect_token(&Token::Assignment)?;
1075- let value = self.parse_expr()?;
1076- Statement::Let {
1077- name,
1078- data_type,
1079- value,
1069+ if self.peek_keyword(Keyword::CURSOR) || self.peek_keyword(Keyword::RESULTSET) {
1070+ // LET cur CURSOR FOR … / LET res RESULTSET := …
1071+ // Route into the same `Declare` shape the `DECLARE`
1072+ // spelling produces so the transform handles both alike.
1073+ let decl = self.parse_snowflake_declare_one(name)?;
1074+ Statement::Declare { stmts: vec![decl] }
1075+ } else {
1076+ // LET var [data_type] := expr
1077+ let data_type = match self.peek_token().token {
1078+ Token::Assignment => None,
1079+ _ => Some(self.parse_data_type()?),
1080+ };
1081+ self.expect_token(&Token::Assignment)?;
1082+ let value = self.parse_expr()?;
1083+ Statement::Let {
1084+ name,
1085+ data_type,
1086+ value,
1087+ }
10801088 }
10811089 } else if matches!(self.peek_nth_token_ref(0).token, Token::Word(_))
10821090 && self.peek_nth_token_ref(1).token == Token::Assignment
@@ -8081,71 +8089,7 @@ impl<'a> Parser<'a> {
80818089 let mut stmts = vec![];
80828090 loop {
80838091 let name = self.parse_identifier()?;
8084- let (declare_type, for_query, assigned_expr, data_type) =
8085- if self.parse_keyword(Keyword::CURSOR) {
8086- self.expect_keyword_is(Keyword::FOR)?;
8087- match &self.peek_token_ref().token {
8088- Token::Word(w) if w.keyword == Keyword::SELECT => (
8089- Some(DeclareType::Cursor),
8090- Some(self.parse_query()?),
8091- None,
8092- None,
8093- ),
8094- _ => (
8095- Some(DeclareType::Cursor),
8096- None,
8097- Some(DeclareAssignment::For(Box::new(
8098- self.parse_snowflake_declaration_payload_expr()?,
8099- ))),
8100- None,
8101- ),
8102- }
8103- } else if self.parse_keyword(Keyword::RESULTSET) {
8104- let assigned_expr = if self.peek_token_ref().token != Token::SemiColon {
8105- self.parse_snowflake_variable_declaration_expression()?
8106- } else {
8107- // Nothing more to do. The statement has no further parameters.
8108- None
8109- };
8110-
8111- (Some(DeclareType::ResultSet), None, assigned_expr, None)
8112- } else if self.parse_keyword(Keyword::EXCEPTION) {
8113- let assigned_expr = if self.peek_token_ref().token == Token::LParen {
8114- Some(DeclareAssignment::Expr(Box::new(self.parse_expr()?)))
8115- } else {
8116- // Nothing more to do. The statement has no further parameters.
8117- None
8118- };
8119-
8120- (Some(DeclareType::Exception), None, assigned_expr, None)
8121- } else {
8122- // Without an explicit keyword, the only valid option is variable declaration.
8123- let (assigned_expr, data_type) = if let Some(assigned_expr) =
8124- self.parse_snowflake_variable_declaration_expression()?
8125- {
8126- (Some(assigned_expr), None)
8127- } else if let Token::Word(_) = &self.peek_token_ref().token {
8128- let data_type = self.parse_data_type()?;
8129- (
8130- self.parse_snowflake_variable_declaration_expression()?,
8131- Some(data_type),
8132- )
8133- } else {
8134- (None, None)
8135- };
8136- (None, None, assigned_expr, data_type)
8137- };
8138- let stmt = Declare {
8139- names: vec![name],
8140- data_type,
8141- assignment: assigned_expr,
8142- declare_type,
8143- binary: None,
8144- sensitive: None,
8145- scroll: None,
8146- hold: None,
8147- for_query,
8148- };
8092+ let stmt = self.parse_snowflake_declare_one(name)?;
81498093
81508094 stmts.push(stmt);
81518095 if self.consume_token(&Token::SemiColon) {
@@ -8183,6 +8127,82 @@ impl<'a> Parser<'a> {
81838127 Ok(Statement::Declare { stmts })
81848128 }
81858129
8130+ /// Parse a single Snowflake `DECLARE` item once its `name` has been consumed.
8131+ ///
8132+ /// Shared by the `DECLARE` block parser and the scripting `LET` parser, so
8133+ /// `LET cur CURSOR FOR …` / `LET res RESULTSET := …` land in the same
8134+ /// [`Declare`] shape as their `DECLARE` spellings.
8135+ pub(crate) fn parse_snowflake_declare_one(
8136+ &mut self,
8137+ name: Ident,
8138+ ) -> Result<Declare, ParserError> {
8139+ let (declare_type, for_query, assigned_expr, data_type) =
8140+ if self.parse_keyword(Keyword::CURSOR) {
8141+ self.expect_keyword_is(Keyword::FOR)?;
8142+ match &self.peek_token_ref().token {
8143+ Token::Word(w) if w.keyword == Keyword::SELECT => (
8144+ Some(DeclareType::Cursor),
8145+ Some(self.parse_query()?),
8146+ None,
8147+ None,
8148+ ),
8149+ _ => (
8150+ Some(DeclareType::Cursor),
8151+ None,
8152+ Some(DeclareAssignment::For(Box::new(
8153+ self.parse_snowflake_declaration_payload_expr()?,
8154+ ))),
8155+ None,
8156+ ),
8157+ }
8158+ } else if self.parse_keyword(Keyword::RESULTSET) {
8159+ let assigned_expr = if self.peek_token_ref().token != Token::SemiColon {
8160+ self.parse_snowflake_variable_declaration_expression()?
8161+ } else {
8162+ // Nothing more to do. The statement has no further parameters.
8163+ None
8164+ };
8165+
8166+ (Some(DeclareType::ResultSet), None, assigned_expr, None)
8167+ } else if self.parse_keyword(Keyword::EXCEPTION) {
8168+ let assigned_expr = if self.peek_token_ref().token == Token::LParen {
8169+ Some(DeclareAssignment::Expr(Box::new(self.parse_expr()?)))
8170+ } else {
8171+ // Nothing more to do. The statement has no further parameters.
8172+ None
8173+ };
8174+
8175+ (Some(DeclareType::Exception), None, assigned_expr, None)
8176+ } else {
8177+ // Without an explicit keyword, the only valid option is variable declaration.
8178+ let (assigned_expr, data_type) = if let Some(assigned_expr) =
8179+ self.parse_snowflake_variable_declaration_expression()?
8180+ {
8181+ (Some(assigned_expr), None)
8182+ } else if let Token::Word(_) = &self.peek_token_ref().token {
8183+ let data_type = self.parse_data_type()?;
8184+ (
8185+ self.parse_snowflake_variable_declaration_expression()?,
8186+ Some(data_type),
8187+ )
8188+ } else {
8189+ (None, None)
8190+ };
8191+ (None, None, assigned_expr, data_type)
8192+ };
8193+ Ok(Declare {
8194+ names: vec![name],
8195+ data_type,
8196+ assignment: assigned_expr,
8197+ declare_type,
8198+ binary: None,
8199+ sensitive: None,
8200+ scroll: None,
8201+ hold: None,
8202+ for_query,
8203+ })
8204+ }
8205+
81868206 /// Parse a [MsSql] `DECLARE` statement.
81878207 ///
81888208 /// Syntax:
0 commit comments