Skip to content

Commit

Permalink
Issue #420 Like Expression with Escape Expression (#1406)
Browse files Browse the repository at this point in the history
* Issue #420 Like Expression with Escape Expression

Fixes issue #420

* CheckStyle compliance
  • Loading branch information
manticore-projects authored Nov 19, 2021
1 parent 9adab8d commit 8eaa4d2
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 12 deletions.
19 changes: 19 additions & 0 deletions src/main/java/net/sf/jsqlparser/expression/StringValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import net.sf.jsqlparser.parser.ASTNodeAccessImpl;

/**
Expand Down Expand Up @@ -95,4 +97,21 @@ public StringValue withValue(String value) {
this.setValue(value);
return this;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
StringValue that = (StringValue) o;
return Objects.equals(value, that.value) && Objects.equals(prefix, that.prefix);
}

@Override
public int hashCode() {
return Objects.hash(value, prefix);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
public class LikeExpression extends BinaryExpression {

private boolean not = false;
private String escape = null;
private Expression escapeExpression = null;
private boolean caseInsensitive = false;

public boolean isNot() {
Expand All @@ -40,19 +40,19 @@ public String getStringExpression() {
@Override
public String toString() {
String retval = getLeftExpression() + " " + (not ? "NOT " : "") + getStringExpression() + " " + getRightExpression();
if (escape != null) {
retval += " ESCAPE " + "'" + escape + "'";
if (escapeExpression != null) {
retval += " ESCAPE " + escapeExpression ;
}

return retval;
}

public String getEscape() {
return escape;
public Expression getEscape() {
return escapeExpression;
}

public void setEscape(String escape) {
this.escape = escape;
public void setEscape(Expression escapeExpression) {
this.escapeExpression = escapeExpression;
}

public boolean isCaseInsensitive() {
Expand All @@ -63,7 +63,7 @@ public void setCaseInsensitive(boolean caseInsensitive) {
this.caseInsensitive = caseInsensitive;
}

public LikeExpression withEscape(String escape) {
public LikeExpression withEscape(Expression escape) {
this.setEscape(escape);
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,10 @@ public void visit(JdbcParameter jdbcParameter) {
public void visit(LikeExpression likeExpression) {
visitBinaryExpression(likeExpression,
(likeExpression.isNot() ? " NOT" : "") + (likeExpression.isCaseInsensitive() ? " ILIKE " : " LIKE "));
String escape = likeExpression.getEscape();
Expression escape = likeExpression.getEscape();
if (escape != null) {
buffer.append(" ESCAPE '").append(escape).append('\'');
buffer.append(" ESCAPE ");
likeExpression.getEscape().accept(this);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -3198,10 +3198,11 @@ Expression LikeExpression(Expression leftExpression) #LikeExpression:
{
LikeExpression result = new LikeExpression();
Expression rightExpression = null;
Expression escape;
}
{
[<K_NOT> { result.setNot(true); } ] ( <K_LIKE> | <K_ILIKE> { result.setCaseInsensitive(true); } ) rightExpression=SimpleExpression()
[<K_ESCAPE> token=<S_CHAR_LITERAL> { result.setEscape((new StringValue(token.image)).getValue()); }]
[<K_ESCAPE> escape=Expression() { result.setEscape(escape); }]
{
result.setLeftExpression(leftExpression);
result.setRightExpression(rightExpression);
Expand Down
28 changes: 28 additions & 0 deletions src/test/java/net/sf/jsqlparser/expression/LikeExpressionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2021 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/

package net.sf.jsqlparser.expression;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.test.TestUtils;
import org.junit.Test;

/**
*
* @author <a href="mailto:andreas@manticore-projects.com">Andreas Reichel</a>
*/
public class LikeExpressionTest {
@Test
public void testLikeWithEscapeExpressionIssue420() throws JSQLParserException {
TestUtils.assertExpressionCanBeParsedAndDeparsed("a LIKE ?1 ESCAPE ?2", true);

TestUtils.assertSqlCanBeParsedAndDeparsed("select * from dual where a LIKE ?1 ESCAPE ?2", true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1446,7 +1446,7 @@ public void testLike() throws JSQLParserException {
plainSelect = (PlainSelect) select.getSelectBody();
assertEquals("test", ((StringValue) ((LikeExpression) plainSelect.getWhere()).
getRightExpression()).getValue());
assertEquals("test2", ((LikeExpression) plainSelect.getWhere()).getEscape());
assertEquals(new StringValue("test2"), ((LikeExpression) plainSelect.getWhere()).getEscape());
}

@Test
Expand Down

0 comments on commit 8eaa4d2

Please sign in to comment.