Fix EQL and JPQL LIKE with ESCAPE clause parsing.

Closes #3873
This commit is contained in:
Mark Paluch
2025-05-12 09:54:51 +02:00
parent 7d409dbb70
commit 16493ff311
7 changed files with 44 additions and 5 deletions

View File

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

View File

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

View File

@@ -2309,7 +2309,16 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
@Override
public QueryTokenStream visitEscape_character(EqlParser.Escape_characterContext ctx) {
return QueryRendererBuilder.from(QueryTokens.token(ctx.CHARACTER()));
if (ctx.CHARACTER() != null) {
return QueryRendererBuilder.from(QueryTokens.token(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 QueryTokenStream.empty();
}
@Override

View File

@@ -2182,7 +2182,16 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
@Override
public QueryTokenStream visitEscape_character(JpqlParser.Escape_characterContext ctx) {
return QueryRenderer.from(QueryTokens.expression(ctx.CHARACTER()));
if (ctx.CHARACTER() != null) {
return QueryRenderer.from(QueryTokens.expression(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 QueryTokenStream.empty();
}
@Override

View File

@@ -1056,6 +1056,14 @@ class EqlQueryRendererTests {
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
@MethodSource("reservedWords")
void entityNameWithPackageContainingReservedWord(String reservedWord) {

View File

@@ -1801,6 +1801,9 @@ class HqlQueryRendererTests {
@Test // GH-3040
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");
}
@Test // GH-3062, GH-3056

View File

@@ -1049,6 +1049,14 @@ class JpqlQueryRendererTests {
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
@MethodSource("reservedWords")
void entityNameWithPackageContainingReservedWord(String reservedWord) {