@@ -1516,6 +1516,9 @@ impl<'a> Parser<'a> {
15161516 Keyword::MAP if *self.peek_token_ref() == Token::LBrace && self.dialect.support_map_literal_syntax() => {
15171517 Ok(Some(self.parse_duckdb_map_literal()?))
15181518 }
1519+ Keyword::LAMBDA if self.dialect.supports_lambda_functions() => {
1520+ Ok(Some(self.parse_lambda_expr()?))
1521+ }
15191522 _ if self.dialect.supports_geometric_types() => match w.keyword {
15201523 Keyword::CIRCLE => Ok(Some(self.parse_geometric_type(GeometricTypeKind::Circle)?)),
15211524 Keyword::BOX => Ok(Some(self.parse_geometric_type(GeometricTypeKind::GeometricBox)?)),
@@ -1568,6 +1571,7 @@ impl<'a> Parser<'a> {
15681571 Ok(Expr::Lambda(LambdaFunction {
15691572 params: OneOrManyWithParens::One(w.clone().into_ident(w_span)),
15701573 body: Box::new(self.parse_expr()?),
1574+ syntax: LambdaSyntax::Arrow,
15711575 }))
15721576 }
15731577 _ => Ok(Expr::Identifier(w.clone().into_ident(w_span))),
@@ -2108,10 +2112,47 @@ impl<'a> Parser<'a> {
21082112 Ok(Expr::Lambda(LambdaFunction {
21092113 params: OneOrManyWithParens::Many(params),
21102114 body: Box::new(expr),
2115+ syntax: LambdaSyntax::Arrow,
21112116 }))
21122117 })
21132118 }
21142119
2120+ /// Parses a lambda expression using the `LAMBDA` keyword syntax.
2121+ ///
2122+ /// Syntax: `LAMBDA <params> : <expr>`
2123+ ///
2124+ /// Examples:
2125+ /// - `LAMBDA x : x + 1`
2126+ /// - `LAMBDA x, i : x > i`
2127+ ///
2128+ /// See <https://duckdb.org/docs/stable/sql/functions/lambda>
2129+ fn parse_lambda_expr(&mut self) -> Result<Expr, ParserError> {
2130+ // Parse the parameters: either a single identifier or comma-separated identifiers
2131+ let params = if self.consume_token(&Token::LParen) {
2132+ // Parenthesized parameters: (x, y)
2133+ let params = self.parse_comma_separated(|p| p.parse_identifier())?;
2134+ self.expect_token(&Token::RParen)?;
2135+ OneOrManyWithParens::Many(params)
2136+ } else {
2137+ // Unparenthesized parameters: x or x, y
2138+ let params = self.parse_comma_separated(|p| p.parse_identifier())?;
2139+ if params.len() == 1 {
2140+ OneOrManyWithParens::One(params.into_iter().next().unwrap())
2141+ } else {
2142+ OneOrManyWithParens::Many(params)
2143+ }
2144+ };
2145+ // Expect the colon separator
2146+ self.expect_token(&Token::Colon)?;
2147+ // Parse the body expression
2148+ let body = self.parse_expr()?;
2149+ Ok(Expr::Lambda(LambdaFunction {
2150+ params,
2151+ body: Box::new(body),
2152+ syntax: LambdaSyntax::LambdaKeyword,
2153+ }))
2154+ }
2155+
21152156 /// Tries to parse the body of an [ODBC escaping sequence]
21162157 /// i.e. without the enclosing braces
21172158 /// Currently implemented:
0 commit comments