Skip to content

DuckDB: support the ==, ** and ~~ operators and chained signs - #2795

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

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

Conversation

@guizmaii

@guizmaii guizmaii commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

For DuckDB (operators, numeric, pattern matching).

Input Before After
a == b error EqualsTo, spelled ==
2 * 3 ** 2 error Multiplication(2, Exponentiation(3, 2))
a ~~ 'x' RegExpMatchOperator(a, ~'x') (wrong tree) LikeExpression LIKE, spelled ~~
a !~~* 'x' wrong tree LikeExpression NOT ILIKE, spelled !~~*
a ~~~ 'x*' error LikeExpression GLOB
- -1, +-+1, ~ ~a error nested SignedExpression
  • Exponentiation is a new BinaryExpression; ExpressionVisitor.visit(Exponentiation) is a default method, so existing visitors keep compiling. Its precedence matches DuckDB: above *, left-associative, below the unary sign (-2 ** 2 = 4). ^ stays BitwiseXor at the level of *, so 2^3**2 still differs from DuckDB's power ^.
  • LikeExpression.setLikeOperator sets the keyword and NOT from the operator; the operator spelling is then derived from them, so later setNot/setLikeKeyWord calls print consistently (falling back to the keyword form, e.g. for NOT GLOB).
  • A sign is separated from an operand starting with a sign when either is ~, or both are -: - -1 must not deparse as the comment --1, nor - ~1 / ~ ~a as the single operators -~ / ~~.
  • Behaviour change: a ~~b and a !~~b used to parse as a regular expression match against ~b; they are now LIKE / NOT LIKE, as in PostgreSQL and DuckDB. Unspaced ~~a failed before and still does.
  • Not included: DuckDB's integer division // (lexed as a Snowflake line comment), ^@ and postfix a NOT NULL.
  • checkGrammarAmbiguity: no conflicts. ./gradlew check: 10,121 tests, 0 failures.
  • DuckDB's own test suite (test/sql, 70,729 statements): 199 more parse, none less.

@guizmaii
guizmaii marked this pull request as ready for review October 13, 2026 08:33
Copilot AI balanced review requested due to automatic review settings October 13, 2026 08:33

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.

@manticore-projects

Copy link
Copy Markdown
Contributor

Please resolve conflicts.

- `a == b` is `EqualsTo` with the `==` spelling.
- `a ** b` is the new `Exponentiation`, above the multiplicative
  operators and left-associative, as in DuckDB.
- `~~`, `~~*`, `~~~`, `!~~` and `!~~*` are `LIKE`, `ILIKE`, `GLOB` and
  their negations, kept as written. `a ~~ 'x'` used to parse as the
  regular expression match `a ~ (~'x')`.
- `- -1`, `+-+1` and `~ ~a` nest signs. A sign is separated from an
  operand starting with the same sign so that `- -1` does not deparse as
  the comment `--1`, nor `~ ~a` as `~~a`.
- The `~~` spelling is now derived from the keyword and `NOT`, so
  `setNot` or `setLikeKeyWord` no longer leave a stale operator, and
  `PRIOR` and `BINARY` are printed with it. `!~~~` and `null` are
  rejected.
- A sign is also separated from an operand when either is `~`: DuckDB
  and PostgreSQL read `-~1` as one unknown operator.
- `**` is the `OP_POWER` token; the `MulChain` alternative was never
  reached.
- `visit(Exponentiation)` is a default method, so existing
  `ExpressionVisitor` implementations keep compiling.
@manticore-projects
manticore-projects merged commit fde4f03 into JSQLParser:master Oct 13, 2026
10 checks passed
@manticore-projects

Copy link
Copy Markdown
Contributor

Thank you!

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