Skip to content

Commit cdf805f

Browse files
committed
fixes #789
1 parent c22dda1 commit cdf805f

File tree

7 files changed

+108
-8
lines changed

7 files changed

+108
-8
lines changed

src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
3838
import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator;
3939
import net.sf.jsqlparser.expression.operators.relational.RegExpMySQLOperator;
40+
import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression;
4041
import net.sf.jsqlparser.schema.Column;
4142
import net.sf.jsqlparser.statement.select.SubSelect;
4243

@@ -172,4 +173,6 @@ public interface ExpressionVisitor {
172173

173174
public void visit(CollateExpression aThis);
174175

176+
public void visit(SimilarToExpression aThis);
177+
175178
}

src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,4 +501,9 @@ public void visit(NextValExpression nextVal) {
501501
public void visit(CollateExpression col) {
502502
col.getLeftExpression().accept(this);
503503
}
504+
505+
@Override
506+
public void visit(SimilarToExpression expr) {
507+
visitBinaryExpression(expr);
508+
}
504509
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2019 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.expression.operators.relational;
11+
12+
import net.sf.jsqlparser.expression.BinaryExpression;
13+
import net.sf.jsqlparser.expression.ExpressionVisitor;
14+
15+
public class SimilarToExpression extends BinaryExpression {
16+
17+
private boolean not = false;
18+
private String escape = null;
19+
20+
public boolean isNot() {
21+
return not;
22+
}
23+
24+
public void setNot(boolean b) {
25+
not = b;
26+
}
27+
28+
@Override
29+
public void accept(ExpressionVisitor expressionVisitor) {
30+
expressionVisitor.visit(this);
31+
}
32+
33+
@Override
34+
public String getStringExpression() {
35+
return "SIMILAR TO";
36+
}
37+
38+
@Override
39+
public String toString() {
40+
String retval = getLeftExpression() + " " + (not ? "NOT " : "") + getStringExpression() + " " + getRightExpression();
41+
if (escape != null) {
42+
retval += " ESCAPE " + "'" + escape + "'";
43+
}
44+
45+
return retval;
46+
}
47+
48+
public String getEscape() {
49+
return escape;
50+
}
51+
52+
public void setEscape(String escape) {
53+
this.escape = escape;
54+
}
55+
}

src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
8282
import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator;
8383
import net.sf.jsqlparser.expression.operators.relational.RegExpMySQLOperator;
84+
import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression;
8485
import net.sf.jsqlparser.schema.Column;
8586
import net.sf.jsqlparser.schema.Table;
8687
import net.sf.jsqlparser.statement.Block;
@@ -856,4 +857,9 @@ public void visit(CollateExpression col) {
856857
@Override
857858
public void visit(ShowStatement aThis) {
858859
}
860+
861+
@Override
862+
public void visit(SimilarToExpression expr) {
863+
visitBinaryExpression(expr);
864+
}
859865
}

src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
import net.sf.jsqlparser.expression.operators.relational.OldOracleJoinBinaryExpression;
8484
import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator;
8585
import net.sf.jsqlparser.expression.operators.relational.RegExpMySQLOperator;
86+
import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression;
8687
import net.sf.jsqlparser.expression.operators.relational.SupportsOldOracleJoinSyntax;
8788
import net.sf.jsqlparser.schema.Column;
8889
import net.sf.jsqlparser.schema.Table;
@@ -346,9 +347,6 @@ public void visit(Subtraction subtraction) {
346347
}
347348

348349
protected void visitBinaryExpression(BinaryExpression binaryExpression, String operator) {
349-
// if (binaryExpression.isNot()) {
350-
// buffer.append(NOT);
351-
// }
352350
binaryExpression.getLeftExpression().accept(this);
353351
buffer.append(operator);
354352
binaryExpression.getRightExpression().accept(this);
@@ -797,4 +795,9 @@ public void visit(CollateExpression col) {
797795
buffer.append(col.getLeftExpression().toString()).append(" COLLATE ").append(col.getCollate());
798796
}
799797

798+
@Override
799+
public void visit(SimilarToExpression expr) {
800+
visitBinaryExpression(expr, (expr.isNot() ? " NOT" : "") + " SIMILAR TO ");
801+
}
802+
800803
}

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

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
252252
| <K_SETS:"SETS">
253253
| <K_SHOW : "SHOW">
254254
| <K_SIBLINGS:"SIBLINGS">
255+
| <K_SIMILAR:"SIMILAR">
255256
| <K_SKIP: "SKIP">
256257
| <K_SOME:"SOME">
257258
| <K_START:"START">
@@ -261,6 +262,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
261262
| <K_TEMP:"TEMP">
262263
| <K_TEMPORARY:"TEMPORARY">
263264
| <K_TIME_KEY_EXPR : ( "CURRENT_TIMESTAMP" | "CURRENT_TIME" | "CURRENT_DATE" ) ( "()" )?>
265+
| <K_TO:"TO">
264266
| <K_TOP:"TOP">
265267
| <K_TRAILING:"TRAILING">
266268
| <K_TRUNCATE:"TRUNCATE">
@@ -2260,11 +2262,12 @@ Expression SQLCondition():
22602262
}
22612263
{
22622264
(
2263-
LOOKAHEAD(InExpression()) result=InExpression()
2265+
result=ExistsExpression()
2266+
| LOOKAHEAD(InExpression()) result=InExpression()
22642267
| LOOKAHEAD(Between()) result=Between()
22652268
| LOOKAHEAD(IsNullExpression()) result=IsNullExpression()
2266-
| LOOKAHEAD(ExistsExpression()) result=ExistsExpression()
2267-
| result=LikeExpression()
2269+
| LOOKAHEAD(3) result=LikeExpression()
2270+
| result=SimilarToExpression()
22682271
)
22692272
{ return result; }
22702273
}
@@ -2334,6 +2337,26 @@ Expression LikeExpression() #LikeExpression:
23342337
}
23352338
}
23362339

2340+
Expression SimilarToExpression() #SimilarToExpression:
2341+
{
2342+
SimilarToExpression result = new SimilarToExpression();
2343+
Expression leftExpression = null;
2344+
Expression rightExpression = null;
2345+
}
2346+
{
2347+
leftExpression=SimpleExpression()
2348+
[<K_NOT> { result.setNot(true); } ]
2349+
<K_SIMILAR> <K_TO>
2350+
rightExpression=SimpleExpression()
2351+
[<K_ESCAPE> token=<S_CHAR_LITERAL> { result.setEscape((new StringValue(token.image)).getValue()); }]
2352+
{
2353+
result.setLeftExpression(leftExpression);
2354+
result.setRightExpression(rightExpression);
2355+
linkAST(result,jjtThis);
2356+
return result;
2357+
}
2358+
}
2359+
23372360
Expression IsNullExpression():
23382361
{
23392362
IsNullExpression result = new IsNullExpression();

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3631,7 +3631,12 @@ public void testSubQueryAliasIssue754() throws JSQLParserException {
36313631
}
36323632

36333633
@Test
3634-
public void testSubQueryOrderByIssue705() throws JSQLParserException {
3635-
assertSqlCanBeParsedAndDeparsed("SELECT a.* FROM ((SELECT T1.SACOJA FROM SOLARB t1) ORDER BY sacoja ASC) a");
3634+
public void testSimilarToIssue789() throws JSQLParserException {
3635+
assertSqlCanBeParsedAndDeparsed("SELECT * FROM mytable WHERE (w_id SIMILAR TO '/foo/__/bar/(left|right)/[0-9]{4}-[0-9]{2}-[0-9]{2}(/[0-9]*)?')");
3636+
}
3637+
3638+
@Test
3639+
public void testSimilarToIssue789_2() throws JSQLParserException {
3640+
assertSqlCanBeParsedAndDeparsed("SELECT * FROM mytable WHERE (w_id NOT SIMILAR TO '/foo/__/bar/(left|right)/[0-9]{4}-[0-9]{2}-[0-9]{2}(/[0-9]*)?')");
36363641
}
36373642
}

0 commit comments

Comments
 (0)