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:
@@ -58,6 +58,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Geoffrey Deremetz
|
||||
* @author Yanming Zhou
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
@@ -119,7 +120,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
|
||||
Select selectStatement = parseSelectStatement(queryString);
|
||||
|
||||
if (selectStatement instanceof SetOperationList setOperationList) {
|
||||
if (selectStatement instanceof SetOperationList setOperationList) {
|
||||
return applySortingToSetOperationList(setOperationList, sort);
|
||||
}
|
||||
|
||||
@@ -217,7 +218,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
}
|
||||
|
||||
Select selectStatement = (Select) statement;
|
||||
if (selectStatement instanceof PlainSelect selectBody) {
|
||||
if (selectStatement instanceof PlainSelect selectBody) {
|
||||
return getJoinAliases(selectBody);
|
||||
}
|
||||
|
||||
@@ -315,7 +316,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
* ValuesStatement has no alias
|
||||
* SetOperation can have multiple alias for each operation item
|
||||
*/
|
||||
if (!(selectStatement instanceof PlainSelect selectBody)) {
|
||||
if (!(selectStatement instanceof PlainSelect selectBody)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -370,7 +371,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
/*
|
||||
We only support count queries for {@link PlainSelect}.
|
||||
*/
|
||||
if (!(selectStatement instanceof PlainSelect selectBody)) {
|
||||
if (!(selectStatement instanceof PlainSelect selectBody)) {
|
||||
return this.query.getQueryString();
|
||||
}
|
||||
|
||||
@@ -413,7 +414,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
|
||||
Select selectBody = selectStatement;
|
||||
|
||||
if (selectStatement instanceof SetOperationList setOperationList) {
|
||||
if (selectStatement instanceof SetOperationList setOperationList) {
|
||||
|
||||
// using the first one since for setoperations the projection has to be the same
|
||||
selectBody = setOperationList.getSelects().get(0);
|
||||
@@ -491,7 +492,12 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
return column.getFullyQualifiedName();
|
||||
}
|
||||
|
||||
return query.isNativeQuery() ? (distinct ? "*" : "1") : tableAlias == null ? "*" : tableAlias;
|
||||
// TODO: We should not handle JPQL here...
|
||||
if (!query.isNativeQuery()) {
|
||||
return tableAlias == null ? "*" : tableAlias;
|
||||
}
|
||||
|
||||
return distinct ? ((tableAlias != null ? tableAlias + "." : "") + "*") : "1";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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