Fix EQL parsing for MOD expression.
The samples used to validate MOD parsing in tests does not comply with the specification and falsely uses '/' instead of ',' as delimiter. Definition is: expression ::= MOD(arithmetic_expression, arithmetic_expression) See: https://eclipse.dev/eclipselink/api/4.0/eclipselink/org/eclipse/persistence/jpa/jpql/parser/ModExpression.html Closes #3277 Original pull request: #3280
This commit is contained in:
committed by
Mark Paluch
parent
148beae6f3
commit
6d73fbc5f3
@@ -23,6 +23,7 @@ grammar Eql;
|
||||
* * https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Christoph Strobl
|
||||
* @since 3.2
|
||||
*/
|
||||
}
|
||||
@@ -509,7 +510,7 @@ functions_returning_numerics
|
||||
| LN '(' arithmetic_expression ')'
|
||||
| SIGN '(' arithmetic_expression ')'
|
||||
| SQRT '(' arithmetic_expression ')'
|
||||
| MOD '(' arithmetic_expression '/' arithmetic_expression ')'
|
||||
| MOD '(' arithmetic_expression ',' arithmetic_expression ')'
|
||||
| POWER '(' arithmetic_expression ',' arithmetic_expression ')'
|
||||
| ROUND '(' arithmetic_expression ',' arithmetic_expression ')'
|
||||
| SIZE '(' collection_valued_path_expression ')'
|
||||
@@ -894,4 +895,4 @@ INTLITERAL : ('0' .. '9')+ ;
|
||||
LONGLITERAL : ('0' .. '9')+ L;
|
||||
DATELITERAL : '{' D STRINGLITERAL '}';
|
||||
TIMELITERAL : '{' T STRINGLITERAL '}';
|
||||
TIMESTAMPLITERAL : '{' T S STRINGLITERAL '}';
|
||||
TIMESTAMPLITERAL : '{' T S STRINGLITERAL '}';
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.List;
|
||||
* An ANTLR {@link org.antlr.v4.runtime.tree.ParseTreeVisitor} that renders an EQL query without making any changes.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Christoph Strobl
|
||||
* @since 3.2
|
||||
*/
|
||||
@SuppressWarnings({ "ConstantConditions", "DuplicatedCode" })
|
||||
@@ -1912,7 +1913,8 @@ class EqlQueryRenderer extends EqlBaseVisitor<List<JpaQueryParsingToken>> {
|
||||
tokens.add(new JpaQueryParsingToken(ctx.MOD(), false));
|
||||
tokens.add(TOKEN_OPEN_PAREN);
|
||||
tokens.addAll(visit(ctx.arithmetic_expression(0)));
|
||||
tokens.add(new JpaQueryParsingToken("/"));
|
||||
NOSPACE(tokens);
|
||||
tokens.add(TOKEN_COMMA);
|
||||
tokens.addAll(visit(ctx.arithmetic_expression(1)));
|
||||
NOSPACE(tokens);
|
||||
tokens.add(TOKEN_CLOSE_PAREN);
|
||||
|
||||
@@ -25,10 +25,13 @@ import org.junit.jupiter.api.Test;
|
||||
/**
|
||||
* Tests built around examples of EQL found in the EclipseLink's docs at
|
||||
* https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL<br/>
|
||||
* With the exception of {@literal MOD} which is defined as {@literal MOD(arithmetic_expression , arithmetic_expression)},
|
||||
* but shown in tests as {@literal MOD(arithmetic_expression ? arithmetic_expression)}.
|
||||
* <br/>
|
||||
* IMPORTANT: Purely verifies the parser without any transformations.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
class EqlComplianceTests {
|
||||
|
||||
@@ -214,7 +217,7 @@ class EqlComplianceTests {
|
||||
assertQuery("SELECT e.name, CURRENT_TIMESTAMP FROM Employee e");
|
||||
assertQuery("SELECT LENGTH(e.lastName) FROM Employee e");
|
||||
assertQuery("SELECT LOWER(e.lastName) FROM Employee e");
|
||||
assertQuery("SELECT MOD(e.hoursWorked / 8) FROM Employee e");
|
||||
assertQuery("SELECT MOD(e.hoursWorked, 8) FROM Employee e");
|
||||
assertQuery("SELECT NULLIF(e.salary, 0) FROM Employee e");
|
||||
assertQuery("SELECT SQRT(o.RESULT) FROM Output o");
|
||||
assertQuery("SELECT SUBSTRING(e.lastName, 0, 2) FROM Employee e");
|
||||
@@ -243,7 +246,7 @@ class EqlComplianceTests {
|
||||
assertQuery("SELECT e FROM Employee e WHERE CURRENT_TIME > CURRENT_TIMESTAMP");
|
||||
assertQuery("SELECT e FROM Employee e WHERE LENGTH(e.lastName) > 0");
|
||||
assertQuery("SELECT e FROM Employee e WHERE LOWER(e.lastName) = 'bilbo'");
|
||||
assertQuery("SELECT e FROM Employee e WHERE MOD(e.hoursWorked / 8) > 0");
|
||||
assertQuery("SELECT e FROM Employee e WHERE MOD(e.hoursWorked, 8) > 0");
|
||||
assertQuery("SELECT e FROM Employee e WHERE NULLIF(e.salary, 0) is null");
|
||||
assertQuery("SELECT e FROM Employee e WHERE SQRT(o.RESULT) > 0.0");
|
||||
assertQuery("SELECT e FROM Employee e WHERE SUBSTRING(e.lastName, 0, 2) = 'Bilbo'");
|
||||
@@ -272,7 +275,7 @@ class EqlComplianceTests {
|
||||
assertQuery("SELECT e FROM Employee e ORDER BY CURRENT_TIMESTAMP");
|
||||
assertQuery("SELECT e FROM Employee e ORDER BY LENGTH(e.lastName)");
|
||||
assertQuery("SELECT e FROM Employee e ORDER BY LOWER(e.lastName)");
|
||||
assertQuery("SELECT e FROM Employee e ORDER BY MOD(e.hoursWorked / 8)");
|
||||
assertQuery("SELECT e FROM Employee e ORDER BY MOD(e.hoursWorked, 8)");
|
||||
assertQuery("SELECT e FROM Employee e ORDER BY NULLIF(e.salary, 0)");
|
||||
assertQuery("SELECT e FROM Employee e ORDER BY SQRT(o.RESULT)");
|
||||
assertQuery("SELECT e FROM Employee e ORDER BY SUBSTRING(e.lastName, 0, 2)");
|
||||
@@ -301,7 +304,7 @@ class EqlComplianceTests {
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY CURRENT_TIMESTAMP");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY LENGTH(e.lastName)");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY LOWER(e.lastName)");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY MOD(e.hoursWorked / 8)");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY MOD(e.hoursWorked, 8)");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY NULLIF(e.salary, 0)");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY SQRT(o.RESULT)");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY SUBSTRING(e.lastName, 0, 2)");
|
||||
@@ -329,7 +332,7 @@ class EqlComplianceTests {
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY e.salary HAVING CURRENT_TIME > CURRENT_TIMESTAMP");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY e.salary HAVING LENGTH(e.lastName) > 0");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY e.salary HAVING LOWER(e.lastName) = 'bilbo'");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY e.salary HAVING MOD(e.hoursWorked / 8) > 0");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY e.salary HAVING MOD(e.hoursWorked, 8) > 0");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY e.salary HAVING NULLIF(e.salary, 0) is null");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY e.salary HAVING SQRT(o.RESULT) > 0.0");
|
||||
assertQuery("SELECT e FROM Employee e GROUP BY e.salary HAVING SUBSTRING(e.lastName, 0, 2) = 'Bilbo'");
|
||||
|
||||
Reference in New Issue
Block a user