Browse Source

Fix EQL and JPQL LIKE with ESCAPE clause parsing.

Closes #3873
3.3.x
Mark Paluch 9 months ago
parent
commit
8e95f2e5be
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 3
      spring-data-jpa/src/main/antlr4/org/springframework/data/jpa/repository/query/Eql.g4
  2. 5
      spring-data-jpa/src/main/antlr4/org/springframework/data/jpa/repository/query/Jpql.g4
  3. 11
      spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/EqlQueryRenderer.java
  4. 11
      spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryRenderer.java
  5. 8
      spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlQueryRendererTests.java
  6. 3
      spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/HqlQueryRendererTests.java
  7. 8
      spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlQueryRendererTests.java

3
spring-data-jpa/src/main/antlr4/org/springframework/data/jpa/repository/query/Eql.g4

@ -677,7 +677,8 @@ entity_type_literal
escape_character escape_character
: CHARACTER : CHARACTER
| character_valued_input_parameter // | string_literal
| character_valued_input_parameter
; ;
numeric_literal numeric_literal

5
spring-data-jpa/src/main/antlr4/org/springframework/data/jpa/repository/query/Jpql.g4

@ -653,7 +653,8 @@ entity_type_literal
escape_character escape_character
: CHARACTER : CHARACTER
| character_valued_input_parameter // | string_literal
| character_valued_input_parameter
; ;
numeric_literal numeric_literal
@ -949,7 +950,7 @@ NOT_EQUAL : '<>' | '!=' ;
CHARACTER : '\'' (~ ('\'' | '\\')) '\'' ; CHARACTER : '\'' (~ ('\'' | '\\')) '\'' ;
IDENTIFICATION_VARIABLE : ('a' .. 'z' | 'A' .. 'Z' | '\u0080' .. '\ufffe' | '$' | '_') ('a' .. 'z' | 'A' .. 'Z' | '\u0080' .. '\ufffe' | '0' .. '9' | '$' | '_')* ; IDENTIFICATION_VARIABLE : ('a' .. 'z' | 'A' .. 'Z' | '\u0080' .. '\ufffe' | '$' | '_') ('a' .. 'z' | 'A' .. 'Z' | '\u0080' .. '\ufffe' | '0' .. '9' | '$' | '_')* ;
STRINGLITERAL : '\'' (~ ('\'' | '\\'))* '\'' ; STRINGLITERAL : '\'' (~ ('\'' | '\\')|'\\')* '\'' ;
JAVASTRINGLITERAL : '"' ( ('\\' [btnfr"']) | ~('"'))* '"'; JAVASTRINGLITERAL : '"' ( ('\\' [btnfr"']) | ~('"'))* '"';
FLOATLITERAL : ('0' .. '9')* '.' ('0' .. '9')+ (E ('0' .. '9')+)* (F|D)?; FLOATLITERAL : ('0' .. '9')* '.' ('0' .. '9')+ (E ('0' .. '9')+)* (F|D)?;
INTLITERAL : ('0' .. '9')+ ; INTLITERAL : ('0' .. '9')+ ;

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

@ -2418,7 +2418,16 @@ class EqlQueryRenderer extends EqlBaseVisitor<List<JpaQueryParsingToken>> {
@Override @Override
public List<JpaQueryParsingToken> visitEscape_character(EqlParser.Escape_characterContext ctx) { public List<JpaQueryParsingToken> visitEscape_character(EqlParser.Escape_characterContext ctx) {
return List.of(new JpaQueryParsingToken(ctx.CHARACTER()));
if (ctx.CHARACTER() != null) {
return List.of(new JpaQueryParsingToken(ctx.CHARACTER()));
} else if (ctx.character_valued_input_parameter() != null) {
return visit(ctx.character_valued_input_parameter());
} else if (ctx.string_literal() != null) {
return visit(ctx.string_literal());
}
return List.of();
} }
@Override @Override

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

@ -2225,7 +2225,16 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<List<JpaQueryParsingToken>> {
@Override @Override
public List<JpaQueryParsingToken> visitEscape_character(JpqlParser.Escape_characterContext ctx) { public List<JpaQueryParsingToken> visitEscape_character(JpqlParser.Escape_characterContext ctx) {
return List.of(new JpaQueryParsingToken(ctx.CHARACTER()));
if (ctx.CHARACTER() != null) {
return List.of(new JpaQueryParsingToken(ctx.CHARACTER()));
} else if (ctx.character_valued_input_parameter() != null) {
return visit(ctx.character_valued_input_parameter());
} else if (ctx.string_literal() != null) {
return visit(ctx.string_literal());
}
return List.of();
} }
@Override @Override

8
spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/EqlQueryRendererTests.java

@ -1038,6 +1038,14 @@ class EqlQueryRendererTests {
assertQuery(query); assertQuery(query);
} }
@Test // GH-3873
void escapeClauseShouldWork() {
assertQuery("select t.name from SomeDbo t where t.name LIKE :name escape '\\\\'");
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE '\\\\'");
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE ?1");
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE :param");
}
@ParameterizedTest // GH-3451 @ParameterizedTest // GH-3451
@MethodSource("reservedWords") @MethodSource("reservedWords")
void entityNameWithPackageContainingReservedWord(String reservedWord) { void entityNameWithPackageContainingReservedWord(String reservedWord) {

3
spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/HqlQueryRendererTests.java

@ -1569,6 +1569,9 @@ class HqlQueryRendererTests {
@Test // GH-3040 @Test // GH-3040
void escapeClauseShouldWork() { void escapeClauseShouldWork() {
assertQuery("select t.name from SomeDbo t where t.name LIKE :name escape '\\\\'"); assertQuery("select t.name from SomeDbo t where t.name LIKE :name escape '\\\\'");
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE '\\\\'");
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE ?1");
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE :param");
} }
@Test // GH-3062, GH-3056 @Test // GH-3062, GH-3056

8
spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpqlQueryRendererTests.java

@ -1046,6 +1046,14 @@ class JpqlQueryRendererTests {
assertQuery(query); assertQuery(query);
} }
@Test // GH-3873
void escapeClauseShouldWork() {
assertQuery("select t.name from SomeDbo t where t.name LIKE :name escape '\\\\'");
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE '\\\\'");
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE ?1");
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE :param");
}
@ParameterizedTest // GH-3451 @ParameterizedTest // GH-3451
@MethodSource("reservedWords") @MethodSource("reservedWords")
void entityNameWithPackageContainingReservedWord(String reservedWord) { void entityNameWithPackageContainingReservedWord(String reservedWord) {

Loading…
Cancel
Save