Skip to content

Commit

Permalink
spring-projectsGH-2341 - Fix missing DISTINCT in count query bug.
Browse files Browse the repository at this point in the history
The `COUNT_MATCH` did not consider line breaks after the `from` clause or the `where` clause. This lead 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.

Closes spring-projects#2341
Related tickets spring-projects#2177
  • Loading branch information
DiegoKrupitza committed Dec 17, 2021
1 parent bca2adc commit 8f49df7
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,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);
Expand Down Expand Up @@ -482,7 +482,8 @@ public static String createCountQueryFor(String originalQuery, @Nullable String
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,11 @@ void createCountQuerySupportsWhitespaceCharacters() {
" 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() {

Expand Down Expand Up @@ -511,6 +516,28 @@ void findProjectionClauseWithIncludedFrom() {
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
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
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);
}
Expand Down

0 comments on commit 8f49df7

Please sign in to comment.