@@ -1606,10 +1606,34 @@ impl<'a> Parser<'a> {
16061606 value: self.parse_introduced_string_expr()?.into(),
16071607 })
16081608 }
1609+ // An unreserved word (likely an identifier) is followed by an arrow,
1610+ // which indicates a lambda function with a single, untyped parameter.
1611+ // For example: `a -> a * 2`.
16091612 Token::Arrow if self.dialect.supports_lambda_functions() => {
16101613 self.expect_token(&Token::Arrow)?;
16111614 Ok(Expr::Lambda(LambdaFunction {
1612- params: OneOrManyWithParens::One(w.to_ident(w_span)),
1615+ params: OneOrManyWithParens::One(LambdaFunctionParameter {
1616+ name: w.to_ident(w_span),
1617+ data_type: None,
1618+ }),
1619+ body: Box::new(self.parse_expr()?),
1620+ syntax: LambdaSyntax::Arrow,
1621+ }))
1622+ }
1623+ // An unreserved word (likely an identifier) that is followed by another word (likley a data type)
1624+ // which is then followed by an arrow, which indicates a lambda function with a single, typed parameter.
1625+ // For example: `a INT -> a * 2`.
1626+ Token::Word(_)
1627+ if self.dialect.supports_lambda_functions()
1628+ && self.peek_nth_token_ref(1).token == Token::Arrow =>
1629+ {
1630+ let data_type = self.parse_data_type()?;
1631+ self.expect_token(&Token::Arrow)?;
1632+ Ok(Expr::Lambda(LambdaFunction {
1633+ params: OneOrManyWithParens::One(LambdaFunctionParameter {
1634+ name: w.to_ident(w_span),
1635+ data_type: Some(data_type),
1636+ }),
16131637 body: Box::new(self.parse_expr()?),
16141638 syntax: LambdaSyntax::Arrow,
16151639 }))
@@ -2195,7 +2219,7 @@ impl<'a> Parser<'a> {
21952219 return Ok(None);
21962220 }
21972221 self.maybe_parse(|p| {
2198- let params = p.parse_comma_separated(|p| p.parse_identifier ())?;
2222+ let params = p.parse_comma_separated(|p| p.parse_lambda_function_parameter ())?;
21992223 p.expect_token(&Token::RParen)?;
22002224 p.expect_token(&Token::Arrow)?;
22012225 let expr = p.parse_expr()?;
@@ -2207,7 +2231,7 @@ impl<'a> Parser<'a> {
22072231 })
22082232 }
22092233
2210- /// Parses a lambda expression using the `LAMBDA` keyword syntax.
2234+ /// Parses a lambda expression following the `LAMBDA` keyword syntax.
22112235 ///
22122236 /// Syntax: `LAMBDA <params> : <expr>`
22132237 ///
@@ -2217,30 +2241,49 @@ impl<'a> Parser<'a> {
22172241 ///
22182242 /// See <https://duckdb.org/docs/stable/sql/functions/lambda>
22192243 fn parse_lambda_expr(&mut self) -> Result<Expr, ParserError> {
2244+ // Parse the parameters: either a single identifier or comma-separated identifiers
2245+ let params = self.parse_lambda_function_parameters()?;
2246+ // Expect the colon separator
2247+ self.expect_token(&Token::Colon)?;
2248+ // Parse the body expression
2249+ let body = self.parse_expr()?;
2250+ Ok(Expr::Lambda(LambdaFunction {
2251+ params,
2252+ body: Box::new(body),
2253+ syntax: LambdaSyntax::LambdaKeyword,
2254+ }))
2255+ }
2256+
2257+ /// Parses the parameters of a lambda function with optional typing.
2258+ fn parse_lambda_function_parameters(
2259+ &mut self,
2260+ ) -> Result<OneOrManyWithParens<LambdaFunctionParameter>, ParserError> {
22202261 // Parse the parameters: either a single identifier or comma-separated identifiers
22212262 let params = if self.consume_token(&Token::LParen) {
22222263 // Parenthesized parameters: (x, y)
2223- let params = self.parse_comma_separated(|p| p.parse_identifier ())?;
2264+ let params = self.parse_comma_separated(|p| p.parse_lambda_function_parameter ())?;
22242265 self.expect_token(&Token::RParen)?;
22252266 OneOrManyWithParens::Many(params)
22262267 } else {
22272268 // Unparenthesized parameters: x or x, y
2228- let params = self.parse_comma_separated(|p| p.parse_identifier ())?;
2269+ let params = self.parse_comma_separated(|p| p.parse_lambda_function_parameter ())?;
22292270 if params.len() == 1 {
22302271 OneOrManyWithParens::One(params.into_iter().next().unwrap())
22312272 } else {
22322273 OneOrManyWithParens::Many(params)
22332274 }
22342275 };
2235- // Expect the colon separator
2236- self.expect_token(&Token::Colon)?;
2237- // Parse the body expression
2238- let body = self.parse_expr()?;
2239- Ok(Expr::Lambda(LambdaFunction {
2240- params,
2241- body: Box::new(body),
2242- syntax: LambdaSyntax::LambdaKeyword,
2243- }))
2276+ Ok(params)
2277+ }
2278+
2279+ /// Parses a single parameter of a lambda function, with optional typing.
2280+ fn parse_lambda_function_parameter(&mut self) -> Result<LambdaFunctionParameter, ParserError> {
2281+ let name = self.parse_identifier()?;
2282+ let data_type = match self.peek_token().token {
2283+ Token::Word(_) => self.maybe_parse(|p| p.parse_data_type())?,
2284+ _ => None,
2285+ };
2286+ Ok(LambdaFunctionParameter { name, data_type })
22442287 }
22452288
22462289 /// Tries to parse the body of an [ODBC escaping sequence]
0 commit comments