Skip to content

Commit f62d382

Browse files
mp911dechristophstrobl
authored andcommitted
Suppress selection item aliasing for the actual count query.
We now no longer apply count selection filtering but rather skip select field aliasing when rendering a count query to drop the field alias within a count query. Previously, we removed field aliasing by filtering the token stream which also removed the AS keyword from cast operators. Closes: #3536 Original Pull Request: #3553
1 parent f15d158 commit f62d382

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

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

+15-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import org.antlr.v4.runtime.ParserRuleContext;
2525
import org.springframework.data.domain.Sort;
26+
import org.springframework.data.jpa.repository.query.HqlParser.SelectionContext;
2627
import org.springframework.lang.Nullable;
2728
import org.springframework.util.Assert;
2829

@@ -331,6 +332,17 @@ public List<JpaQueryParsingToken> visitVariable(HqlParser.VariableContext ctx) {
331332
return tokens;
332333
}
333334

335+
@Override
336+
public List<JpaQueryParsingToken> visitSelection(SelectionContext ctx) {
337+
338+
if(!countQuery || isSubquery(ctx)) {
339+
return super.visitSelection(ctx);
340+
}
341+
342+
// do not append variables to skip AS field aliasing
343+
return visit(ctx.selectExpression());
344+
}
345+
334346
@Override
335347
public List<JpaQueryParsingToken> visitSelectClause(HqlParser.SelectClauseContext ctx) {
336348

@@ -339,6 +351,7 @@ public List<JpaQueryParsingToken> visitSelectClause(HqlParser.SelectClauseContex
339351
tokens.add(new JpaQueryParsingToken(ctx.SELECT()));
340352

341353
if (countQuery && !isSubquery(ctx)) {
354+
342355
tokens.add(TOKEN_COUNT_FUNC);
343356

344357
if (countProjection != null) {
@@ -358,14 +371,12 @@ public List<JpaQueryParsingToken> visitSelectClause(HqlParser.SelectClauseContex
358371

359372
if (ctx.DISTINCT() != null) {
360373

361-
List<JpaQueryParsingToken> countSelection = QueryTransformers.filterCountSelection(selectionListTokens);
362-
363-
if (countSelection.stream().anyMatch(hqlToken -> hqlToken.getToken().contains("new"))) {
374+
if (selectionListTokens.stream().anyMatch(hqlToken -> hqlToken.getToken().contains("new"))) {
364375
// constructor
365376
tokens.add(new JpaQueryParsingToken(() -> primaryFromAlias));
366377
} else {
367378
// keep all the select items to distinct against
368-
tokens.addAll(countSelection);
379+
tokens.addAll(selectionListTokens);
369380
}
370381
} else {
371382
tokens.add(new JpaQueryParsingToken(() -> primaryFromAlias));

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

+19-2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,23 @@ void applyCountToSimpleQuery() {
8585
assertThat(results).isEqualTo("select count(e) FROM Employee e where e.name = :name");
8686
}
8787

88+
@Test // GH-3536
89+
void shouldCreateCountQueryForDistinctCount() {
90+
91+
// given
92+
var original = """
93+
select distinct cast(e.timestampField as date) as foo
94+
from ExampleEntity e
95+
order by cast(e.timestampField as date) desc
96+
""";
97+
98+
// when
99+
var results = createCountQueryFor(original);
100+
101+
// then
102+
assertThat(results).isEqualTo("select count(distinct cast(e.timestampField as date)) from ExampleEntity e");
103+
}
104+
88105
@Test
89106
void applyCountToMoreComplexQuery() {
90107

@@ -1037,9 +1054,9 @@ void createsCountQueryUsingAliasCorrectly() {
10371054

10381055
assertCountQuery("select distinct 1 as x from Employee","select count(distinct 1) from Employee AS __");
10391056
assertCountQuery("SELECT DISTINCT abc AS x FROM T","SELECT count(DISTINCT abc) FROM T AS __");
1040-
assertCountQuery("select distinct a as x, b as y from Employee","select count(distinct a , b) from Employee AS __");
1057+
assertCountQuery("select distinct a as x, b as y from Employee","select count(distinct a, b) from Employee AS __");
10411058
assertCountQuery("select distinct sum(amount) as x from Employee GROUP BY n","select count(distinct sum(amount)) from Employee AS __ GROUP BY n");
1042-
assertCountQuery("select distinct a, b, sum(amount) as c, d from Employee GROUP BY n","select count(distinct a, b, sum(amount) , d) from Employee AS __ GROUP BY n");
1059+
assertCountQuery("select distinct a, b, sum(amount) as c, d from Employee GROUP BY n","select count(distinct a, b, sum(amount), d) from Employee AS __ GROUP BY n");
10431060
assertCountQuery("select distinct a, count(b) as c from Employee GROUP BY n","select count(distinct a, count(b)) from Employee AS __ GROUP BY n");
10441061
}
10451062

0 commit comments

Comments
 (0)