Skip to content

Commit bc234f0

Browse files
committed
Fix nested EQL and JPQL aggregation function argument grammar.
We now accept a wider range of function arguments instead of limiting to property paths. Closes #4013
1 parent c3187fb commit bc234f0

File tree

7 files changed

+33
-28
lines changed

7 files changed

+33
-28
lines changed

spring-data-jpa/src/main/antlr4/org/springframework/data/jpa/repository/query/Eql.g4

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ constructor_item
219219
;
220220

221221
aggregate_expression
222-
: (AVG | MAX | MIN | SUM) '(' (DISTINCT)? state_valued_path_expression ')'
223-
| COUNT '(' (DISTINCT)? (identification_variable | state_valued_path_expression | single_valued_object_path_expression) ')'
222+
: (AVG | MAX | MIN | SUM) '(' (DISTINCT)? simple_select_expression ')'
223+
| COUNT '(' (DISTINCT)? simple_select_expression ')'
224224
| function_invocation
225225
;
226226

@@ -593,10 +593,7 @@ datetime_part
593593
;
594594

595595
function_arg
596-
: literal
597-
| state_valued_path_expression
598-
| input_parameter
599-
| scalar_expression
596+
: simple_select_expression
600597
;
601598

602599
case_expression

spring-data-jpa/src/main/antlr4/org/springframework/data/jpa/repository/query/Jpql.g4

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ constructor_item
220220
;
221221

222222
aggregate_expression
223-
: (AVG | MAX | MIN | SUM) '(' (DISTINCT)? state_valued_path_expression ')'
224-
| COUNT '(' (DISTINCT)? (identification_variable | state_valued_path_expression | single_valued_object_path_expression) ')'
223+
: (AVG | MAX | MIN | SUM) '(' (DISTINCT)? simple_select_expression ')'
224+
| COUNT '(' (DISTINCT)? simple_select_expression ')'
225225
| function_invocation
226226
;
227227

@@ -593,10 +593,7 @@ datetime_part
593593
;
594594

595595
function_arg
596-
: literal
597-
| state_valued_path_expression
598-
| input_parameter
599-
| scalar_expression
596+
: simple_select_expression
600597
;
601598

602599
case_expression

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlQueryRenderer.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ public QueryTokenStream visitAggregate_expression(EqlParser.Aggregate_expression
494494
builder.append(QueryTokens.expression(ctx.DISTINCT()));
495495
}
496496

497-
builder.appendInline(visit(ctx.state_valued_path_expression()));
497+
builder.appendInline(visit(ctx.simple_select_expression()));
498498
builder.append(TOKEN_CLOSE_PAREN);
499499
} else if (ctx.COUNT() != null) {
500500

@@ -503,13 +503,7 @@ public QueryTokenStream visitAggregate_expression(EqlParser.Aggregate_expression
503503
if (ctx.DISTINCT() != null) {
504504
builder.append(QueryTokens.expression(ctx.DISTINCT()));
505505
}
506-
if (ctx.identification_variable() != null) {
507-
builder.appendInline(visit(ctx.identification_variable()));
508-
} else if (ctx.state_valued_path_expression() != null) {
509-
builder.appendInline(visit(ctx.state_valued_path_expression()));
510-
} else if (ctx.single_valued_object_path_expression() != null) {
511-
builder.appendInline(visit(ctx.single_valued_object_path_expression()));
512-
}
506+
builder.appendInline(visit(ctx.simple_select_expression()));
513507
builder.append(TOKEN_CLOSE_PAREN);
514508
} else if (ctx.function_invocation() != null) {
515509
builder.append(visit(ctx.function_invocation()));

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryRenderer.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ public QueryTokenStream visitAggregate_expression(JpqlParser.Aggregate_expressio
495495
builder.append(QueryTokens.expression(ctx.DISTINCT()));
496496
}
497497

498-
builder.appendInline(visit(ctx.state_valued_path_expression()));
498+
builder.appendInline(visit(ctx.simple_select_expression()));
499499
builder.append(TOKEN_CLOSE_PAREN);
500500
} else if (ctx.COUNT() != null) {
501501

@@ -504,13 +504,8 @@ public QueryTokenStream visitAggregate_expression(JpqlParser.Aggregate_expressio
504504
if (ctx.DISTINCT() != null) {
505505
builder.append(QueryTokens.expression(ctx.DISTINCT()));
506506
}
507-
if (ctx.identification_variable() != null) {
508-
builder.appendInline(visit(ctx.identification_variable()));
509-
} else if (ctx.state_valued_path_expression() != null) {
510-
builder.appendInline(visit(ctx.state_valued_path_expression()));
511-
} else if (ctx.single_valued_object_path_expression() != null) {
512-
builder.appendInline(visit(ctx.single_valued_object_path_expression()));
513-
}
507+
508+
builder.appendInline(visit(ctx.simple_select_expression()));
514509
builder.append(TOKEN_CLOSE_PAREN);
515510
} else if (ctx.function_invocation() != null) {
516511
builder.append(visit(ctx.function_invocation()));

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlQueryRendererTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,14 @@ void findOrdersThatHaveProductNamedByAParameter() {
12541254
""");
12551255
}
12561256

1257+
@Test // GH-4013
1258+
void minMaxFunctionsShouldWork() {
1259+
assertQuery("SELECT MAX(e.age), e.address.city FROM Employee e");
1260+
assertQuery("SELECT MAX(1), e.address.city FROM Employee e");
1261+
assertQuery("SELECT MAX(MIN(MOD(e.salary, 10))), e.address.city FROM Employee e");
1262+
assertQuery("SELECT MIN(MOD(e.salary, 10)), e.address.city FROM Employee e");
1263+
}
1264+
12571265
@Test // GH-2982
12581266
void floorShouldBeValidEntityName() {
12591267

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/HqlQueryRendererTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2080,6 +2080,12 @@ void lnFunctionShouldWork() {
20802080
assertQuery("select ln(7.5) from Element a");
20812081
}
20822082

2083+
@Test // GH-4013
2084+
void minMaxFunctionsShouldWork() {
2085+
assertQuery("SELECT MAX(MIN(MOD(e.salary, 10))), e.address.city FROM Employee e");
2086+
assertQuery("SELECT MIN(MOD(e.salary, 10)), e.address.city FROM Employee e");
2087+
}
2088+
20832089
@Test // GH-2981
20842090
void cteWithClauseShouldWork() {
20852091

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlQueryRendererTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,14 @@ void findOrdersThatHaveProductNamedByAParameter() {
12601260
""");
12611261
}
12621262

1263+
@Test // GH-4013
1264+
void minMaxFunctionsShouldWork() {
1265+
assertQuery("SELECT MAX(e.age), e.address.city FROM Employee e");
1266+
assertQuery("SELECT MAX(1), e.address.city FROM Employee e");
1267+
assertQuery("SELECT MAX(MIN(MOD(e.salary, 10))), e.address.city FROM Employee e");
1268+
assertQuery("SELECT MIN(MOD(e.salary, 10)), e.address.city FROM Employee e");
1269+
}
1270+
12631271
@Test // GH-2982
12641272
void floorShouldBeValidEntityName() {
12651273

0 commit comments

Comments
 (0)