Skip to content

Commit 59aa40f

Browse files
committed
fix(parser): parse Oracle outer join operator (+) after LIKE / SIMILAR TO operands (#2598)
Signed-off-by: 付典 <fudianchn@gmail.com>
1 parent 7cc8638 commit 59aa40f

2 files changed

Lines changed: 105 additions & 0 deletions

File tree

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8672,6 +8672,15 @@ Expression LikeExpression(Expression leftExpression) #LikeExpression:
86728672
) { result.setLikeKeyWord( LikeExpression.KeyWord.from(token.image)); }
86738673
[ LOOKAHEAD(2) <K_BINARY> {result.setUseBinary(true); } ]
86748674
rightExpression=SimpleExpression()
8675+
[
8676+
LOOKAHEAD("(" "+" ")")
8677+
"(" "+" ")"
8678+
{
8679+
if (rightExpression instanceof Column) {
8680+
((Column) rightExpression).setOldOracleJoinSyntax(EqualsTo.ORACLE_JOIN_RIGHT);
8681+
}
8682+
}
8683+
]
86758684
[ LOOKAHEAD(2) <K_ESCAPE>
86768685
(
86778686
LOOKAHEAD(2) token = <S_CHAR_LITERAL> { result.setEscape( new StringValue( token.image ) ); }
@@ -8696,6 +8705,15 @@ Expression SimilarToExpression(Expression leftExpression) #SimilarToExpression:
86968705
[<K_NOT> { result.setNot(true); } ]
86978706
<K_SIMILAR> <K_TO>
86988707
rightExpression=SimpleExpression()
8708+
[
8709+
LOOKAHEAD("(" "+" ")")
8710+
"(" "+" ")"
8711+
{
8712+
if (rightExpression instanceof Column) {
8713+
((Column) rightExpression).setOldOracleJoinSyntax(EqualsTo.ORACLE_JOIN_RIGHT);
8714+
}
8715+
}
8716+
]
86998717
[ LOOKAHEAD(2) <K_ESCAPE> token=<S_CHAR_LITERAL> { result.setEscape((new StringValue(token.image)).getValue()); }]
87008718
{
87018719
result.setLeftExpression(leftExpression);

src/test/java/net/sf/jsqlparser/expression/operators/relational/LikeExpressionTest.java

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@
1212
import static org.junit.jupiter.api.Assertions.*;
1313

1414
import net.sf.jsqlparser.JSQLParserException;
15+
import net.sf.jsqlparser.expression.BinaryExpression;
1516
import net.sf.jsqlparser.expression.Expression;
1617
import net.sf.jsqlparser.expression.StringValue;
18+
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
1719
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
20+
import net.sf.jsqlparser.schema.Column;
21+
import net.sf.jsqlparser.statement.select.PlainSelect;
1822
import net.sf.jsqlparser.test.TestUtils;
1923
import org.junit.jupiter.api.Test;
2024

@@ -98,4 +102,87 @@ public void testMatchRegexp() throws JSQLParserException {
98102
TestUtils.assertSqlCanBeParsedAndDeparsed(
99103
"select * from dual where v NOT MATCH_REGEXP 'keyword1 keyword2'", true);
100104
}
105+
106+
@Test
107+
public void testLikeWithOldOracleJoinSyntaxOnRightOperand() throws JSQLParserException {
108+
String sqlStr = "SELECT * FROM table1 t1, table2 t2 WHERE t1.col1 LIKE t2.col2(+)";
109+
PlainSelect select = (PlainSelect) TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
110+
LikeExpression like = (LikeExpression) select.getWhere();
111+
112+
assertEquals(EqualsTo.ORACLE_JOIN_RIGHT,
113+
((Column) like.getRightExpression()).getOldOracleJoinSyntax());
114+
assertEquals(EqualsTo.NO_ORACLE_JOIN,
115+
((Column) like.getLeftExpression()).getOldOracleJoinSyntax());
116+
}
117+
118+
@Test
119+
public void testNotLikeWithOldOracleJoinSyntaxOnRightOperand() throws JSQLParserException {
120+
TestUtils.assertSqlCanBeParsedAndDeparsed(
121+
"SELECT * FROM table1 t1, table2 t2 WHERE t1.col1 NOT LIKE t2.col2(+)", true);
122+
}
123+
124+
@Test
125+
public void testSimilarToWithOldOracleJoinSyntaxOnRightOperand() throws JSQLParserException {
126+
String sqlStr = "SELECT * FROM table1 t1, table2 t2 WHERE t1.col1 SIMILAR TO t2.col2(+)";
127+
PlainSelect select = (PlainSelect) TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
128+
BinaryExpression similarTo = (BinaryExpression) select.getWhere();
129+
130+
assertEquals(EqualsTo.ORACLE_JOIN_RIGHT,
131+
((Column) similarTo.getRightExpression()).getOldOracleJoinSyntax());
132+
}
133+
134+
@Test
135+
public void testSimilarToOnSeparateTokensWithOldOracleJoinSyntaxOnRightOperand()
136+
throws JSQLParserException {
137+
String sqlStr = "SELECT * FROM table1 t1, table2 t2 WHERE t1.col1 SIMILAR\nTO t2.col2(+)";
138+
PlainSelect select = (PlainSelect) TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
139+
140+
assertTrue(select.getWhere() instanceof SimilarToExpression);
141+
assertEquals(EqualsTo.ORACLE_JOIN_RIGHT,
142+
((Column) ((SimilarToExpression) select.getWhere()).getRightExpression())
143+
.getOldOracleJoinSyntax());
144+
}
145+
146+
@Test
147+
public void testILikeWithOldOracleJoinSyntaxOnRightOperand() throws JSQLParserException {
148+
String sqlStr = "SELECT * FROM table1 t1, table2 t2 WHERE t1.col1 ILIKE t2.col2(+)";
149+
PlainSelect select = (PlainSelect) TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
150+
LikeExpression like = (LikeExpression) select.getWhere();
151+
152+
assertEquals(LikeExpression.KeyWord.ILIKE, like.getLikeKeyWord());
153+
assertEquals(EqualsTo.ORACLE_JOIN_RIGHT,
154+
((Column) like.getRightExpression()).getOldOracleJoinSyntax());
155+
}
156+
157+
@Test
158+
public void testLikeWithOldOracleJoinSyntaxInJoinOnClause() throws JSQLParserException {
159+
String sqlStr =
160+
"SELECT * FROM table1 t1 LEFT JOIN table2 t2 ON t1.a = t2.b AND t1.col1 LIKE t2.col2(+)";
161+
PlainSelect select = (PlainSelect) TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
162+
LikeExpression like = (LikeExpression) ((AndExpression) select.getJoins().get(0)
163+
.getOnExpression()).getRightExpression();
164+
165+
assertEquals(EqualsTo.ORACLE_JOIN_RIGHT,
166+
((Column) like.getRightExpression()).getOldOracleJoinSyntax());
167+
}
168+
169+
@Test
170+
public void testSimilarToWithOldOracleJoinSyntaxOnRightOperandAndEscape()
171+
throws JSQLParserException {
172+
TestUtils.assertSqlCanBeParsedAndDeparsed(
173+
"SELECT * FROM table1 t1, table2 t2 WHERE t1.col1 SIMILAR TO t2.col2(+) ESCAPE '\\'",
174+
true);
175+
}
176+
177+
@Test
178+
public void testLikeWithOldOracleJoinSyntaxOnLeftOperand() throws JSQLParserException {
179+
String sqlStr = "SELECT * FROM table1 t1, table2 t2 WHERE t1.col1(+) LIKE t2.col2";
180+
PlainSelect select = (PlainSelect) TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
181+
LikeExpression like = (LikeExpression) select.getWhere();
182+
183+
assertEquals(EqualsTo.ORACLE_JOIN_RIGHT,
184+
((Column) like.getLeftExpression()).getOldOracleJoinSyntax());
185+
assertEquals(EqualsTo.NO_ORACLE_JOIN,
186+
((Column) like.getRightExpression()).getOldOracleJoinSyntax());
187+
}
101188
}

0 commit comments

Comments
 (0)