Skip to content

Avoid double-parenthesis in JpqlQueryBuilder.InPredicate rendering #3962

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
* A Domain-Specific Language to build JPQL queries using Java code.
*
* @author Mark Paluch
* @author Choi Wang Gyu
*/
@SuppressWarnings("JavadocDeclaration")
public final class JpqlQueryBuilder {
Expand Down Expand Up @@ -1422,8 +1423,14 @@ record InPredicate(Expression path, String operator, Expression predicate) imple
@Override
public String render(RenderContext context) {

// TODO: should we rather wrap it with nested or check if its a nested predicate before we call render
return "%s %s (%s)".formatted(path.render(context), operator, predicate.render(context));
String predicateStr = predicate.render(context);

// Avoid double parentheses if predicate string already starts and ends with parentheses
if (predicateStr.startsWith("(") && predicateStr.endsWith(")")) {
return "%s %s %s".formatted(path.render(context), operator, predicateStr);
}

return "%s %s (%s)".formatted(path.render(context), operator, predicateStr);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
*
* @author Christoph Strobl
* @author Mark Paluch
* @author Choi Wang Gyu
*/
class JpqlQueryBuilderUnitTests {

Expand Down Expand Up @@ -136,6 +137,31 @@ void predicateRendering() {
assertThat(where.neq(expression("'AT'")).render(context)).isEqualTo("o.country != 'AT'");
}

@Test // GH-3961 - Nested predicate parentheses handling
void inPredicateWithNestedExpression() {

Entity entity = JpqlQueryBuilder.entity(Order.class);
WhereStep where = JpqlQueryBuilder.where(JpqlQueryBuilder.path(entity, "country"));
RenderContext context = ctx(entity);

// Test regular IN predicate with parentheses
assertThat(where.in(expression("'AT', 'DE'")).render(context)).isEqualTo("o.country IN ('AT', 'DE')");

// Test IN predicate with already parenthesized expression - should avoid double parentheses
Expression parenthesizedExpression = expression("('AT', 'DE')");
assertThat(where.in(parenthesizedExpression).render(context))
.isEqualTo("o.country IN ('AT', 'DE')");

// Test NOT IN predicate with already parenthesized expression
assertThat(where.notIn(parenthesizedExpression).render(context))
.isEqualTo("o.country NOT IN ('AT', 'DE')");

// Test IN with subquery (already parenthesized)
Expression subqueryExpression = expression("(SELECT c.code FROM Country c WHERE c.active = true)");
assertThat(where.in(subqueryExpression).render(context))
.isEqualTo("o.country IN (SELECT c.code FROM Country c WHERE c.active = true)");
}

@Test // GH-3588
void selectRendering() {

Expand Down