committed by
Christoph Strobl
parent
6063c73d5d
commit
c5aa790e39
2
pom.xml
2
pom.xml
@@ -34,7 +34,7 @@
|
||||
<hibernate-64-next-snapshots>6.4.3-SNAPSHOT</hibernate-64-next-snapshots>
|
||||
<hsqldb>2.7.1</hsqldb>
|
||||
<h2>2.2.220</h2>
|
||||
<jsqlparser>4.5</jsqlparser>
|
||||
<jsqlparser>4.8</jsqlparser>
|
||||
<mysql-connector-java>8.0.33</mysql-connector-java>
|
||||
<postgresql>42.6.0</postgresql>
|
||||
<springdata.commons>3.3.0-SNAPSHOT</springdata.commons>
|
||||
|
||||
@@ -31,13 +31,10 @@ import net.sf.jsqlparser.statement.merge.Merge;
|
||||
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 @@ import org.springframework.util.StringUtils;
|
||||
* @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 class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
|
||||
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<String> joinAliases = getJoinAliases(selectBody);
|
||||
Set<String> selectionAliases = getSelectionAliases(selectBody);
|
||||
@@ -155,7 +153,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
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 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
}
|
||||
|
||||
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 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
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 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
}
|
||||
|
||||
Select selectStatement = (Select) statement;
|
||||
if (selectStatement.getSelectBody()instanceof PlainSelect selectBody) {
|
||||
if (selectStatement instanceof PlainSelect selectBody) {
|
||||
return getJoinAliases(selectBody);
|
||||
}
|
||||
|
||||
@@ -319,7 +315,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
* 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 class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
/*
|
||||
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 class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
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 class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
String tableAlias = detectAlias(selectBody);
|
||||
|
||||
// is never null
|
||||
List<SelectItem> selectItems = selectBody.getSelectItems();
|
||||
List<SelectItem<?>> 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)));
|
||||
selectBody.setSelectItems(Collections.singletonList(new SelectItem(jSqlCount)));
|
||||
|
||||
if (CollectionUtils.isEmpty(selectStatement.getWithItemsList())) {
|
||||
return selectBody.toString();
|
||||
}
|
||||
|
||||
String withStatements = selectStatement.getWithItemsList().stream() //
|
||||
.map(WithItem::toString) //
|
||||
.collect(Collectors.joining(","));
|
||||
|
||||
return "with " + withStatements + "\n" + selectBody;
|
||||
return selectBody.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -435,13 +423,13 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
|
||||
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 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
|
||||
* @param projection the projection to analyse
|
||||
* @return <code>true</code> when the projection only contains a single column definition otherwise <code>false</code>
|
||||
*/
|
||||
private boolean onlyASingleColumnProjection(List<SelectItem> projection) {
|
||||
private boolean onlyASingleColumnProjection(List<SelectItem<?>> 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
|
||||
|
||||
@@ -162,7 +162,7 @@ public class JSqlParserQueryEnhancerUnitTests extends QueryEnhancerTckTests {
|
||||
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 @@ public class JSqlParserQueryEnhancerUnitTests extends QueryEnhancerTckTests {
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user