diff --git a/pom.xml b/pom.xml index 4838c7bd5f..11bf3f6ec1 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ 6.4.3-SNAPSHOT 2.7.1

2.2.220

- 4.5 + 4.8 8.0.33 42.6.0 3.3.0-SNAPSHOT diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java index c377d666c1..767e5cbf82 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java @@ -31,13 +31,10 @@ import net.sf.jsqlparser.statement.select.OrderByElement; import net.sf.jsqlparser.statement.select.PlainSelect; import net.sf.jsqlparser.statement.select.Select; -import net.sf.jsqlparser.statement.select.SelectBody; -import net.sf.jsqlparser.statement.select.SelectExpressionItem; import net.sf.jsqlparser.statement.select.SelectItem; import net.sf.jsqlparser.statement.select.SetOperationList; -import net.sf.jsqlparser.statement.select.WithItem; +import net.sf.jsqlparser.statement.select.Values; import net.sf.jsqlparser.statement.update.Update; -import net.sf.jsqlparser.statement.values.ValuesStatement; import java.util.ArrayList; import java.util.Collections; @@ -59,6 +56,7 @@ * @author Diego Krupitza * @author Greg Turnquist * @author Geoffrey Deremetz + * @author Yanming Zhou * @since 2.7.0 */ public class JSqlParserQueryEnhancer implements QueryEnhancer { @@ -120,13 +118,13 @@ public String applySorting(Sort sort, @Nullable String alias) { Select selectStatement = parseSelectStatement(queryString); - if (selectStatement.getSelectBody()instanceof SetOperationList setOperationList) { + if (selectStatement instanceof SetOperationList setOperationList) { return applySortingToSetOperationList(setOperationList, sort); - } else if (!(selectStatement.getSelectBody() instanceof PlainSelect)) { - return queryString; } - PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody(); + if (!(selectStatement instanceof PlainSelect selectBody)) { + return queryString; + } Set joinAliases = getJoinAliases(selectBody); Set selectionAliases = getSelectionAliases(selectBody); @@ -155,7 +153,7 @@ public String applySorting(Sort sort, @Nullable String alias) { private String applySortingToSetOperationList(SetOperationList setOperationListStatement, Sort sort) { // special case: ValuesStatements are detected as nested OperationListStatements - if (setOperationListStatement.getSelects().stream().anyMatch(ValuesStatement.class::isInstance)) { + if (setOperationListStatement.getSelects().stream().anyMatch(Values.class::isInstance)) { return setOperationListStatement.toString(); } @@ -185,8 +183,8 @@ private Set getSelectionAliases(PlainSelect selectBody) { } return selectBody.getSelectItems().stream() // - .filter(SelectExpressionItem.class::isInstance) // - .map(item -> ((SelectExpressionItem) item).getAlias()) // + .filter(SelectItem.class::isInstance) // + .map(item -> ((SelectItem) item).getAlias()) // .filter(Objects::nonNull) // .map(Alias::getName) // .collect(Collectors.toSet()); @@ -203,9 +201,7 @@ Set getSelectionAliases() { return new HashSet<>(); } - Select selectStatement = (Select) statement; - PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody(); - return this.getSelectionAliases(selectBody); + return this.getSelectionAliases((PlainSelect) statement); } /** @@ -221,7 +217,7 @@ private Set getJoinAliases(String query) { } Select selectStatement = (Select) statement; - if (selectStatement.getSelectBody()instanceof PlainSelect selectBody) { + if (selectStatement instanceof PlainSelect selectBody) { return getJoinAliases(selectBody); } @@ -319,7 +315,7 @@ private String detectAlias(String query) { * ValuesStatement has no alias * SetOperation can have multiple alias for each operation item */ - if (!(selectStatement.getSelectBody()instanceof PlainSelect selectBody)) { + if (!(selectStatement instanceof PlainSelect selectBody)) { return null; } @@ -374,7 +370,7 @@ public String createCountQueryFor(@Nullable String countProjection) { /* We only support count queries for {@link PlainSelect}. */ - if (!(selectStatement.getSelectBody()instanceof PlainSelect selectBody)) { + if (!(selectStatement instanceof PlainSelect selectBody)) { return this.query.getQueryString(); } @@ -384,7 +380,7 @@ public String createCountQueryFor(@Nullable String countProjection) { if (StringUtils.hasText(countProjection)) { Function jSqlCount = getJSqlCount(Collections.singletonList(countProjection), false); - selectBody.setSelectItems(Collections.singletonList(new SelectExpressionItem(jSqlCount))); + selectBody.setSelectItems(Collections.singletonList(new SelectItem(jSqlCount))); return selectBody.toString(); } @@ -394,34 +390,26 @@ public String createCountQueryFor(@Nullable String countProjection) { String tableAlias = detectAlias(selectBody); // is never null - List selectItems = selectBody.getSelectItems(); + List> selectItems = selectBody.getSelectItems(); if (onlyASingleColumnProjection(selectItems)) { - SelectExpressionItem singleProjection = (SelectExpressionItem) selectItems.get(0); + SelectItem singleProjection = (SelectItem) selectItems.get(0); Column column = (Column) singleProjection.getExpression(); String countProp = column.getFullyQualifiedName(); Function jSqlCount = getJSqlCount(Collections.singletonList(countProp), distinct); - selectBody.setSelectItems(Collections.singletonList(new SelectExpressionItem(jSqlCount))); + selectBody.setSelectItems(Collections.singletonList(new SelectItem<>(jSqlCount))); return selectBody.toString(); } String countProp = query.isNativeQuery() ? (distinct ? "*" : "1") : tableAlias == null ? "*" : tableAlias; Function jSqlCount = getJSqlCount(Collections.singletonList(countProp), distinct); - selectBody.setSelectItems(Collections.singletonList(new SelectExpressionItem(jSqlCount))); - - if (CollectionUtils.isEmpty(selectStatement.getWithItemsList())) { - return selectBody.toString(); - } - - String withStatements = selectStatement.getWithItemsList().stream() // - .map(WithItem::toString) // - .collect(Collectors.joining(",")); + selectBody.setSelectItems(Collections.singletonList(new SelectItem(jSqlCount))); - return "with " + withStatements + "\n" + selectBody; + return selectBody.toString(); } @Override @@ -435,13 +423,13 @@ public String getProjection() { Select selectStatement = (Select) statement; - if (selectStatement.getSelectBody() instanceof ValuesStatement) { + if (selectStatement instanceof Values) { return ""; } - SelectBody selectBody = selectStatement.getSelectBody(); + Select selectBody = selectStatement; - if (selectStatement.getSelectBody()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); @@ -493,11 +481,11 @@ private Select parseSelectStatement(String query) { * @param projection the projection to analyse * @return true when the projection only contains a single column definition otherwise false */ - private boolean onlyASingleColumnProjection(List projection) { + private boolean onlyASingleColumnProjection(List> projection) { // this is unfortunately the only way to check without any hacky & hard string regex magic - return projection.size() == 1 && projection.get(0) instanceof SelectExpressionItem - && (((SelectExpressionItem) projection.get(0)).getExpression()) instanceof Column; + return projection.size() == 1 && projection.get(0) instanceof SelectItem + && (((SelectItem) projection.get(0)).getExpression()) instanceof Column; } @Override diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancerUnitTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancerUnitTests.java index 639a156bf3..58b5b65893 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancerUnitTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancerUnitTests.java @@ -162,7 +162,7 @@ void withStatementsWorks() { assertThat(stringQuery.hasConstructorExpression()).isFalse(); assertThat(queryEnhancer.createCountQueryFor()).isEqualToIgnoringCase( - "with sample_data (day, value) AS (VALUES ((0, 13), (1, 12), (2, 15), (3, 4), (4, 8), (5, 16)))\n" + "with sample_data (day, value) AS (VALUES ((0, 13), (1, 12), (2, 15), (3, 4), (4, 8), (5, 16))) " + "SELECT count(1) FROM sample_data AS a"); assertThat(queryEnhancer.applySorting(Sort.by("day").descending())).endsWith("ORDER BY a.day DESC"); assertThat(queryEnhancer.getJoinAliases()).isEmpty(); @@ -185,7 +185,7 @@ void multipleWithStatementsWorks() { assertThat(stringQuery.hasConstructorExpression()).isFalse(); assertThat(queryEnhancer.createCountQueryFor()).isEqualToIgnoringCase( - "with sample_data (day, value) AS (VALUES ((0, 13), (1, 12), (2, 15), (3, 4), (4, 8), (5, 16))),test2 AS (VALUES (1, 2, 3))\n" + "with sample_data (day, value) AS (VALUES ((0, 13), (1, 12), (2, 15), (3, 4), (4, 8), (5, 16))), test2 AS (VALUES (1, 2, 3)) " + "SELECT count(1) FROM sample_data AS a"); assertThat(queryEnhancer.applySorting(Sort.by("day").descending())).endsWith("ORDER BY a.day DESC"); assertThat(queryEnhancer.getJoinAliases()).isEmpty();