Reuse parsed SQL statement for alias and projection detection.

Closes #3039
This commit is contained in:
Mark Paluch
2023-06-26 09:38:33 +02:00
parent 57a6f726b4
commit 13a4661bc0

View File

@@ -64,6 +64,7 @@ import org.springframework.util.StringUtils;
public class JSqlParserQueryEnhancer implements QueryEnhancer { public class JSqlParserQueryEnhancer implements QueryEnhancer {
private final DeclaredQuery query; private final DeclaredQuery query;
private final Statement statement;
private final ParsedType parsedType; private final ParsedType parsedType;
/** /**
@@ -72,7 +73,13 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
public JSqlParserQueryEnhancer(DeclaredQuery query) { public JSqlParserQueryEnhancer(DeclaredQuery query) {
this.query = query; this.query = query;
this.parsedType = detectParsedType(); try {
this.statement = CCJSqlParserUtil.parse(this.query.getQueryString());
} catch (JSQLParserException e) {
throw new IllegalArgumentException("The query is not a valid SQL Query", e);
}
this.parsedType = detectParsedType(statement);
} }
/** /**
@@ -80,10 +87,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
* *
* @return the parsed type * @return the parsed type
*/ */
private ParsedType detectParsedType() { private static ParsedType detectParsedType(Statement statement) {
try {
Statement statement = CCJSqlParserUtil.parse(this.query.getQueryString());
if (statement instanceof Insert) { if (statement instanceof Insert) {
return ParsedType.INSERT; return ParsedType.INSERT;
@@ -98,9 +102,6 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
} else { } else {
return ParsedType.OTHER; return ParsedType.OTHER;
} }
} catch (JSQLParserException e) {
throw new IllegalArgumentException("The query you provided is not a valid SQL Query!", e);
}
} }
@Override @Override
@@ -127,9 +128,8 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody(); PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody();
final Set<String> joinAliases = getJoinAliases(selectBody); Set<String> joinAliases = getJoinAliases(selectBody);
Set<String> selectionAliases = getSelectionAliases(selectBody);
final Set<String> selectionAliases = getSelectionAliases(selectBody);
List<OrderByElement> orderByElements = sort.stream() // List<OrderByElement> orderByElements = sort.stream() //
.map(order -> getOrderClause(joinAliases, selectionAliases, alias, order)) // .map(order -> getOrderClause(joinAliases, selectionAliases, alias, order)) //
@@ -203,7 +203,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
return new HashSet<>(); return new HashSet<>();
} }
Select selectStatement = parseSelectStatement(this.query.getQueryString()); Select selectStatement = (Select) statement;
PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody(); PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody();
return this.getSelectionAliases(selectBody); return this.getSelectionAliases(selectBody);
} }
@@ -220,7 +220,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
return new HashSet<>(); return new HashSet<>();
} }
Select selectStatement = parseSelectStatement(query); Select selectStatement = (Select) statement;
if (selectStatement.getSelectBody()instanceof PlainSelect selectBody) { if (selectStatement.getSelectBody()instanceof PlainSelect selectBody) {
return getJoinAliases(selectBody); return getJoinAliases(selectBody);
} }
@@ -306,12 +306,12 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
if (ParsedType.MERGE.equals(this.parsedType)) { if (ParsedType.MERGE.equals(this.parsedType)) {
Merge mergeStatement = parseSelectStatement(query, Merge.class); Merge mergeStatement = (Merge) statement;
return detectAlias(mergeStatement); return detectAlias(mergeStatement);
} else if (ParsedType.SELECT.equals(this.parsedType)) { } else if (ParsedType.SELECT.equals(this.parsedType)) {
Select selectStatement = parseSelectStatement(query); Select selectStatement = (Select) statement;
/* /*
* For all the other types ({@link ValuesStatement} and {@link SetOperationList}) it does not make sense to provide * For all the other types ({@link ValuesStatement} and {@link SetOperationList}) it does not make sense to provide
@@ -319,11 +319,10 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
* ValuesStatement has no alias * ValuesStatement has no alias
* SetOperation can have multiple alias for each operation item * SetOperation can have multiple alias for each operation item
*/ */
if (!(selectStatement.getSelectBody() instanceof PlainSelect)) { if (!(selectStatement.getSelectBody()instanceof PlainSelect selectBody)) {
return null; return null;
} }
PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody();
return detectAlias(selectBody); return detectAlias(selectBody);
} }
@@ -375,12 +374,10 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
/* /*
We only support count queries for {@link PlainSelect}. We only support count queries for {@link PlainSelect}.
*/ */
if (!(selectStatement.getSelectBody() instanceof PlainSelect)) { if (!(selectStatement.getSelectBody()instanceof PlainSelect selectBody)) {
return this.query.getQueryString(); return this.query.getQueryString();
} }
PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody();
// remove order by // remove order by
selectBody.setOrderByElements(null); selectBody.setOrderByElements(null);
@@ -436,7 +433,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
Assert.hasText(query.getQueryString(), "Query must not be null or empty"); Assert.hasText(query.getQueryString(), "Query must not be null or empty");
Select selectStatement = parseSelectStatement(query.getQueryString()); Select selectStatement = (Select) statement;
if (selectStatement.getSelectBody() instanceof ValuesStatement) { if (selectStatement.getSelectBody() instanceof ValuesStatement) {
return ""; return "";