Skip to content

Upgrade jsqlparser to 4.8 #3248

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -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<String> joinAliases = getJoinAliases(selectBody);
Set<String> selectionAliases = getSelectionAliases(selectBody);
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -185,8 +183,8 @@ private Set<String> 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());
Expand All @@ -203,9 +201,7 @@ Set<String> getSelectionAliases() {
return new HashSet<>();
}

Select selectStatement = (Select) statement;
PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody();
return this.getSelectionAliases(selectBody);
return this.getSelectionAliases((PlainSelect) statement);
}

/**
Expand All @@ -221,7 +217,7 @@ private Set<String> getJoinAliases(String query) {
}

Select selectStatement = (Select) statement;
if (selectStatement.getSelectBody()instanceof PlainSelect selectBody) {
if (selectStatement instanceof PlainSelect selectBody) {
return getJoinAliases(selectBody);
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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();
}

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

Expand All @@ -394,34 +390,26 @@ public String createCountQueryFor(@Nullable String countProjection) {
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)));

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
Expand All @@ -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);
Expand Down Expand Up @@ -493,11 +481,11 @@ private Select parseSelectStatement(String query) {
* @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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand Down