Resolve handling of ESCAPE clause with LIKE queries on Hibernate.

The HQL parser has to handle parameters in addition to character values in order to support SpEL.

Closes #2954
Original Pull Request: #2956.
This commit is contained in:
Greg L. Turnquist
2023-05-15 14:12:19 -05:00
committed by Mark Paluch
parent e0cfe41095
commit 38ced42d6a
6 changed files with 28 additions and 9 deletions

View File

@@ -579,7 +579,7 @@ dealingWithNullExpression
// https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#hql-like-predicate
stringPatternMatching
: expression NOT? (LIKE | ILIKE) expression (ESCAPE character)?
: expression NOT? (LIKE | ILIKE) expression (ESCAPE expression)?
;
// https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#hql-elements-indices

View File

@@ -2124,7 +2124,7 @@ class HqlQueryRenderer extends HqlBaseVisitor<List<JpaQueryParsingToken>> {
if (ctx.ESCAPE() != null) {
tokens.add(new JpaQueryParsingToken(ctx.ESCAPE()));
tokens.addAll(visit(ctx.character()));
tokens.addAll(visit(ctx.expression(2)));
}
return tokens;

View File

@@ -1206,6 +1206,12 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<List<JpaQueryParsingToken>> {
tokens.add(new JpaQueryParsingToken(ctx.LIKE()));
tokens.addAll(visit(ctx.pattern_value()));
if (ctx.ESCAPE() != null) {
tokens.add(new JpaQueryParsingToken(ctx.ESCAPE()));
tokens.addAll(visit(ctx.escape_character()));
}
return tokens;
}

View File

@@ -34,4 +34,22 @@ class EclipseLinkUserRepositoryFinderTests extends UserRepositoryFinderTests {
@Disabled
@Override
void executesInKeywordForPageCorrectly() {}
@Disabled("Can't get ESCAPE clause working with EclipseLink. See #2955")
@Override
void escapingInLikeSpels() {
super.escapingInLikeSpels();
}
@Disabled("Can't get ESCAPE clause working with EclipseLink. See #2955")
@Override
void escapingInLikeSpelsInThePresenceOfEscapeCharacters() {
super.escapingInLikeSpelsInThePresenceOfEscapeCharacters();
}
@Disabled("Can't get ESCAPE clause working with EclipseLink. See #2955")
@Override
void escapingInLikeSpelsInThePresenceOfEscapedWildcards() {
super.escapingInLikeSpelsInThePresenceOfEscapedWildcards();
}
}

View File

@@ -25,7 +25,6 @@ import java.util.List;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -235,7 +234,6 @@ class UserRepositoryFinderTests {
.isEmpty();
}
@Disabled("Can't get ESCAPE clause working with Hibernate")
@Test // DATAJPA-1519
void escapingInLikeSpels() {
@@ -246,7 +244,6 @@ class UserRepositoryFinderTests {
assertThat(userRepository.findContainingEscaped("att_")).containsExactly(extra);
}
@Disabled("Can't get ESCAPE clause working with Hibernate")
@Test // DATAJPA-1522
void escapingInLikeSpelsInThePresenceOfEscapeCharacters() {
@@ -256,7 +253,6 @@ class UserRepositoryFinderTests {
assertThat(userRepository.findContainingEscaped("att\\x")).containsExactly(withEscapeCharacter);
}
@Disabled("Can't get ESCAPE clause working with Hibernate")
@Test // DATAJPA-1522
void escapingInLikeSpelsInThePresenceOfEscapedWildcards() {
@@ -288,8 +284,7 @@ class UserRepositoryFinderTests {
List<RolesAndFirstname> rolesAndFirstnameBy = userRepository.findRolesAndFirstnameBy();
assertThat(rolesAndFirstnameBy)
.isNotNull();
assertThat(rolesAndFirstnameBy).isNotNull();
for (RolesAndFirstname rolesAndFirstname : rolesAndFirstnameBy) {
assertThat(rolesAndFirstname.getFirstname()).isNotNull();

View File

@@ -625,7 +625,7 @@ public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecifi
List<NameOnlyDto> findByNamedQueryWithConstructorExpression();
// DATAJPA-1519
@Query("select u from User u where u.lastname like '%?#{escape([0])}%' escape ?#{escapeCharacter()}")
@Query("select u from User u where u.lastname like %?#{escape([0])}% escape ?#{escapeCharacter()}")
List<User> findContainingEscaped(String namePart);
// DATAJPA-1303