Upgrade to JSqlParser 4.8

Closes: #3340
Original Pull Request: #3248
This commit is contained in:
Yanming Zhou
2023-11-29 15:03:37 +08:00
committed by Christoph Strobl
parent 6063c73d5d
commit c5aa790e39
3 changed files with 28 additions and 40 deletions

View File

@@ -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>

View File

@@ -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

View File

@@ -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();