Skip to content

Commit f695858

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 f695858

2 files changed

Lines changed: 81 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: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
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;
1718
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
19+
import net.sf.jsqlparser.schema.Column;
20+
import net.sf.jsqlparser.statement.select.PlainSelect;
1821
import net.sf.jsqlparser.test.TestUtils;
1922
import org.junit.jupiter.api.Test;
2023

@@ -98,4 +101,64 @@ public void testMatchRegexp() throws JSQLParserException {
98101
TestUtils.assertSqlCanBeParsedAndDeparsed(
99102
"select * from dual where v NOT MATCH_REGEXP 'keyword1 keyword2'", true);
100103
}
104+
105+
@Test
106+
public void testLikeWithOldOracleJoinSyntaxOnRightOperand() throws JSQLParserException {
107+
String sqlStr = "SELECT * FROM table1 t1, table2 t2 WHERE t1.col1 LIKE t2.col2(+)";
108+
PlainSelect select = (PlainSelect) TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
109+
LikeExpression like = (LikeExpression) select.getWhere();
110+
111+
assertEquals(EqualsTo.ORACLE_JOIN_RIGHT,
112+
((Column) like.getRightExpression()).getOldOracleJoinSyntax());
113+
assertEquals(EqualsTo.NO_ORACLE_JOIN,
114+
((Column) like.getLeftExpression()).getOldOracleJoinSyntax());
115+
}
116+
117+
@Test
118+
public void testNotLikeWithOldOracleJoinSyntaxOnRightOperand() throws JSQLParserException {
119+
TestUtils.assertSqlCanBeParsedAndDeparsed(
120+
"SELECT * FROM table1 t1, table2 t2 WHERE t1.col1 NOT LIKE t2.col2(+)", true);
121+
}
122+
123+
@Test
124+
public void testSimilarToWithOldOracleJoinSyntaxOnRightOperand() throws JSQLParserException {
125+
String sqlStr = "SELECT * FROM table1 t1, table2 t2 WHERE t1.col1 SIMILAR TO t2.col2(+)";
126+
PlainSelect select = (PlainSelect) TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
127+
BinaryExpression similarTo = (BinaryExpression) select.getWhere();
128+
129+
assertEquals(EqualsTo.ORACLE_JOIN_RIGHT,
130+
((Column) similarTo.getRightExpression()).getOldOracleJoinSyntax());
131+
}
132+
133+
@Test
134+
public void testSimilarToOnSeparateTokensWithOldOracleJoinSyntaxOnRightOperand()
135+
throws JSQLParserException {
136+
String sqlStr = "SELECT * FROM table1 t1, table2 t2 WHERE t1.col1 SIMILAR\nTO t2.col2(+)";
137+
PlainSelect select = (PlainSelect) TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
138+
139+
assertTrue(select.getWhere() instanceof SimilarToExpression);
140+
assertEquals(EqualsTo.ORACLE_JOIN_RIGHT,
141+
((Column) ((SimilarToExpression) select.getWhere()).getRightExpression())
142+
.getOldOracleJoinSyntax());
143+
}
144+
145+
@Test
146+
public void testLikeWithOldOracleJoinSyntaxOnRightOperandAndEscape()
147+
throws JSQLParserException {
148+
TestUtils.assertSqlCanBeParsedAndDeparsed(
149+
"SELECT * FROM table1 t1, table2 t2 WHERE t1.col1 LIKE t2.col2(+) ESCAPE '\\'",
150+
true);
151+
}
152+
153+
@Test
154+
public void testLikeWithOldOracleJoinSyntaxOnLeftOperand() throws JSQLParserException {
155+
String sqlStr = "SELECT * FROM table1 t1, table2 t2 WHERE t1.col1(+) LIKE t2.col2";
156+
PlainSelect select = (PlainSelect) TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
157+
LikeExpression like = (LikeExpression) select.getWhere();
158+
159+
assertEquals(EqualsTo.ORACLE_JOIN_RIGHT,
160+
((Column) like.getLeftExpression()).getOldOracleJoinSyntax());
161+
assertEquals(EqualsTo.NO_ORACLE_JOIN,
162+
((Column) like.getRightExpression()).getOldOracleJoinSyntax());
163+
}
101164
}

0 commit comments

Comments
 (0)