Skip to content

Commit 2c272f4

Browse files
adriilwumpz
authored andcommitted
JSQLPARSER-584: adds support for MySQL (a,b,...)OP(c,d,...) expression (#585)
* JSQLPARSER-584: adds support for MySQL (a,b,...)OP(c,d,...) expression * JSQLPARSER-584: adds some tests and rename MySQLValueListExpression to ValueListExpression
1 parent 7205906 commit 2c272f4

File tree

8 files changed

+111
-0
lines changed

8 files changed

+111
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ public interface ExpressionVisitor {
167167
void visit(KeepExpression aexpr);
168168

169169
void visit(MySQLGroupConcat groupConcat);
170+
171+
void visit(ValueListExpression valueList);
170172

171173
void visit(RowConstructor rowConstructor);
172174

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,13 @@ public void visit(MySQLGroupConcat groupConcat) {
416416
}
417417
}
418418
}
419+
420+
@Override
421+
public void visit(ValueListExpression valueListExpression) {
422+
for (Expression expr : valueListExpression.getExpressionList().getExpressions()) {
423+
expr.accept(this);
424+
}
425+
}
419426

420427
@Override
421428
public void visit(Pivot pivot) {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2018 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+
*
24+
*/
25+
package net.sf.jsqlparser.expression;
26+
27+
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
28+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
29+
30+
/**
31+
* Models a list of expressions usable as condition.<br>
32+
* This allows for instance the following expression :
33+
* <code>"[WHERE] (a, b) [OPERATOR] (c, d)"</code>
34+
* where "(a, b)" and "(c, d)" are instances of this class.
35+
*
36+
* @author adriil
37+
*/
38+
public class ValueListExpression extends ASTNodeAccessImpl implements Expression {
39+
40+
private ExpressionList expressionList;
41+
42+
public ExpressionList getExpressionList() {
43+
return expressionList;
44+
}
45+
46+
public void setExpressionList(ExpressionList expressionList) {
47+
this.expressionList = expressionList;
48+
}
49+
50+
@Override
51+
public void accept(ExpressionVisitor expressionVisitor) {
52+
expressionVisitor.visit(this);
53+
}
54+
55+
@Override
56+
public String toString() {
57+
return expressionList.toString();
58+
}
59+
60+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import net.sf.jsqlparser.expression.KeepExpression;
4646
import net.sf.jsqlparser.expression.LongValue;
4747
import net.sf.jsqlparser.expression.MySQLGroupConcat;
48+
import net.sf.jsqlparser.expression.ValueListExpression;
4849
import net.sf.jsqlparser.expression.NotExpression;
4950
import net.sf.jsqlparser.expression.NullValue;
5051
import net.sf.jsqlparser.expression.NumericBind;
@@ -608,6 +609,11 @@ public void visit(KeepExpression aexpr) {
608609
@Override
609610
public void visit(MySQLGroupConcat groupConcat) {
610611
}
612+
613+
@Override
614+
public void visit(ValueListExpression valueList) {
615+
valueList.getExpressionList().accept(this);
616+
}
611617

612618
@Override
613619
public void visit(Delete delete) {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import net.sf.jsqlparser.expression.KeepExpression;
4646
import net.sf.jsqlparser.expression.LongValue;
4747
import net.sf.jsqlparser.expression.MySQLGroupConcat;
48+
import net.sf.jsqlparser.expression.ValueListExpression;
4849
import net.sf.jsqlparser.expression.NotExpression;
4950
import net.sf.jsqlparser.expression.NullValue;
5051
import net.sf.jsqlparser.expression.NumericBind;
@@ -726,6 +727,11 @@ public void visit(KeepExpression aexpr) {
726727
public void visit(MySQLGroupConcat groupConcat) {
727728
buffer.append(groupConcat.toString());
728729
}
730+
731+
@Override
732+
public void visit(ValueListExpression valueList) {
733+
buffer.append(valueList.toString());
734+
}
729735

730736
@Override
731737
public void visit(RowConstructor rowConstructor) {

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,7 @@ Expression ComparisonItem() :
22432243
(
22442244
retval=AllComparisonExpression()
22452245
| LOOKAHEAD(3) retval=AnyComparisonExpression()
2246+
| LOOKAHEAD(ValueListExpression()) retval=ValueListExpression()
22462247
| LOOKAHEAD(3) retval=SimpleExpression()
22472248
| retval=RowConstructor()
22482249
)
@@ -2860,6 +2861,19 @@ MySQLGroupConcat MySQLGroupConcat():{
28602861
}
28612862
}
28622863

2864+
ValueListExpression ValueListExpression():
2865+
{
2866+
ValueListExpression retval = new ValueListExpression();
2867+
ExpressionList expressionList = null;
2868+
}
2869+
{
2870+
"(" expressionList = SimpleExpressionListAtLeastTwoItems() ")"
2871+
{
2872+
retval.setExpressionList(expressionList);
2873+
return retval;
2874+
}
2875+
}
2876+
28632877
TableFunction TableFunction():
28642878
{
28652879
Alias alias = null;

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2759,4 +2759,9 @@ public void testIssue266KeywordTop() throws JSQLParserException {
27592759
assertSqlCanBeParsedAndDeparsed("SELECT @top");
27602760
assertSqlCanBeParsedAndDeparsed("SELECT @TOP");
27612761
}
2762+
2763+
public void testIssue584MySQLValueListExpression() throws JSQLParserException {
2764+
assertSqlCanBeParsedAndDeparsed("SELECT a, b FROM T WHERE (T.a, T.b) = (c, d)");
2765+
assertSqlCanBeParsedAndDeparsed("SELECT a FROM T WHERE (T.a) = (SELECT b FROM T, c, d)");
2766+
}
27622767
}

src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ public void testExpressionIssue515() throws JSQLParserException {
484484
assertTrue(tableList.contains("SOME_TABLE"));
485485
}
486486

487+
@Test
487488
public void testSelectHavingSubquery() throws Exception {
488489
String sql = "SELECT * FROM TABLE1 GROUP BY COL1 HAVING SUM(COL2) > (SELECT COUNT(*) FROM TABLE2)";
489490
net.sf.jsqlparser.statement.Statement statement = pm.parse(new StringReader(sql));
@@ -495,4 +496,14 @@ public void testSelectHavingSubquery() throws Exception {
495496
assertTrue(tableList.contains("TABLE1"));
496497
assertTrue(tableList.contains("TABLE2"));
497498
}
499+
500+
@Test
501+
public void testMySQLValueListExpression() throws JSQLParserException {
502+
String sql = "SELECT * FROM TABLE1 WHERE (a, b) = (c, d)";
503+
TablesNamesFinder finder = new TablesNamesFinder();
504+
List<String> tableList = finder.getTableList(CCJSqlParserUtil.parse(sql));
505+
assertEquals(1, tableList.size());
506+
assertTrue(tableList.contains("TABLE1"));
507+
}
508+
498509
}

0 commit comments

Comments
 (0)