Fix missing DISTINCT in count queries.
The `COUNT_MATCH` does not consider line breaks after the `from` clause or the `where` clause. This leads to a no match scenario in the construction of the count query. With the fix we now consider line breaks/whitespaces after the `from` and `where` clause. See #2341 Related tickets: #2177
This commit is contained in:
committed by
Greg L. Turnquist
parent
32f0f54ebb
commit
3e64d9ad9b
@@ -147,7 +147,7 @@ public abstract class QueryUtils {
|
||||
builder.append(IDENTIFIER_GROUP);
|
||||
builder.append("(.*)");
|
||||
|
||||
COUNT_MATCH = compile(builder.toString(), CASE_INSENSITIVE);
|
||||
COUNT_MATCH = compile(builder.toString(), CASE_INSENSITIVE | DOTALL);
|
||||
|
||||
Map<PersistentAttributeType, Class<? extends Annotation>> persistentAttributeTypes = new HashMap<>();
|
||||
persistentAttributeTypes.put(ONE_TO_ONE, OneToOne.class);
|
||||
@@ -490,7 +490,8 @@ public abstract class QueryUtils {
|
||||
boolean useVariable = StringUtils.hasText(variable) //
|
||||
&& !variable.startsWith(" new") //
|
||||
&& !variable.startsWith("count(") //
|
||||
&& !variable.contains(","); //
|
||||
&& !variable.contains(",") //
|
||||
&& !variable.contains("*");
|
||||
|
||||
String complexCountValue = matcher.matches() && StringUtils.hasText(matcher.group(COMPLEX_COUNT_FIRST_INDEX))
|
||||
? COMPLEX_COUNT_VALUE
|
||||
|
||||
@@ -423,6 +423,11 @@ class QueryUtilsUnitTests {
|
||||
" where user.age = 18\n ");
|
||||
}
|
||||
|
||||
@Test // GH-2341
|
||||
void createCountQueryStarCharacterConverted() {
|
||||
assertThat(createCountQueryFor("select * from User user")).isEqualTo("select count(user) from User user");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createCountQuerySupportsLineBreaksInSelectClause() {
|
||||
|
||||
@@ -524,6 +529,28 @@ class QueryUtilsUnitTests {
|
||||
assertThat(QueryUtils.getProjection("select x, frommage, y from t")).isEqualTo("x, frommage, y");
|
||||
}
|
||||
|
||||
@Test // GH-2341
|
||||
void countProjectionDistrinctQueryIncludesNewLineAfterFromAndBeforeJoin() {
|
||||
String originalQuery = "SELECT DISTINCT entity1\nFROM Entity1 entity1\nLEFT JOIN Entity2 entity2 ON entity1.key = entity2.key";
|
||||
|
||||
assertCountQuery(originalQuery,
|
||||
"select count(DISTINCT entity1) FROM Entity1 entity1\nLEFT JOIN Entity2 entity2 ON entity1.key = entity2.key");
|
||||
}
|
||||
|
||||
@Test // GH-2341
|
||||
void countProjectionDistinctQueryIncludesNewLineAfterEntity() {
|
||||
String originalQuery = "SELECT DISTINCT entity1\nFROM Entity1 entity1 LEFT JOIN Entity2 entity2 ON entity1.key = entity2.key";
|
||||
assertCountQuery(originalQuery,
|
||||
"select count(DISTINCT entity1) FROM Entity1 entity1 LEFT JOIN Entity2 entity2 ON entity1.key = entity2.key");
|
||||
}
|
||||
|
||||
@Test // GH-2341
|
||||
void countProjectionDistinctQueryIncludesNewLineAfterEntityAndBeforeWhere() {
|
||||
String originalQuery = "SELECT DISTINCT entity1\nFROM Entity1 entity1 LEFT JOIN Entity2 entity2 ON entity1.key = entity2.key\nwhere entity1.id = 1799";
|
||||
assertCountQuery(originalQuery,
|
||||
"select count(DISTINCT entity1) FROM Entity1 entity1 LEFT JOIN Entity2 entity2 ON entity1.key = entity2.key\nwhere entity1.id = 1799");
|
||||
}
|
||||
|
||||
private static void assertCountQuery(String originalQuery, String countQuery) {
|
||||
assertThat(createCountQueryFor(originalQuery)).isEqualTo(countQuery);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user