Skip to content

Commit

Permalink
Suppress selection item aliasing for the actual count query.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mp911de authored and christophstrobl committed Aug 9, 2024
1 parent e3da2f7 commit 9d4bde3
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,7 @@
*/
package org.springframework.data.jpa.repository.query;

import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_AS;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_CLOSE_PAREN;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_COUNT_FUNC;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_DOUBLE_UNDERSCORE;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_OPEN_PAREN;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_SELECT_COUNT;
import static org.springframework.data.jpa.repository.query.QueryTokens.*;

import org.springframework.data.jpa.repository.query.HqlParser.SelectClauseContext;
import org.springframework.data.jpa.repository.query.QueryRenderer.QueryRendererBuilder;
Expand Down Expand Up @@ -208,6 +203,22 @@ public QueryTokenStream visitSelectClause(HqlParser.SelectClauseContext ctx) {
return builder;
}

@Override
public QueryTokenStream visitSelection(HqlParser.SelectionContext ctx) {

if (isSubquery(ctx)) {
return super.visitSelection(ctx);
}

QueryRendererBuilder builder = QueryRenderer.builder();

builder.append(visit(ctx.selectExpression()));

// do not append variables to skip AS field aliasing

return builder;
}

@Override
public QueryRendererBuilder visitQueryOrder(HqlParser.QueryOrderContext ctx) {

Expand Down Expand Up @@ -247,7 +258,7 @@ private QueryRendererBuilder getDistinctCountSelection(QueryTokenStream selectio
nested.append(QueryTokens.token(primaryFromAlias));
} else {
// keep all the select items to distinct against
nested.append(countSelection);
nested.append(selectionListbuilder);
}
return nested;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,23 @@ void applyCountToSimpleQuery() {
assertThat(results).isEqualTo("select count(e) FROM Employee e where e.name = :name");
}

@Test // GH-3536
void shouldCreateCountQueryForDistinctCount() {

// given
var original = """
select distinct cast(e.timestampField as date) as foo
from ExampleEntity e
order by cast(e.timestampField as date) desc
""";

// when
var results = createCountQueryFor(original);

// then
assertThat(results).isEqualTo("select count(distinct cast(e.timestampField as date)) from ExampleEntity e");
}

@Test
void applyCountToMoreComplexQuery() {

Expand Down

0 comments on commit 9d4bde3

Please sign in to comment.