Skip to content

Commit ab2b2c0

Browse files
committed
fixes #138 and AnyComparisionExpression
1 parent a0e3729 commit ab2b2c0

File tree

10 files changed

+214
-13
lines changed

10 files changed

+214
-13
lines changed

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,17 @@
2323

2424
import net.sf.jsqlparser.statement.select.SubSelect;
2525

26+
/**
27+
* Combines ANY and SOME expressions.
28+
* @author toben
29+
*/
2630
public class AnyComparisonExpression implements Expression {
2731

2832
private final SubSelect subSelect;
29-
30-
public AnyComparisonExpression(SubSelect subSelect) {
33+
private final AnyType anyType;
34+
35+
public AnyComparisonExpression(AnyType anyType, SubSelect subSelect) {
36+
this.anyType = anyType;
3137
this.subSelect = subSelect;
3238
}
3339

@@ -39,9 +45,13 @@ public SubSelect getSubSelect() {
3945
public void accept(ExpressionVisitor expressionVisitor) {
4046
expressionVisitor.visit(this);
4147
}
48+
49+
public AnyType getAnyType() {
50+
return anyType;
51+
}
4252

4353
@Override
4454
public String toString() {
45-
return "ANY " + subSelect.toString();
55+
return anyType.name() + " " + subSelect.toString();
4656
}
4757
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2015 JSQLParser
6+
* %%
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Lesser General Public License as
9+
* published by the Free Software Foundation, either version 2.1 of the
10+
* License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Lesser Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Lesser Public
18+
* License along with this program. If not, see
19+
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
20+
* #L%
21+
*/
22+
/*
23+
* Copyright (C) 2015 JSQLParser.
24+
*
25+
* This library is free software; you can redistribute it and/or
26+
* modify it under the terms of the GNU Lesser General Public
27+
* License as published by the Free Software Foundation; either
28+
* version 2.1 of the License, or (at your option) any later version.
29+
*
30+
* This library is distributed in the hope that it will be useful,
31+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
32+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33+
* Lesser General Public License for more details.
34+
*
35+
* You should have received a copy of the GNU Lesser General Public
36+
* License along with this library; if not, write to the Free Software
37+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
38+
* MA 02110-1301 USA
39+
*/
40+
package net.sf.jsqlparser.expression;
41+
42+
/**
43+
*
44+
* @author toben
45+
*/
46+
public enum AnyType {
47+
48+
ANY,
49+
SOME
50+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,6 @@ public interface ExpressionVisitor {
158158
void visit(KeepExpression aexpr);
159159

160160
void visit(MySQLGroupConcat groupConcat);
161+
162+
void visit(RowConstructor rowConstructor);
161163
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,4 +432,11 @@ public void visit(AllTableColumns allTableColumns) {
432432
public void visit(SelectExpressionItem selectExpressionItem) {
433433
selectExpressionItem.getExpression().accept(this);
434434
}
435+
436+
@Override
437+
public void visit(RowConstructor rowConstructor) {
438+
for (Expression expr : rowConstructor.getExprList().getExpressions()) {
439+
expr.accept(this);
440+
}
441+
}
435442
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2015 JSQLParser
6+
* %%
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Lesser General Public License as
9+
* published by the Free Software Foundation, either version 2.1 of the
10+
* License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Lesser Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Lesser Public
18+
* License along with this program. If not, see
19+
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
20+
* #L%
21+
*/
22+
package net.sf.jsqlparser.expression;
23+
24+
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
25+
26+
/**
27+
* Rowconstructor.
28+
* @author tw
29+
*/
30+
public class RowConstructor implements Expression {
31+
32+
private ExpressionList exprList;
33+
private String name = null;
34+
35+
public RowConstructor() {
36+
}
37+
38+
public ExpressionList getExprList() {
39+
return exprList;
40+
}
41+
42+
public void setExprList(ExpressionList exprList) {
43+
this.exprList = exprList;
44+
}
45+
46+
public String getName() {
47+
return name;
48+
}
49+
50+
public void setName(String name) {
51+
this.name = name;
52+
}
53+
54+
@Override
55+
public void accept(ExpressionVisitor expressionVisitor) {
56+
expressionVisitor.visit(this);
57+
}
58+
59+
@Override
60+
public String toString() {
61+
return (name !=null ? name : "") + exprList.toString();
62+
}
63+
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,4 +615,11 @@ public void visit(Execute execute) {
615615
public void visit(SetStatement set) {
616616
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
617617
}
618+
619+
@Override
620+
public void visit(RowConstructor rowConstructor) {
621+
for (Expression expr : rowConstructor.getExprList().getExpressions()) {
622+
expr.accept(this);
623+
}
624+
}
618625
}

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ public void visit(AllComparisonExpression allComparisonExpression) {
422422

423423
@Override
424424
public void visit(AnyComparisonExpression anyComparisonExpression) {
425-
buffer.append("ANY ");
425+
buffer.append(anyComparisonExpression.getAnyType().name()).append(" ");
426426
anyComparisonExpression.getSubSelect().accept((ExpressionVisitor) this);
427427
}
428428

@@ -545,4 +545,22 @@ public void visit(KeepExpression aexpr) {
545545
public void visit(MySQLGroupConcat groupConcat) {
546546
buffer.append(groupConcat.toString());
547547
}
548+
549+
@Override
550+
public void visit(RowConstructor rowConstructor) {
551+
if (rowConstructor.getName() != null) {
552+
buffer.append(rowConstructor.getName());
553+
}
554+
buffer.append("(");
555+
boolean first = true;
556+
for (Expression expr : rowConstructor.getExprList().getExpressions()) {
557+
if (first) {
558+
first = false;
559+
} else {
560+
buffer.append(", ");
561+
}
562+
expr.accept(this);
563+
}
564+
buffer.append(")");
565+
}
548566
}

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

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,6 +1584,20 @@ ExpressionList SimpleExpressionList():
15841584
}
15851585
}
15861586

1587+
ExpressionList SimpleExpressionListAtLeastTwoItems():
1588+
{
1589+
ExpressionList retval = new ExpressionList();
1590+
List<Expression> expressions = new ArrayList<Expression>();
1591+
Expression expr = null;
1592+
}
1593+
{
1594+
expr=SimpleExpression() { expressions.add(expr); } ("," expr=SimpleExpression() { expressions.add(expr); })+
1595+
{
1596+
retval.setExpressions(expressions);
1597+
return retval;
1598+
}
1599+
}
1600+
15871601
Expression ComparisonItem() :
15881602
{
15891603
Expression retval = null;
@@ -1592,7 +1606,8 @@ Expression ComparisonItem() :
15921606
(
15931607
retval=AllComparisonExpression()
15941608
| LOOKAHEAD(AnyComparisonExpression()) retval=AnyComparisonExpression()
1595-
| retval=SimpleExpression()
1609+
| LOOKAHEAD(3) retval=SimpleExpression()
1610+
| retval=RowConstructor()
15961611
)
15971612

15981613
{
@@ -1615,10 +1630,12 @@ Expression AllComparisonExpression() :
16151630
Expression AnyComparisonExpression() :
16161631
{
16171632
AnyComparisonExpression retval = null;
1633+
AnyType anyType;
16181634
SubSelect subselect = null;
16191635
}
16201636
{
1621-
(<K_ANY> | <K_SOME>) "(" subselect=SubSelect() ")" { retval = new AnyComparisonExpression(subselect); }
1637+
(<K_ANY> { anyType = AnyType.ANY; } | <K_SOME> { anyType = AnyType.SOME; } )
1638+
"(" subselect=SubSelect() ")" { retval = new AnyComparisonExpression(anyType, subselect); }
16221639
{
16231640
return retval;
16241641
}
@@ -1792,7 +1809,7 @@ Expression PrimaryExpression():
17921809

17931810
| retval=CaseWhenExpression()
17941811

1795-
| "?" { retval = new JdbcParameter(); } [ token = <S_LONG> { ((JdbcParameter)retval).setIndex(Integer.valueOf(token.image)); } ]
1812+
| "?" { retval = new JdbcParameter(); } [ LOOKAHEAD(2) token = <S_LONG> { ((JdbcParameter)retval).setIndex(Integer.valueOf(token.image)); } ]
17961813

17971814
| LOOKAHEAD(2) retval=JdbcNamedParameter()
17981815

@@ -2125,6 +2142,23 @@ WhenClause WhenThenValue():
21252142
}
21262143
}
21272144

2145+
RowConstructor RowConstructor(): {
2146+
ExpressionList list = null;
2147+
RowConstructor rowConstructor = new RowConstructor();
2148+
} {
2149+
//("(" list =SimpleExpressionListAtLeastTwoItems() ")"
2150+
//|
2151+
[ <K_ROW> { rowConstructor.setName("ROW");} ]
2152+
"("
2153+
list = SimpleExpressionList()
2154+
")"
2155+
2156+
{
2157+
rowConstructor.setExprList(list);
2158+
return rowConstructor;
2159+
}
2160+
}
2161+
21282162
Execute Execute(): {
21292163
String funcName = null;
21302164
ExpressionList expressionList = null;

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,4 +1762,12 @@ public void testSelectKeepOver() throws JSQLParserException {
17621762
public void testGroupConcat() throws JSQLParserException {
17631763
assertSqlCanBeParsedAndDeparsed("SELECT student_name, GROUP_CONCAT(DISTINCT test_score ORDER BY test_score DESC SEPARATOR ' ') FROM student GROUP BY student_name");
17641764
}
1765+
1766+
public void testRowConstructor1() throws JSQLParserException {
1767+
assertSqlCanBeParsedAndDeparsed("SELECT * FROM t1 WHERE (col1, col2) = (SELECT col3, col4 FROM t2 WHERE id = 10)");
1768+
}
1769+
1770+
public void testRowConstructor2() throws JSQLParserException {
1771+
assertSqlCanBeParsedAndDeparsed("SELECT * FROM t1 WHERE ROW(col1, col2) = (SELECT col3, col4 FROM t2 WHERE id = 10)");
1772+
}
17651773
}

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@
3232
/**
3333
* Tries to parse and deparse all statments in
3434
* net.sf.jsqlparser.test.oracle-tests.
35-
*
35+
*
3636
* As a matter of fact there are a lot of files that can still not processed.
3737
* Here a step by step improvement is the way to go.
38-
*
38+
*
3939
* The test ensures, that the successfull parsed file count does not decrease.
4040
*
4141
* @author toben
@@ -47,8 +47,8 @@ public class SpecialOracleTest {
4747

4848
@Test
4949
public void testAllSqlsParseDeparse() throws IOException {
50-
int count=0;
51-
int success=0;
50+
int count = 0;
51+
int success = 0;
5252
File[] sqlTestFiles = SQLS_DIR.listFiles();
5353

5454
for (File file : sqlTestFiles) {
@@ -63,12 +63,14 @@ public void testAllSqlsParseDeparse() throws IOException {
6363
} catch (JSQLParserException ex) {
6464
//LOG.log(Level.SEVERE, null, ex);
6565
LOG.log(Level.INFO, " -> PROBLEM {0}", ex.toString());
66+
} catch (Exception ex) {
67+
LOG.log(Level.INFO, " -> PROBLEM {0}", ex.toString());
6668
}
6769
}
6870
}
69-
71+
7072
LOG.log(Level.INFO, "tested {0} files. got {1} correct parse results", new Object[]{count, success});
71-
assertTrue(success>=128);
73+
assertTrue(success >= 129);
7274
}
7375

7476
@Test

0 commit comments

Comments
 (0)