Skip to content

Commit b3701a4

Browse files
committed
Reuse parsed SQL statement for alias and projection detection.
Closes #3039
1 parent 605e532 commit b3701a4

File tree

1 file changed

+31
-34
lines changed

1 file changed

+31
-34
lines changed

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
public class JSqlParserQueryEnhancer implements QueryEnhancer {
6565

6666
private final DeclaredQuery query;
67+
private final Statement statement;
6768
private final ParsedType parsedType;
6869

6970
/**
@@ -72,34 +73,34 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
7273
public JSqlParserQueryEnhancer(DeclaredQuery query) {
7374

7475
this.query = query;
75-
this.parsedType = detectParsedType();
76+
try {
77+
this.statement = CCJSqlParserUtil.parse(this.query.getQueryString());
78+
} catch (JSQLParserException e) {
79+
throw new IllegalArgumentException("The query is not a valid SQL Query", e);
80+
}
81+
82+
this.parsedType = detectParsedType(statement);
7683
}
7784

7885
/**
7986
* Detects what type of query is provided.
8087
*
8188
* @return the parsed type
8289
*/
83-
private ParsedType detectParsedType() {
84-
85-
try {
86-
Statement statement = CCJSqlParserUtil.parse(this.query.getQueryString());
87-
88-
if (statement instanceof Insert) {
89-
return ParsedType.INSERT;
90-
} else if (statement instanceof Update) {
91-
return ParsedType.UPDATE;
92-
} else if (statement instanceof Delete) {
93-
return ParsedType.DELETE;
94-
} else if (statement instanceof Select) {
95-
return ParsedType.SELECT;
96-
} else if (statement instanceof Merge) {
97-
return ParsedType.MERGE;
98-
} else {
99-
return ParsedType.OTHER;
100-
}
101-
} catch (JSQLParserException e) {
102-
throw new IllegalArgumentException("The query you provided is not a valid SQL Query!", e);
90+
private static ParsedType detectParsedType(Statement statement) {
91+
92+
if (statement instanceof Insert) {
93+
return ParsedType.INSERT;
94+
} else if (statement instanceof Update) {
95+
return ParsedType.UPDATE;
96+
} else if (statement instanceof Delete) {
97+
return ParsedType.DELETE;
98+
} else if (statement instanceof Select) {
99+
return ParsedType.SELECT;
100+
} else if (statement instanceof Merge) {
101+
return ParsedType.MERGE;
102+
} else {
103+
return ParsedType.OTHER;
103104
}
104105
}
105106

@@ -127,9 +128,8 @@ public String applySorting(Sort sort, @Nullable String alias) {
127128

128129
PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody();
129130

130-
final Set<String> joinAliases = getJoinAliases(selectBody);
131-
132-
final Set<String> selectionAliases = getSelectionAliases(selectBody);
131+
Set<String> joinAliases = getJoinAliases(selectBody);
132+
Set<String> selectionAliases = getSelectionAliases(selectBody);
133133

134134
List<OrderByElement> orderByElements = sort.stream() //
135135
.map(order -> getOrderClause(joinAliases, selectionAliases, alias, order)) //
@@ -203,7 +203,7 @@ Set<String> getSelectionAliases() {
203203
return new HashSet<>();
204204
}
205205

206-
Select selectStatement = parseSelectStatement(this.query.getQueryString());
206+
Select selectStatement = (Select) statement;
207207
PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody();
208208
return this.getSelectionAliases(selectBody);
209209
}
@@ -220,7 +220,7 @@ private Set<String> getJoinAliases(String query) {
220220
return new HashSet<>();
221221
}
222222

223-
Select selectStatement = parseSelectStatement(query);
223+
Select selectStatement = (Select) statement;
224224
if (selectStatement.getSelectBody()instanceof PlainSelect selectBody) {
225225
return getJoinAliases(selectBody);
226226
}
@@ -306,24 +306,23 @@ private String detectAlias(String query) {
306306

307307
if (ParsedType.MERGE.equals(this.parsedType)) {
308308

309-
Merge mergeStatement = parseSelectStatement(query, Merge.class);
309+
Merge mergeStatement = (Merge) statement;
310310
return detectAlias(mergeStatement);
311311

312312
} else if (ParsedType.SELECT.equals(this.parsedType)) {
313313

314-
Select selectStatement = parseSelectStatement(query);
314+
Select selectStatement = (Select) statement;
315315

316316
/*
317317
* For all the other types ({@link ValuesStatement} and {@link SetOperationList}) it does not make sense to provide
318318
* alias since:
319319
* ValuesStatement has no alias
320320
* SetOperation can have multiple alias for each operation item
321321
*/
322-
if (!(selectStatement.getSelectBody() instanceof PlainSelect)) {
322+
if (!(selectStatement.getSelectBody()instanceof PlainSelect selectBody)) {
323323
return null;
324324
}
325325

326-
PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody();
327326
return detectAlias(selectBody);
328327
}
329328

@@ -375,12 +374,10 @@ public String createCountQueryFor(@Nullable String countProjection) {
375374
/*
376375
We only support count queries for {@link PlainSelect}.
377376
*/
378-
if (!(selectStatement.getSelectBody() instanceof PlainSelect)) {
377+
if (!(selectStatement.getSelectBody()instanceof PlainSelect selectBody)) {
379378
return this.query.getQueryString();
380379
}
381380

382-
PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody();
383-
384381
// remove order by
385382
selectBody.setOrderByElements(null);
386383

@@ -436,7 +433,7 @@ public String getProjection() {
436433

437434
Assert.hasText(query.getQueryString(), "Query must not be null or empty");
438435

439-
Select selectStatement = parseSelectStatement(query.getQueryString());
436+
Select selectStatement = (Select) statement;
440437

441438
if (selectStatement.getSelectBody() instanceof ValuesStatement) {
442439
return "";

0 commit comments

Comments
 (0)