Use primary table alias for SQL count query derivation with DISTINCT queries.
We now use render COUNT(DISTINCT a.*) where 'a' is the primary table alias instead of COUNT(DISTINCT *). Closes #3707
This commit is contained in:
@@ -354,11 +354,11 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
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);
|
||||
@@ -373,7 +373,8 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
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)));
|
||||
}
|
||||
|
||||
@@ -463,7 +464,8 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
* @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)) {
|
||||
|
||||
@@ -472,7 +474,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
return column.getFullyQualifiedName();
|
||||
}
|
||||
|
||||
return (distinct ? "*" : "1");
|
||||
return distinct ? ((tableAlias != null ? tableAlias + "." : "") + "*") : "1";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,6 +51,22 @@ public class JSqlParserQueryEnhancerUnitTests extends QueryEnhancerTckTests {
|
||||
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")
|
||||
|
||||
Reference in New Issue
Block a user