Skip to content

Commit 3f0e47c

Browse files
Merge commit 'a5204f63ccb1ea8d30de002b4fc40be39935c275' into AllowComplexParsingClean
Conflicts: src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt src/test/java/net/sf/jsqlparser/statement/select/NestedBracketsPerformanceTest.java src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java
2 parents 42abed4 + a5204f6 commit 3f0e47c

23 files changed

Lines changed: 371 additions & 86 deletions

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**

pmd-rules.xml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,17 @@ under the License.
5454
<rule ref="category/java/codestyle.xml/UselessParentheses" />
5555
<rule ref="category/java/codestyle.xml/UselessQualifiedThis" />
5656

57-
<!-- for Codazy -->
58-
<rule ref="category/java/codestyle.xml/MethodNamingConventions" />
57+
<!-- for Codazy -->
58+
<rule ref="category/java/codestyle.xml/MethodNamingConventions">
59+
<properties>
60+
<property name="methodPattern" value="[a-z][a-zA-Z0-9]*" />
61+
<property name="staticPattern" value="[a-z][a-zA-Z0-9]*" />
62+
<property name="nativePattern" value="[a-z][a-zA-Z0-9]*" />
63+
<property name="junit3TestPattern" value="test[A-Z0-9][a-zA-Z0-9]*" />
64+
<property name="junit4TestPattern" value="[a-z][a-zA-Z0-9]*" />
65+
<property name="junit5TestPattern" value="[a-z][a-zA-Z0-9]*" />
66+
</properties>
67+
</rule>
5968
<rule ref="category/java/codestyle.xml/ClassNamingConventions" />
6069

6170
<rule ref="category/java/design.xml/CollapsibleIfStatements" />

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

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
*/
4444
public class CaseExpression extends ASTNodeAccessImpl implements Expression {
4545

46+
private boolean usingBrackets = false;
4647
private Expression switchExpression;
4748
private List<WhenClause> whenClauses;
4849
private Expression elseExpression;
@@ -90,9 +91,9 @@ public void setWhenClauses(List<WhenClause> whenClauses) {
9091

9192
@Override
9293
public String toString() {
93-
return "CASE " + ((switchExpression != null) ? switchExpression + " " : "")
94+
return (usingBrackets ? "(" : "") + "CASE " + ((switchExpression != null) ? switchExpression + " " : "")
9495
+ PlainSelect.getStringList(whenClauses, false, false) + " "
95-
+ ((elseExpression != null) ? "ELSE " + elseExpression + " " : "") + "END";
96+
+ ((elseExpression != null) ? "ELSE " + elseExpression + " " : "") + "END" + (usingBrackets ? ")" : "");
9697
}
9798

9899
public CaseExpression withSwitchExpression(Expression switchExpression) {
@@ -129,4 +130,26 @@ public <E extends Expression> E getSwitchExpression(Class<E> type) {
129130
public <E extends Expression> E getElseExpression(Class<E> type) {
130131
return type.cast(getElseExpression());
131132
}
133+
134+
/**
135+
* @return the usingBrackets
136+
*/
137+
public boolean isUsingBrackets() {
138+
return usingBrackets;
139+
}
140+
141+
/**
142+
* @param usingBrackets the usingBrackets to set
143+
*/
144+
public void setUsingBrackets(boolean usingBrackets) {
145+
this.usingBrackets = usingBrackets;
146+
}
147+
148+
/**
149+
* @param usingBrackets the usingBrackets to set
150+
*/
151+
public CaseExpression withUsingBrackets(boolean usingBrackets) {
152+
this.usingBrackets=usingBrackets;
153+
return this;
154+
}
132155
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,6 @@ public interface ExpressionVisitor {
163163
void visit(VariableAssignment aThis);
164164

165165
void visit(XMLSerializeExpr aThis);
166+
167+
void visit(TimezoneExpression aThis);
166168
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,4 +576,9 @@ public void visit(XMLSerializeExpr expr) {
576576
elm.getExpression().accept(this);
577577
}
578578
}
579+
580+
@Override
581+
public void visit(TimezoneExpression expr) {
582+
expr.getLeftExpression().accept(this);
583+
}
579584
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2019 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.expression;
11+
12+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
13+
14+
import java.util.ArrayList;
15+
import java.util.List;
16+
17+
public class TimezoneExpression extends ASTNodeAccessImpl implements Expression {
18+
19+
private Expression leftExpression;
20+
private ArrayList<String> timezoneExpressions = new ArrayList<>();
21+
22+
public Expression getLeftExpression() {
23+
return leftExpression;
24+
}
25+
26+
public void setLeftExpression(Expression expression) {
27+
leftExpression = expression;
28+
}
29+
30+
@Override
31+
public void accept(ExpressionVisitor expressionVisitor) {
32+
expressionVisitor.visit(this);
33+
}
34+
35+
public List<String> getTimezoneExpressions() {
36+
return timezoneExpressions;
37+
}
38+
39+
public void addTimezoneExpression(String timezoneExpr) {
40+
this.timezoneExpressions.add(timezoneExpr);
41+
}
42+
43+
@Override
44+
public String toString() {
45+
String returnValue = getLeftExpression().toString();
46+
for (String expr : timezoneExpressions) {
47+
returnValue += " AT TIME ZONE " + expr;
48+
}
49+
50+
return returnValue;
51+
}
52+
}

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

Lines changed: 8 additions & 2 deletions
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
}
@@ -33,7 +34,7 @@ public ExpressionList(List<Expression> expressions) {
3334
}
3435

3536
public ExpressionList(Expression... expressions) {
36-
this.expressions = Arrays.asList(expressions);
37+
this.expressions = new ArrayList<>(Arrays.asList(expressions));
3738
}
3839

3940
public List<Expression> getExpressions() {
@@ -55,14 +56,19 @@ public void setExpressions(List<Expression> expressions) {
5556
this.expressions = expressions;
5657
}
5758

59+
public ExpressionList withBrackets(boolean brackets) {
60+
this.withBrackets = brackets;
61+
return this;
62+
}
63+
5864
@Override
5965
public void accept(ItemsListVisitor itemsListVisitor) {
6066
itemsListVisitor.visit(this);
6167
}
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: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,68 +11,72 @@
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

67-
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);
65+
public ValuesStatement addExpressions(Expression... addExpressions) {
66+
if (expressions != null && expressions instanceof ExpressionList) {
67+
((ExpressionList) expressions).addExpressions(addExpressions);
68+
return this;
69+
} else {
70+
return this.withExpressions(new ExpressionList(addExpressions));
71+
}
7172
}
7273

73-
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);
74+
public ValuesStatement addExpressions(Collection<? extends Expression> addExpressions) {
75+
if (expressions != null && expressions instanceof ExpressionList) {
76+
((ExpressionList) expressions).addExpressions(addExpressions);
77+
return this;
78+
} else {
79+
return this.withExpressions(new ExpressionList(new ArrayList<>(addExpressions)));
80+
}
7781
}
7882
}

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import java.util.ArrayList;
1313
import java.util.List;
14+
1415
import net.sf.jsqlparser.expression.AllComparisonExpression;
1516
import net.sf.jsqlparser.expression.AnalyticExpression;
1617
import net.sf.jsqlparser.expression.AnyComparisonExpression;
@@ -48,6 +49,7 @@
4849
import net.sf.jsqlparser.expression.TimeKeyExpression;
4950
import net.sf.jsqlparser.expression.TimeValue;
5051
import net.sf.jsqlparser.expression.TimestampValue;
52+
import net.sf.jsqlparser.expression.TimezoneExpression;
5153
import net.sf.jsqlparser.expression.UserVariable;
5254
import net.sf.jsqlparser.expression.ValueListExpression;
5355
import net.sf.jsqlparser.expression.VariableAssignment;
@@ -829,9 +831,7 @@ public void visit(Comment comment) {
829831

830832
@Override
831833
public void visit(ValuesStatement values) {
832-
for (Expression expr : values.getExpressions()) {
833-
expr.accept(this);
834-
}
834+
values.getExpressions().accept(this);
835835
}
836836

837837
@Override
@@ -930,4 +930,9 @@ public void visit(CreateSynonym createSynonym) {
930930
private static <T> void throwUnsupported(T type){
931931
throw new UnsupportedOperationException(String.format("Finding tables from %s is not supported", type.getClass().getSimpleName()));
932932
}
933+
934+
@Override
935+
public void visit(TimezoneExpression aThis) {
936+
aThis.getLeftExpression().accept(this);
937+
}
933938
}

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import net.sf.jsqlparser.expression.TimeKeyExpression;
5252
import net.sf.jsqlparser.expression.TimeValue;
5353
import net.sf.jsqlparser.expression.TimestampValue;
54+
import net.sf.jsqlparser.expression.TimezoneExpression;
5455
import net.sf.jsqlparser.expression.UserVariable;
5556
import net.sf.jsqlparser.expression.ValueListExpression;
5657
import net.sf.jsqlparser.expression.VariableAssignment;
@@ -604,7 +605,7 @@ public void visit(TimeValue timeValue) {
604605

605606
@Override
606607
public void visit(CaseExpression caseExpression) {
607-
buffer.append("CASE ");
608+
buffer.append(caseExpression.isUsingBrackets() ? "(" : "").append("CASE ");
608609
Expression switchExp = caseExpression.getSwitchExpression();
609610
if (switchExp != null) {
610611
switchExp.accept(this);
@@ -622,7 +623,7 @@ public void visit(CaseExpression caseExpression) {
622623
buffer.append(" ");
623624
}
624625

625-
buffer.append("END");
626+
buffer.append("END").append(caseExpression.isUsingBrackets() ? ")" : "");
626627
}
627628

628629
@Override
@@ -989,4 +990,13 @@ public void visit(XMLSerializeExpr expr) {
989990
}
990991
buffer.append(") AS ").append(expr.getDataType()).append(")");
991992
}
993+
994+
@Override
995+
public void visit(TimezoneExpression var) {
996+
var.getLeftExpression().accept(this);
997+
998+
for (String expr : var.getTimezoneExpressions()) {
999+
buffer.append(" AT TIME ZONE " + expr);
1000+
}
1001+
}
9921002
}

0 commit comments

Comments
 (0)