Skip to content
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

Fix for Jakarta data issue #2182 #2223

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.JPAVersion;
import org.eclipse.persistence.jpa.jpql.WordParser;
Expand Down Expand Up @@ -421,9 +424,81 @@ protected void toParsedText(StringBuilder writer, boolean actual) {
private CharSequence preParse(CharSequence jpqlFragment) {
WordParser wordParser = new WordParser(jpqlFragment);
wordParser.skipLeadingWhitespace();
// Check if the query is a FROM statement
if (Expression.FROM.equalsIgnoreCase(wordParser.word())) {
return Expression.SELECT + " " + Expression.THIS + " " + jpqlFragment;
}
// Check if the query is a SELECT statement
if (Expression.SELECT.equalsIgnoreCase(wordParser.word())) {
// Extract the query string
String query = jpqlFragment.toString();
String selectClause = "SELECT ";
String fromClause = " FROM ";
int selectIndex = query.indexOf(selectClause);
int fromIndex = query.indexOf(fromClause, selectIndex);
if (fromIndex > selectIndex) {
String fields = query.substring(selectIndex + selectClause.length(), fromIndex).trim();
// If the fields already contain 'this', no need to modify
if (fields.contains("this")||fields.contains(".")) {
return query;
}
// Check if the query contains an alias
if (containsAlias(query)) {
return query;
}
// Add 'this.' to each field, handling edge cases
String[] fieldArray = fields.split("\\s*,\\s*"); // Split on commas with optional spaces
StringBuilder modifiedFields = new StringBuilder();
for (String field : fieldArray) {
if (modifiedFields.length() > 0) {
modifiedFields.append(", ");
}
String trimmedField = field.trim();
if (isPlainField(trimmedField)) {
modifiedFields.append("this.").append(trimmedField);
} else {
modifiedFields.append(trimmedField);
}
}
// Construct the final query
String finalQuery = selectClause + modifiedFields.toString() + query.substring(fromIndex);
return finalQuery;
}
}
return jpqlFragment;
}
// Helper method to determine if a field is a plain identifier
private boolean isPlainField(String field) {
// A plain field is one that does not contain functions or special characters
return !field.contains("(") && !field.contains(" ");
}
public static boolean containsAlias(String jpqlQuery) {
// Regular expression to match JPQL FROM clause and potential aliases
String fromClausePattern = "FROM\\s+([\\w\\.]+)\\s+(\\w+)";
// List of common JPQL keywords to exclude as aliases
String[] jpqlKeywords = {"WHERE", "GROUP BY", "ORDER BY", "HAVING", "JOIN"};
// Compile pattern and create matcher
Pattern pattern = Pattern.compile(fromClausePattern, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(jpqlQuery);
// Check if the query matches the pattern
if (matcher.find()) {
// Extract the table name and alias
String tableName = matcher.group(1);
String alias = matcher.group(2);
// Return true if alias is found
if (alias != null && !alias.trim().isEmpty()){
// Check if the alias is not a JPQL keyword
for (String keyword : jpqlKeywords) {
if (alias.equals(keyword)) {
return false;
}
}
return true;
}
}
// Return false if no alias is found
return false;
}
}


Loading