Skip to content

Commit

Permalink
Use primary table alias for SQL count query derivation with DISTINCT …
Browse files Browse the repository at this point in the history
…queries.

We now use render COUNT(DISTINCT a.*) where 'a' is the primary table alias instead of COUNT(DISTINCT *).

Closes #3707
  • Loading branch information
mp911de committed Dec 10, 2024
1 parent 813bf49 commit dcd36bf
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -354,11 +354,11 @@ public String createCountQueryFor(@Nullable String countProjection) {
return this.query.getQueryString();
}

return createCountQueryFor(this.query, selectBody, countProjection);
return createCountQueryFor(this.query, selectBody, countProjection, primaryAlias);
}

private static String createCountQueryFor(DeclaredQuery query, PlainSelect selectBody,
@Nullable String countProjection) {
@Nullable String countProjection, @Nullable String primaryAlias) {

// remove order by
selectBody.setOrderByElements(null);
Expand All @@ -373,7 +373,8 @@ private static String createCountQueryFor(DeclaredQuery query, PlainSelect selec
selectBody.setDistinct(null); // reset possible distinct

Function jSqlCount = getJSqlCount(
Collections.singletonList(countPropertyNameForSelection(selectBody.getSelectItems(), distinct)), distinct);
Collections.singletonList(countPropertyNameForSelection(selectBody.getSelectItems(), distinct, primaryAlias)),
distinct);
selectBody.setSelectItems(Collections.singletonList(SelectItem.from(jSqlCount)));
}

Expand Down Expand Up @@ -463,7 +464,8 @@ private static OrderByElement getOrderClause(Set<String> joinAliases, Set<String
* @param tableAlias the table alias which can be {@literal null}.
* @return
*/
private static String countPropertyNameForSelection(List<SelectItem<?>> selectItems, boolean distinct) {
private static String countPropertyNameForSelection(List<SelectItem<?>> selectItems, boolean distinct,
@Nullable String tableAlias) {

if (onlyASingleColumnProjection(selectItems)) {

Expand All @@ -472,7 +474,7 @@ private static String countPropertyNameForSelection(List<SelectItem<?>> selectIt
return column.getFullyQualifiedName();
}

return (distinct ? "*" : "1");
return distinct ? ((tableAlias != null ? tableAlias + "." : "") + "*") : "1";
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,22 @@ void shouldApplySorting() {
assertThat(sql).isEqualTo("SELECT e FROM Employee e ORDER BY e.foo ASC, e.bar ASC");
}

@Test // GH-3707
void countQueriesShouldConsiderPrimaryTableAlias() {

QueryEnhancer enhancer = createQueryEnhancer(DeclaredQuery.of("""
SELECT DISTINCT a.*, b.b1
FROM TableA a
JOIN TableB b ON a.b = b.b
LEFT JOIN TableC c ON b.c = c.c
ORDER BY b.b1, a.a1, a.a2
""", true));

String sql = enhancer.createCountQueryFor();

assertThat(sql).startsWith("SELECT count(DISTINCT a.*) FROM TableA a");
}

@Override
@ParameterizedTest // GH-2773
@MethodSource("jpqlCountQueries")
Expand Down

0 comments on commit dcd36bf

Please sign in to comment.