Fix query rendering for signed expressions & literals.

This commit makes sure to retain signed expressions (hql, jpql) and literals (jpql) when rendering the query.
Prior to the change singed expression/literal rendering added a space between the sign and the actual value so that `-1` would become `- 1` and `-count(u)` would be `- count(u)`.
Additionally a minor glitch in the jpql rendering was resolved that would add an extra space before the closing bracket of a LENGTH expression.

See: #3342
This commit is contained in:
Christoph Strobl
2024-02-01 10:05:22 +01:00
parent a1ebea0a61
commit e5d61e10da
4 changed files with 40 additions and 2 deletions

View File

@@ -24,6 +24,7 @@ import java.util.List;
* An ANTLR {@link org.antlr.v4.runtime.tree.ParseTreeVisitor} that renders an HQL query without making any changes.
*
* @author Greg Turnquist
* @author Christoph Strobl
* @since 3.1
*/
class HqlQueryRenderer extends HqlBaseVisitor<List<JpaQueryParsingToken>> {
@@ -1325,7 +1326,7 @@ class HqlQueryRenderer extends HqlBaseVisitor<List<JpaQueryParsingToken>> {
List<JpaQueryParsingToken> tokens = new ArrayList<>();
tokens.add(new JpaQueryParsingToken(ctx.op));
tokens.add(new JpaQueryParsingToken(ctx.op, false));
tokens.addAll(visit(ctx.expression()));
return tokens;

View File

@@ -1468,7 +1468,7 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<List<JpaQueryParsingToken>> {
List<JpaQueryParsingToken> tokens = new ArrayList<>();
if (ctx.op != null) {
tokens.add(new JpaQueryParsingToken(ctx.op));
tokens.add(new JpaQueryParsingToken(ctx.op, false));
}
tokens.addAll(visit(ctx.arithmetic_primary()));
@@ -1699,6 +1699,7 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<List<JpaQueryParsingToken>> {
tokens.add(new JpaQueryParsingToken(ctx.LENGTH(), false));
tokens.add(TOKEN_OPEN_PAREN);
tokens.addAll(visit(ctx.string_expression(0)));
NOSPACE(tokens);
tokens.add(TOKEN_CLOSE_PAREN);
} else if (ctx.LOCATE() != null) {

View File

@@ -33,6 +33,7 @@ import org.junit.jupiter.params.provider.ValueSource;
* IMPORTANT: Purely verifies the parser without any transformations.
*
* @author Greg Turnquist
* @author Christoph Strobl
* @since 3.1
*/
class HqlQueryRendererTests {
@@ -1651,4 +1652,13 @@ class HqlQueryRendererTests {
void signedLiteralShouldWork(String query) {
assertQuery(query);
}
@ParameterizedTest // GH-3342
@ValueSource(strings = {
"select -count(u) from User u",
"select +1*(-count(u)) from User u"
})
void signedExpressionsShouldWork(String query) {
assertQuery(query);
}
}

View File

@@ -22,6 +22,8 @@ import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
/**
* Tests built around examples of JPQL found in the JPA spec
@@ -30,6 +32,7 @@ import org.junit.jupiter.api.Test;
* IMPORTANT: Purely verifies the parser without any transformations.
*
* @author Greg Turnquist
* @author Christoph Strobl
* @since 3.1
*/
class JpqlQueryRendererTests {
@@ -988,4 +991,27 @@ class JpqlQueryRendererTests {
void powerShouldBeLegalInAQuery() {
assertQuery("select e.power.id from MyEntity e");
}
@ParameterizedTest // GH-3342
@ValueSource(strings = {
"select 1 as value from User u",
"select -1 as value from User u",
"select +1 as value from User u",
"select +1*-100 as value from User u",
"select count(u)*-0.7f as value from User u",
"select count(oi) + (-100) as perc from StockOrderItem oi",
"select p from Payment p where length(p.cardNumber) between +16 and -20"
})
void signedLiteralShouldWork(String query) {
assertQuery(query);
}
@ParameterizedTest // GH-3342
@ValueSource(strings = {
"select -count(u) from User u",
"select +1*(-count(u)) from User u"
})
void signedExpressionsShouldWork(String query) {
assertQuery(query);
}
}