Skip to content

Commit

Permalink
Fix query rendering for signed expressions & literals.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
christophstrobl committed Feb 1, 2024
1 parent a1ebea0 commit e5d61e1
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* 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>> {
Expand Down Expand Up @@ -1325,7 +1326,7 @@ public List<JpaQueryParsingToken> visitSignedExpression(HqlParser.SignedExpressi

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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1468,7 +1468,7 @@ public List<JpaQueryParsingToken> visitArithmetic_factor(JpqlParser.Arithmetic_f
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()));

Expand Down Expand Up @@ -1699,6 +1699,7 @@ public List<JpaQueryParsingToken> visitFunctions_returning_numerics(
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) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
* IMPORTANT: Purely verifies the parser without any transformations.
*
* @author Greg Turnquist
* @author Christoph Strobl
* @since 3.1
*/
class HqlQueryRendererTests {
Expand Down Expand Up @@ -1651,4 +1652,13 @@ group by extract(epoch from departureTime)
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
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
Expand All @@ -30,6 +32,7 @@
* IMPORTANT: Purely verifies the parser without any transformations.
*
* @author Greg Turnquist
* @author Christoph Strobl
* @since 3.1
*/
class JpqlQueryRendererTests {
Expand Down Expand Up @@ -988,4 +991,27 @@ void newShouldBeLegalAsPartOfAStateFieldPathExpression() {
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);
}
}

0 comments on commit e5d61e1

Please sign in to comment.