Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ambiguous grammar error when BETWEEN followed by two AND keywords #534

Closed
jcgoette opened this issue Nov 28, 2022 · 2 comments · Fixed by #566
Closed

Ambiguous grammar error when BETWEEN followed by two AND keywords #534

jcgoette opened this issue Nov 28, 2022 · 2 comments · Fixed by #566
Labels

Comments

@jcgoette
Copy link

Describe the bug
Raises error:

SELECT
  1
FROM
  DUAL
WHERE
  SYSDATE BETWEEN '2022-11-28 00:00:00' AND '2022-11-28 23:59:59'
  AND EXISTS (
    SELECT
      1
    FROM
      DUAL
  )

Doesn't raise error:

SELECT
  1
FROM
  DUAL
WHERE
  EXISTS (
    SELECT
      1
    FROM
      DUAL
  )
  AND SYSDATE BETWEEN '2022-11-28 00:00:00' AND '2022-11-28 23:59:59'

Expected behavior
Format. :)

Actual behavior
Raised error:

An Unexpected Error Occurred
Parse error: Ambiguous grammar [ [ { "type": "statement", "children": [ { "type": "clause", "nameKw": { "type": "keyword", "tokenType": "RESERVED_SELECT", "text": "SELECT", "raw": "SELECT" }, "children": [ { "type": "literal", "text": "1" } ] }, { "type": "clause", "nameKw": { "type": "keyword", "tokenType": "RESERVED_CLAUSE", "text": "FROM", "raw": "FROM" }, "children": [ { "type": "identifier", "text": "DUAL" } ] }, { "type": "clause", "nameKw": { "type": "keyword", "tokenType": "RESERVED_CLAUSE", "text": "WHERE", "raw": "WHERE" }, "children": [ { "type": "identifier", "text": "SYSDATE" }, { "type": "between_predicate", "betweenKw": { "type": "keyword", "tokenType": "BETWEEN", "text": "BETWEEN", "raw": "BETWEEN" }, "expr1": [ { "type": "literal", "text": "'2022-11-28 00:00:00'" } ], "andKw": { "type": "keyword", "tokenType": "AND", "text": "AND", "raw": "AND" }, "expr2": [ { "type": "literal", "text": "'2022-11-28 23:59:59'" } ] }, { "type": "keyword", "tokenType": "AND", "text": "AND", "raw": "AND" }, { "type": "keyword", "tokenType": "RESERVED_KEYWORD", "text": "EXISTS", "raw": "EXISTS" }, { "type": "parenthesis", "children": [ { "type": "clause", "nameKw": { "type": "keyword", "tokenType": "RESERVED_SELECT", "text": "SELECT", "raw": "SELECT" }, "children": [ { "type": "literal", "text": "1" } ] }, { "type": "clause", "nameKw": { "type": "keyword", "tokenType": "RESERVED_CLAUSE", "text": "FROM", "raw": "FROM" }, "children": [ { "type": "identifier", "text": "DUAL" } ] } ], "openParen": "(", "closeParen": ")" } ] } ], "hasSemicolon": false } ], [ { "type": "statement", "children": [ { "type": "clause", "nameKw": { "type": "keyword", "tokenType": "RESERVED_SELECT", "text": "SELECT", "raw": "SELECT" }, "children": [ { "type": "literal", "text": "1" } ] }, { "type": "clause", "nameKw": { "type": "keyword", "tokenType": "RESERVED_CLAUSE", "text": "FROM", "raw": "FROM" }, "children": [ { "type": "identifier", "text": "DUAL" } ] }, { "type": "clause", "nameKw": { "type": "keyword", "tokenType": "RESERVED_CLAUSE", "text": "WHERE", "raw": "WHERE" }, "children": [ { "type": "identifier", "text": "SYSDATE" }, { "type": "between_predicate", "betweenKw": { "type": "keyword", "tokenType": "BETWEEN", "text": "BETWEEN", "raw": "BETWEEN" }, "expr1": [ { "type": "literal", "text": "'2022-11-28 00:00:00'" }, { "type": "keyword", "tokenType": "AND", "text": "AND", "raw": "AND" }, { "type": "literal", "text": "'2022-11-28 23:59:59'" } ], "andKw": { "type": "keyword", "tokenType": "AND", "text": "AND", "raw": "AND" }, "expr2": [ { "type": "keyword", "tokenType": "RESERVED_KEYWORD", "text": "EXISTS", "raw": "EXISTS" } ] }, { "type": "parenthesis", "children": [ { "type": "clause", "nameKw": { "type": "keyword", "tokenType": "RESERVED_SELECT", "text": "SELECT", "raw": "SELECT" }, "children": [ { "type": "literal", "text": "1" } ] }, { "type": "clause", "nameKw": { "type": "keyword", "tokenType": "RESERVED_CLAUSE", "text": "FROM", "raw": "FROM" }, "children": [ { "type": "identifier", "text": "DUAL" } ] } ], "openParen": "(", "closeParen": ")" } ] } ], "hasSemicolon": false } ] ]

Usage

  • How are you calling / using the library?
    • From sql-formatter-org.github.io
  • What SQL language(s) does this apply to?
    • All
  • Which SQL Formatter version are you using?
    • Latest
@jcgoette jcgoette added the bug label Nov 28, 2022
@nene nene changed the title Parse error: Ambiguous grammar - "SELECT" Following "BETWEEN"? Ambiguous grammar error when BETWEEN followed by two AND keywords Dec 15, 2022
@nene
Copy link
Collaborator

nene commented Dec 15, 2022

Thanks for reporting, unfortunately haven't had time to tackle this problem.

The actual culprit here is this sort of expression:

... BETWEEN ... AND ... AND ...

The parser is getting confused whether it should parse it as:

(... BETWEEN ... AND ...) AND ...
... BETWEEN (... AND ...) AND ...
... BETWEEN ... AND (... AND ...)

a workaround for now is to supply your own extra parenthesis, like:

WHERE
  (SYSDATE BETWEEN '2022-11-28 00:00:00' AND '2022-11-28 23:59:59')
  AND (SELECT 1 FROM DUAL)

nene added a commit that referenced this issue Feb 17, 2023
Fixes a long-standing bug which resulted in ambiguous grammar.

The solution involves adding multiple new parser rules
which exclude the AND/OR/XOR operators from expressions
inside the BETWEEN-expression.

This solution is far from elegant. Really it's plain ugly,
but at least it gets the bug fixed. I think there's no good
way to fix it in the current parser/formatter architecture.

Fixes #534
@nene nene closed this as completed in #566 Feb 17, 2023
@nene
Copy link
Collaborator

nene commented Feb 17, 2023

This long-standing bug is now finally fixed in 12.1.1 release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants