Skip to content

Commit daea33e

Browse files
tomershaywumpz
authored andcommitted
Add ability to support "NOT LIKE ..." expressions (#539)
The parser is able to parse expressions such as "a NOT LIKE '%pattern%'", but is not able to parse expressions where the not is before the entire expression. For example: "NOT a LIKE '%pattern%'. When parsing the latter, the error is: Caused by: net.sf.jsqlparser.parser.ParseException: Encountered " "LIKE" "LIKE "" at line 1, column 32. Was expecting one of: ... The reason this is important is both because these syntaxes are both valid, and also because the deparser uses the second method. Therefore, if you parse a query with the first type of expression, then deparse it and parse again, you'll get the same error.
1 parent 452baff commit daea33e

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2084,9 +2084,18 @@ Expression LikeExpression() #LikeExpression:
20842084
Expression rightExpression = null;
20852085
}
20862086
{
2087-
leftExpression=SimpleExpression()
2088-
[<K_NOT> { result.setNot(true); } ] ( <K_LIKE> | <K_ILIKE> { result.setCaseInsensitive(true); } ) rightExpression=SimpleExpression()
2089-
[<K_ESCAPE> token=<S_CHAR_LITERAL> { result.setEscape((new StringValue(token.image)).getValue()); }]
2087+
(
2088+
(
2089+
leftExpression=SimpleExpression()
2090+
[<K_NOT> { result.setNot(true); } ] ( <K_LIKE> | <K_ILIKE> { result.setCaseInsensitive(true); } ) rightExpression=SimpleExpression()
2091+
[<K_ESCAPE> token=<S_CHAR_LITERAL> { result.setEscape((new StringValue(token.image)).getValue()); }]
2092+
)
2093+
|
2094+
(
2095+
[<K_NOT> { result.setNot(true); } ] leftExpression=SimpleExpression() ( <K_LIKE> | <K_ILIKE> { result.setCaseInsensitive(true); } ) rightExpression=SimpleExpression()
2096+
[<K_ESCAPE> token=<S_CHAR_LITERAL> { result.setEscape((new StringValue(token.image)).getValue()); }]
2097+
)
2098+
)
20902099
{
20912100
result.setLeftExpression(leftExpression);
20922101
result.setRightExpression(rightExpression);

src/test/java/net/sf/jsqlparser/test/select/SelectTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,24 @@ public void testLike() throws JSQLParserException {
11921192
assertEquals("test2", ((LikeExpression) plainSelect.getWhere()).getEscape());
11931193
}
11941194

1195+
public void testNotLike() throws JSQLParserException {
1196+
String statement = "SELECT * FROM tab1 WHERE a NOT LIKE 'test'";
1197+
Select select = (Select) parserManager.parse(new StringReader(statement));
1198+
PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
1199+
assertEquals("test", ((StringValue) ((LikeExpression) plainSelect.getWhere()).
1200+
getRightExpression()).getValue());
1201+
assertEquals(true, (boolean) ((LikeExpression) plainSelect.getWhere()).isNot());
1202+
}
1203+
1204+
public void testNotLikeWithNotBeforeExpression() throws JSQLParserException {
1205+
String statement = "SELECT * FROM tab1 WHERE NOT a LIKE 'test'";
1206+
Select select = (Select) parserManager.parse(new StringReader(statement));
1207+
PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
1208+
assertEquals("test", ((StringValue) ((LikeExpression) plainSelect.getWhere()).
1209+
getRightExpression()).getValue());
1210+
assertEquals(true, (boolean) ((LikeExpression) plainSelect.getWhere()).isNot());
1211+
}
1212+
11951213
public void testIlike() throws JSQLParserException {
11961214
String statement = "SELECT col1 FROM table1 WHERE col1 ILIKE '%hello%'";
11971215
assertSqlCanBeParsedAndDeparsed(statement);

0 commit comments

Comments
 (0)