Skip to content

Support DuckDB's lambda x, y : expr syntax - #2782

Merged
manticore-projects merged 2 commits into
JSQLParser:masterfrom
guizmaii:duckdb-lambda-keyword
Oct 13, 2026
Merged

manticore-projects merged 2 commits into
JSQLParser:masterfrom
guizmaii:duckdb-lambda-keyword

Conversation

@guizmaii

@guizmaii guizmaii commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Purpose

Support DuckDB's recommended lambda syntax, lambda x, y : expr (DuckDB docs).

Current behaviour

There is no rule for it. list_transform(l, lambda x : x + 1) only parses by accident, as a parameter lambda followed by a keyword argument x : x + 1, which deparses as list_transform(l, lambda) once a FILTER or OVER follows. The common forms are rejected:

  • a condition body: list_filter(l, lambda x : x > 0), lambda x : x IS NOT NULL
  • several parameters: list_reduce(l, lambda acc, x : acc + x)

Change

  • DuckDBLambdaExpression() parses lambda x [, y ...] : expr into a LambdaExpression, reached from PrimaryExpression before Column(), behind isDuckDBLambdaAhead(): lambda followed by names separated by commas and a :.
  • LambdaExpression#isLambdaKeyword() records the syntax, so it deparses as written.
  • lambda stays a plain identifier (no new token, like the other isKeywordAhead() words): as a column, alias, table, type (CAST(a AS lambda), CREATE TABLE t (a lambda)), collation or in ALTER TABLE, and SELECT lambda x, y FROM t (a column aliased x) parses as before.

Validation

  • Java 17 Gradle check: 10,045 tests, zero failures/errors; Spotless, Checkstyle, PMD and SpotBugs pass.
  • DuckDBTest: comparison and boolean bodies, two parameters, nested lambdas, an array literal with a parenthesized element as the first argument, a lambda followed by more arguments, AST shape, and lambda as a name in queries, types, collations and DDL.

DuckDB's recommended lambda syntax, `lambda x, y : expr`, had no rule: `lambda x : x + 1`
only parsed by accident, as a column named `lambda` followed by a JSON path, and a
condition body (`lambda x : x > 0`, `lambda x : x IS NOT NULL`) or several parameters
(`lambda acc, x : acc + x`) were rejected. These are the common forms in `list_filter`
and `list_reduce`.

`DuckDBLambdaExpression()` parses it into a `LambdaExpression` flagged with
`isLambdaKeyword()`, which deparses it as written. `LAMBDA` is a non-reserved keyword,
so it remains usable as a name.
Copilot AI balanced review requested due to automatic review settings October 12, 2026 23:34

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

As a keyword token, LAMBDA stopped parsing where only plain identifiers are
accepted: `CAST(a AS lambda)`, `COLLATE lambda`, `CREATE TABLE t (a lambda)`,
`ALTER TABLE t DROP COLUMN lambda`, `ALTER TABLE t RENAME lambda TO x`.
`isDuckDBLambdaAhead()` recognises `lambda name [, name ...] :` contextually,
as `isKeywordAhead()` does for other words, so no token is needed.
@manticore-projects
manticore-projects merged commit eba5002 into JSQLParser:master Oct 13, 2026
10 checks passed
@manticore-projects

Copy link
Copy Markdown
Contributor

Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants