Skip to content

Commit ca11738

Browse files
committed
Fix EQL and JPQL LIKE with ESCAPE clause parsing.
Closes #3873
1 parent 7fdd89e commit ca11738

File tree

7 files changed

+43
-7
lines changed

7 files changed

+43
-7
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,8 @@ entity_type_literal
709709

710710
escape_character
711711
: CHARACTER
712-
| character_valued_input_parameter //
712+
| string_literal
713+
| character_valued_input_parameter
713714
;
714715

715716
numeric_literal

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,8 @@ entity_type_literal
695695

696696
escape_character
697697
: CHARACTER
698-
| character_valued_input_parameter //
698+
| string_literal
699+
| character_valued_input_parameter
699700
;
700701

701702
numeric_literal

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2336,7 +2336,16 @@ public QueryTokenStream visitEntity_type_literal(EqlParser.Entity_type_literalCo
23362336

23372337
@Override
23382338
public QueryTokenStream visitEscape_character(EqlParser.Escape_characterContext ctx) {
2339-
return QueryTokenStream.ofToken(ctx.CHARACTER());
2339+
2340+
if (ctx.CHARACTER() != null) {
2341+
return QueryTokenStream.ofToken(ctx.CHARACTER());
2342+
} else if (ctx.character_valued_input_parameter() != null) {
2343+
return visit(ctx.character_valued_input_parameter());
2344+
} else if (ctx.string_literal() != null) {
2345+
return visit(ctx.string_literal());
2346+
}
2347+
2348+
return QueryTokenStream.empty();
23402349
}
23412350

23422351
@Override

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2298,7 +2298,16 @@ public QueryTokenStream visitEntity_type_literal(JpqlParser.Entity_type_literalC
22982298

22992299
@Override
23002300
public QueryTokenStream visitEscape_character(JpqlParser.Escape_characterContext ctx) {
2301-
return QueryTokenStream.ofToken(ctx.CHARACTER());
2301+
2302+
if (ctx.CHARACTER() != null) {
2303+
return QueryTokenStream.ofToken(ctx.CHARACTER());
2304+
} else if (ctx.character_valued_input_parameter() != null) {
2305+
return visit(ctx.character_valued_input_parameter());
2306+
} else if (ctx.string_literal() != null) {
2307+
return visit(ctx.string_literal());
2308+
}
2309+
2310+
return QueryTokenStream.empty();
23022311
}
23032312

23042313
@Override

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,14 @@ void signedExpressionsShouldWork(String query) {
11361136
assertQuery(query);
11371137
}
11381138

1139+
@Test // GH-3873
1140+
void escapeClauseShouldWork() {
1141+
assertQuery("select t.name from SomeDbo t where t.name LIKE :name escape '\\\\'");
1142+
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE '\\\\'");
1143+
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE ?1");
1144+
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE :param");
1145+
}
1146+
11391147
@ParameterizedTest // GH-3451
11401148
@MethodSource("reservedWords")
11411149
void entityNameWithPackageContainingReservedWord(String reservedWord) {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919

2020
import java.util.stream.Stream;
2121

22-
import org.antlr.v4.runtime.CharStreams;
23-
import org.antlr.v4.runtime.CommonTokenStream;
24-
import org.junit.jupiter.api.Disabled;
2522
import org.junit.jupiter.api.Test;
2623
import org.junit.jupiter.params.ParameterizedTest;
2724
import org.junit.jupiter.params.provider.Arguments;
@@ -2170,6 +2167,9 @@ void binaryLiteralsShouldWork() {
21702167
@Test // GH-3040
21712168
void escapeClauseShouldWork() {
21722169
assertQuery("select t.name from SomeDbo t where t.name LIKE :name escape '\\\\'");
2170+
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE '\\\\'");
2171+
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE ?1");
2172+
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE :param");
21732173
}
21742174

21752175
@Test // GH-3062, GH-3056

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,6 +1394,14 @@ void signedExpressionsShouldWork(String query) {
13941394
assertQuery(query);
13951395
}
13961396

1397+
@Test // GH-3873
1398+
void escapeClauseShouldWork() {
1399+
assertQuery("select t.name from SomeDbo t where t.name LIKE :name escape '\\\\'");
1400+
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE '\\\\'");
1401+
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE ?1");
1402+
assertQuery("SELECT e FROM SampleEntity e WHERE LOWER(e.label) LIKE LOWER(?1) ESCAPE :param");
1403+
}
1404+
13971405
@ParameterizedTest // GH-3451
13981406
@MethodSource("reservedWords")
13991407
void entityNameWithPackageContainingReservedWord(String reservedWord) {

0 commit comments

Comments
 (0)