Sort properties shouldn't overlap with aliases.

When using an alias in a query, verify using "." as a proper separator against both alias projections as the primary alias to ensure that a Sort property doesn't overlap with an alias.

See #3054
This commit is contained in:
Greg L. Turnquist
2023-07-05 12:41:40 -05:00
parent 133ec27b74
commit 36accbbb0c
2 changed files with 31 additions and 1 deletions

View File

@@ -131,13 +131,18 @@ class JpaQueryTransformerSupport {
return false;
}
// If the Sort starts with the primary alias
if (order.getProperty().startsWith(primaryFromAlias + ".")) {
return false;
}
// If the Sort references an alias directly
if (projectionAliases.contains(order.getProperty())) {
return false;
}
// If the Sort property starts with an alias
if (projectionAliases.stream().anyMatch(alias -> order.getProperty().startsWith(alias))) {
if (projectionAliases.stream().anyMatch(alias -> order.getProperty().startsWith(alias + "."))) {
return false;
}

View File

@@ -1006,6 +1006,31 @@ class HqlQueryTransformerTests {
""");
}
@Test // GH-3054
void aliasesShouldNotOverlapWithSortProperties() {
assertThat(
createQueryFor("select e from Employee e where e.name = :name", Sort.by(Sort.Order.desc("evaluationDate"))))
.isEqualToIgnoringWhitespace(
"select e from Employee e where e.name = :name order by e.evaluationDate desc");
assertThat(createQueryFor("select e from Employee e join training t where e.name = :name",
Sort.by(Sort.Order.desc("trainingDueDate")))).isEqualToIgnoringWhitespace(
"select e from Employee e join training t where e.name = :name order by e.trainingDueDate desc");
assertThat(createQueryFor("select e from Employee e join training t where e.name = :name",
Sort.by(Sort.Order.desc("t.trainingDueDate")))).isEqualToIgnoringWhitespace(
"select e from Employee e join training t where e.name = :name order by t.trainingDueDate desc");
assertThat(createQueryFor("SELECT t3 FROM Test3 t3 JOIN t3.test2 t2 JOIN t2.test1 test WHERE test.id = :test1Id",
Sort.by(Sort.Order.desc("testDuplicateColumnName")))).isEqualToIgnoringWhitespace(
"SELECT t3 FROM Test3 t3 JOIN t3.test2 t2 JOIN t2.test1 test WHERE test.id = :test1Id order by t3.testDuplicateColumnName desc");
assertThat(createQueryFor("SELECT t3 FROM Test3 t3 JOIN t3.test2 x WHERE x.id = :test2Id",
Sort.by(Sort.Order.desc("t3.testDuplicateColumnName")))).isEqualToIgnoringWhitespace(
"SELECT t3 FROM Test3 t3 JOIN t3.test2 x WHERE x.id = :test2Id order by t3.testDuplicateColumnName desc");
}
private void assertCountQuery(String originalQuery, String countQuery) {
assertThat(createCountQueryFor(originalQuery)).isEqualTo(countQuery);
}