Skip to content

Commit 686958c

Browse files
committed
1 parent 2320b1b commit 686958c

File tree

9 files changed

+82
-66
lines changed

9 files changed

+82
-66
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Also I would like to know about needed examples or documentation stuff.
5757

5858
## Extensions in the latest SNAPSHOT version 4.1
5959

60+
* API change in ValuesStatement: the expression list is now hold as a ItemList and not as a List<Expression>
6061
* support for parser modification within **parseExpression** and **parseCondExpression**
6162
' support for table schema for foreign keys
6263
* support for Oracle hints on **insert, update and merge**

src/main/java/net/sf/jsqlparser/expression/operators/relational/ExpressionList.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
public class ExpressionList implements ItemsList {
2525

2626
private List<Expression> expressions;
27+
private boolean withBrackets = true;
2728

2829
public ExpressionList() {
2930
}
@@ -54,6 +55,11 @@ public ExpressionList withExpressions(List<Expression> expressions) {
5455
public void setExpressions(List<Expression> expressions) {
5556
this.expressions = expressions;
5657
}
58+
59+
public ExpressionList withBrackets(boolean brackets) {
60+
this.withBrackets = brackets;
61+
return this;
62+
}
5763

5864
@Override
5965
public void accept(ItemsListVisitor itemsListVisitor) {
@@ -62,7 +68,7 @@ public void accept(ItemsListVisitor itemsListVisitor) {
6268

6369
@Override
6470
public String toString() {
65-
return PlainSelect.getStringList(expressions, true, true);
71+
return PlainSelect.getStringList(expressions, true, withBrackets);
6672
}
6773

6874
public ExpressionList addExpressions(Collection<? extends Expression> expressions) {

src/main/java/net/sf/jsqlparser/statement/values/ValuesStatement.java

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,68 +11,62 @@
1111

1212
import java.util.ArrayList;
1313
import java.util.Collection;
14-
import java.util.Collections;
15-
import java.util.List;
16-
import java.util.Optional;
1714
import net.sf.jsqlparser.expression.Expression;
15+
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
16+
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
1817
import net.sf.jsqlparser.statement.Statement;
1918
import net.sf.jsqlparser.statement.StatementVisitor;
20-
import net.sf.jsqlparser.statement.select.PlainSelect;
2119
import net.sf.jsqlparser.statement.select.SelectBody;
2220
import net.sf.jsqlparser.statement.select.SelectVisitor;
2321

2422
public class ValuesStatement implements Statement, SelectBody {
25-
26-
private List<Expression> expressions;
23+
24+
private ItemsList expressions;
2725

2826
public ValuesStatement() {
2927
// empty constructor
3028
}
3129

32-
public ValuesStatement(List<Expression> expressions) {
30+
public ValuesStatement(ItemsList expressions) {
3331
this.expressions = expressions;
3432
}
35-
33+
3634
@Override
3735
public void accept(StatementVisitor statementVisitor) {
3836
statementVisitor.visit(this);
3937
}
40-
41-
public List<Expression> getExpressions() {
38+
39+
public ItemsList getExpressions() {
4240
return expressions;
4341
}
44-
45-
public void setExpressions(List<Expression> expressions) {
42+
43+
public void setExpressions(ItemsList expressions) {
4644
this.expressions = expressions;
4745
}
48-
46+
4947
@Override
5048
public String toString() {
5149
StringBuilder sql = new StringBuilder();
5250
sql.append("VALUES ");
53-
sql.append(PlainSelect.getStringList(expressions, true, true));
51+
sql.append(expressions.toString());
5452
return sql.toString();
5553
}
56-
54+
5755
@Override
5856
public void accept(SelectVisitor selectVisitor) {
5957
selectVisitor.visit(this);
6058
}
6159

62-
public ValuesStatement withExpressions(List<Expression> expressions) {
60+
public ValuesStatement withExpressions(ItemsList expressions) {
6361
this.setExpressions(expressions);
6462
return this;
6563
}
6664

6765
public ValuesStatement addExpressions(Expression... expressions) {
68-
List<Expression> collection = Optional.ofNullable(getExpressions()).orElseGet(ArrayList::new);
69-
Collections.addAll(collection, expressions);
70-
return this.withExpressions(collection);
66+
return this.withExpressions(new ExpressionList(expressions));
7167
}
7268

7369
public ValuesStatement addExpressions(Collection<? extends Expression> expressions) {
74-
List<Expression> collection = Optional.ofNullable(getExpressions()).orElseGet(ArrayList::new);
75-
collection.addAll(expressions);
76-
return this.withExpressions(collection);
70+
return this.withExpressions(new ExpressionList(new ArrayList<>(expressions)));
7771
}
7872
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -829,9 +829,7 @@ public void visit(Comment comment) {
829829

830830
@Override
831831
public void visit(ValuesStatement values) {
832-
for (Expression expr : values.getExpressions()) {
833-
expr.accept(this);
834-
}
832+
values.getExpressions().accept(this);
835833
}
836834

837835
@Override

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

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
import net.sf.jsqlparser.expression.MySQLIndexHint;
1919
import net.sf.jsqlparser.expression.OracleHint;
2020
import net.sf.jsqlparser.expression.SQLServerHints;
21+
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
22+
import net.sf.jsqlparser.expression.operators.relational.ItemsListVisitor;
23+
import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
24+
import net.sf.jsqlparser.expression.operators.relational.NamedExpressionList;
2125
import net.sf.jsqlparser.schema.Column;
2226
import net.sf.jsqlparser.schema.Table;
2327
import net.sf.jsqlparser.statement.select.AllColumns;
@@ -52,7 +56,7 @@
5256

5357
@SuppressWarnings({"PMD.CyclomaticComplexity"})
5458
public class SelectDeParser extends AbstractDeParser<PlainSelect>
55-
implements SelectVisitor, SelectItemVisitor, FromItemVisitor, PivotVisitor {
59+
implements SelectVisitor, SelectItemVisitor, FromItemVisitor, PivotVisitor, ItemsListVisitor {
5660

5761
private ExpressionVisitor expressionVisitor;
5862

@@ -517,7 +521,7 @@ public void visit(ParenthesisFromItem parenthesis) {
517521

518522
@Override
519523
public void visit(ValuesStatement values) {
520-
new ValuesStatementDeParser(expressionVisitor, buffer).deParse(values);
524+
new ValuesStatementDeParser(this, buffer).deParse(values);
521525
}
522526

523527
private void deparseOptimizeFor(OptimizeFor optimizeFor) {
@@ -530,4 +534,19 @@ private void deparseOptimizeFor(OptimizeFor optimizeFor) {
530534
void deParse(PlainSelect statement) {
531535
statement.accept(this);
532536
}
537+
538+
@Override
539+
public void visit(ExpressionList expressionList) {
540+
buffer.append(expressionList.toString());
541+
}
542+
543+
@Override
544+
public void visit(NamedExpressionList namedExpressionList) {
545+
buffer.append(namedExpressionList.toString());
546+
}
547+
548+
@Override
549+
public void visit(MultiExpressionList multiExprList) {
550+
buffer.append(multiExprList.toString());
551+
}
533552
}

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

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,21 @@
99
*/
1010
package net.sf.jsqlparser.util.deparser;
1111

12-
import net.sf.jsqlparser.expression.Expression;
13-
import net.sf.jsqlparser.expression.ExpressionVisitor;
12+
import net.sf.jsqlparser.expression.operators.relational.ItemsListVisitor;
1413
import net.sf.jsqlparser.statement.values.ValuesStatement;
1514

1615
public class ValuesStatementDeParser extends AbstractDeParser<ValuesStatement> {
1716

18-
private final ExpressionVisitor expressionVisitor;
17+
private final ItemsListVisitor expressionVisitor;
1918

20-
public ValuesStatementDeParser(ExpressionVisitor expressionVisitor, StringBuilder buffer) {
19+
public ValuesStatementDeParser(ItemsListVisitor expressionVisitor, StringBuilder buffer) {
2120
super(buffer);
2221
this.expressionVisitor = expressionVisitor;
2322
}
2423

2524
@Override
2625
public void deParse(ValuesStatement values) {
27-
boolean first = true;
28-
buffer.append("VALUES (");
29-
for (Expression expr : values.getExpressions()) {
30-
if (first) {
31-
first = false;
32-
} else {
33-
buffer.append(", ");
34-
}
35-
expr.accept(expressionVisitor);
36-
}
37-
buffer.append(")");
26+
buffer.append("VALUES ");
27+
values.getExpressions().accept(expressionVisitor);
3828
}
3929
}

src/main/java/net/sf/jsqlparser/util/validation/validator/ValuesStatementValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ public class ValuesStatementValidator extends AbstractValidator<ValuesStatement>
2020
@Override
2121
public void validate(ValuesStatement values) {
2222
validateFeature(Feature.values);
23-
validateOptionalExpressions(values.getExpressions());
23+
validateOptionalItemsList(values.getExpressions());
2424
}
2525
}

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

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -847,16 +847,14 @@ ShowStatement Show(): {
847847
}
848848

849849
ValuesStatement Values(): {
850-
List<Expression> expList = new ArrayList<Expression>();
851-
Expression exp;
850+
ItemsList itemsList;
852851
} {
853852
<K_VALUES>
854-
"("
855-
exp=PrimaryExpression() { expList.add(exp); }
856-
("," exp=PrimaryExpression() { expList.add(exp); } )*
857-
")"
853+
854+
itemsList = SimpleExpressionList(false)
855+
858856
{
859-
return new ValuesStatement(expList);
857+
return new ValuesStatement(itemsList);
860858
}
861859
}
862860

@@ -1891,7 +1889,7 @@ ExpressionListItem ExpressionListItem():
18911889
}
18921890
{
18931891
"("
1894-
expressionList=SimpleExpressionList() { expressionListItem = new ExpressionListItem(); expressionListItem.setExpressionList(expressionList); }
1892+
expressionList=SimpleExpressionList(true) { expressionListItem = new ExpressionListItem(); expressionListItem.setExpressionList(expressionList); }
18951893
")"
18961894
[alias=Alias() { expressionListItem.setAlias(alias); }]
18971895
{ return expressionListItem; }
@@ -2330,11 +2328,11 @@ GroupByElement GroupByColumnReferences():
23302328
|
23312329
<K_GROUPING> <K_SETS> "("
23322330
( LOOKAHEAD(2) "(" ")" { groupBy.addGroupingSet(new ExpressionList()); }
2333-
| LOOKAHEAD(3) "(" list = SimpleExpressionList() ")" { groupBy.addGroupingSet(list); }
2331+
| LOOKAHEAD(3) "(" list = SimpleExpressionList(true) ")" { groupBy.addGroupingSet(list); }
23342332
| expr = SimpleExpression() { groupBy.addGroupingSet(expr); } )
23352333

23362334
( "," ( LOOKAHEAD(2) "(" ")" { groupBy.addGroupingSet(new ExpressionList()); }
2337-
| LOOKAHEAD(3) "(" list = SimpleExpressionList() ")" { groupBy.addGroupingSet(list); }
2335+
| LOOKAHEAD(3) "(" list = SimpleExpressionList(true) ")" { groupBy.addGroupingSet(list); }
23382336
| expr = SimpleExpression() { groupBy.addGroupingSet(expr); } ) )*
23392337
")"
23402338
)
@@ -2798,7 +2796,7 @@ Expression InExpression() #InExpression :
27982796
}
27992797
{
28002798
( LOOKAHEAD(3) "(" (
2801-
LOOKAHEAD(SimpleExpressionList()) leftItemsList = SimpleExpressionList() { result.setLeftItemsList(leftItemsList); }
2799+
LOOKAHEAD(SimpleExpressionList(true)) leftItemsList = SimpleExpressionList(true) { result.setLeftItemsList(leftItemsList); }
28022800
|
28032801
leftExpression=SimpleExpression()
28042802
[ "(" "+" ")" { result.setOldOracleJoinSyntax(EqualsTo.ORACLE_JOIN_RIGHT); } ]
@@ -2814,7 +2812,7 @@ Expression InExpression() #InExpression :
28142812
LOOKAHEAD(3) multiExpressionList = MultiInExpressions()
28152813
| LOOKAHEAD(3) rightExpression = Function()
28162814
| LOOKAHEAD(2) token=<S_CHAR_LITERAL> { rightExpression = new StringValue(token.image); }
2817-
| LOOKAHEAD(3) "(" (LOOKAHEAD(3) rightItemsList=SubSelect() | rightItemsList=SimpleExpressionList() )")"
2815+
| LOOKAHEAD(3) "(" (LOOKAHEAD(3) rightItemsList=SubSelect() | rightItemsList=SimpleExpressionList(true) )")"
28182816
| rightExpression = SimpleExpression()
28192817
)
28202818
{
@@ -2833,15 +2831,15 @@ MultiExpressionList MultiInExpressions():
28332831
}
28342832
{
28352833
"(" "("
2836-
expressionList=SimpleExpressionList() {
2834+
expressionList=SimpleExpressionList(true) {
28372835
if(multiExpressionList == null) {
28382836
multiExpressionList = new MultiExpressionList();
28392837
}
28402838
multiExpressionList.addExpressionList(expressionList);
28412839
}
28422840
// potentially additional expression lists
28432841
( LOOKAHEAD(3)
2844-
")" "," "(" expressionList=SimpleExpressionList()
2842+
")" "," "(" expressionList=SimpleExpressionList(true)
28452843
{
28462844
if(multiExpressionList == null) {
28472845
multiExpressionList = new MultiExpressionList();
@@ -2962,9 +2960,9 @@ ExpressionList SQLExpressionList():
29622960
}
29632961
}
29642962

2965-
ExpressionList SimpleExpressionList() #ExpressionList:
2963+
ExpressionList SimpleExpressionList(boolean outerBrackets) #ExpressionList:
29662964
{
2967-
ExpressionList retval = new ExpressionList();
2965+
ExpressionList retval = new ExpressionList().withBrackets(outerBrackets);
29682966
List<Expression> expressions = new ArrayList<Expression>();
29692967
Expression expr = null;
29702968
}
@@ -3370,7 +3368,7 @@ Expression PrimaryExpression() #PrimaryExpression:
33703368

33713369
| LOOKAHEAD("(" retval=SubSelect() ")") "(" retval=SubSelect() ")"
33723370

3373-
| "(" list = SimpleExpressionList() ")"
3371+
| "(" list = SimpleExpressionList(true) ")"
33743372
{
33753373
if (list.getExpressions().size() == 1) {
33763374
retval = new Parenthesis(list.getExpressions().get(0));
@@ -3737,7 +3735,7 @@ RowConstructor RowConstructor(): {
37373735
} {
37383736
[ <K_ROW> { rowConstructor.setName("ROW");} ]
37393737
"("
3740-
list = SimpleExpressionList()
3738+
list = SimpleExpressionList(true)
37413739
")"
37423740

37433741
{
@@ -3781,9 +3779,9 @@ Execute Execute(): {
37813779
( "," expr = VariableExpression() { namedExprList.add(expr); })*
37823780
{ expressionList = new ExpressionList(namedExprList); } )
37833781
|
3784-
LOOKAHEAD(3) expressionList=SimpleExpressionList()
3782+
LOOKAHEAD(3) expressionList=SimpleExpressionList(true)
37853783
|
3786-
("(" expressionList=SimpleExpressionList() ")" { execute.setParenthesis(true); })
3784+
("(" expressionList=SimpleExpressionList(true) ")" { execute.setParenthesis(true); })
37873785
)?
37883786

37893787
{
@@ -3882,7 +3880,7 @@ Function InternalFunction(Function retval) :
38823880
|
38833881
LOOKAHEAD(NamedExpressionListExprFirst()) namedExpressionList = NamedExpressionListExprFirst()
38843882
|
3885-
LOOKAHEAD(3) (expressionList=SimpleExpressionList() [ orderByList = OrderByElements() { retval.setOrderByElements(orderByList); } ])
3883+
LOOKAHEAD(3) (expressionList=SimpleExpressionList(true) [ orderByList = OrderByElements() { retval.setOrderByElements(orderByList); } ])
38863884
|
38873885
expr = SubSelect() { expr.setUseBrackets(false); expressionList = new ExpressionList(expr); }
38883886

@@ -3940,7 +3938,7 @@ MySQLGroupConcat MySQLGroupConcat():{
39403938
{
39413939
<K_GROUP_CONCAT> "("
39423940
[<K_DISTINCT> { retval.setDistinct(true); } ]
3943-
expressionList = SimpleExpressionList()
3941+
expressionList = SimpleExpressionList(true)
39443942
[ orderByList = OrderByElements() { retval.setOrderByElements(orderByList); } ]
39453943
[ <K_SEPARATOR> t=<S_CHAR_LITERAL> { retval.setSeparator(t.image); } ]
39463944
")"

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4520,4 +4520,14 @@ public void testProblematicDeparsingIssue1183_2() throws JSQLParserException {
45204520
public void testKeywordCostsIssue1185() throws JSQLParserException {
45214521
assertSqlCanBeParsedAndDeparsed("WITH costs AS (SELECT * FROM MY_TABLE1 AS ALIAS_TABLE1) SELECT * FROM TESTSTMT");
45224522
}
4523+
4524+
@Test
4525+
public void testKeywordCostsIssue1135() throws JSQLParserException {
4526+
assertSqlCanBeParsedAndDeparsed("with sample_data(day, value) as (values ((0, 13), (1, 12), (2, 15), (3, 4), (4, 8), (5, 16))) select day, value from sample_data", true);
4527+
}
4528+
4529+
@Test
4530+
public void testKeywordCostsIssue1135_2() throws JSQLParserException {
4531+
assertSqlCanBeParsedAndDeparsed("with sample_data(day, value) as (values (0, 13), (1, 12), (2, 15), (3, 4), (4, 8), (5, 16)) select day, value from sample_data", true);
4532+
}
45234533
}

0 commit comments

Comments
 (0)