Skip to content

Commit 9ecbb28

Browse files
committed
Merge origin/master
2 parents 686958c + 426102e commit 9ecbb28

9 files changed

Lines changed: 151 additions & 27 deletions

File tree

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/ExpressionVisitorAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ protected void visitBinaryExpression(BinaryExpression expr) {
399399

400400
@Override
401401
public void visit(JsonExpression jsonExpr) {
402-
visit(jsonExpr.getColumn());
402+
jsonExpr.getExpression().accept(this);
403403
}
404404

405405
@Override

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

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@
1313
import java.util.List;
1414

1515
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
16-
import net.sf.jsqlparser.schema.Column;
1716

1817
public class JsonExpression extends ASTNodeAccessImpl implements Expression {
1918

20-
private Column column;
19+
private Expression expr;
2120

2221
private List<String> idents = new ArrayList<String>();
2322
private List<String> operators = new ArrayList<String>();
@@ -27,12 +26,12 @@ public void accept(ExpressionVisitor expressionVisitor) {
2726
expressionVisitor.visit(this);
2827
}
2928

30-
public Column getColumn() {
31-
return column;
29+
public Expression getExpression() {
30+
return expr;
3231
}
3332

34-
public void setColumn(Column column) {
35-
this.column = column;
33+
public void setExpression(Expression expr) {
34+
this.expr = expr;
3635
}
3736

3837
// public List<String> getIdents() {
@@ -46,7 +45,7 @@ public void setColumn(Column column) {
4645
// operators.add("->");
4746
// }
4847
// }
49-
//
48+
//
5049
// public void addIdent(String ident) {
5150
// addIdent(ident, "->");
5251
// }
@@ -58,15 +57,15 @@ public void addIdent(String ident, String operator) {
5857
@Override
5958
public String toString() {
6059
StringBuilder b = new StringBuilder();
61-
b.append(column.toString());
60+
b.append(expr.toString());
6261
for (int i = 0; i < idents.size(); i++) {
6362
b.append(operators.get(i)).append(idents.get(i));
6463
}
6564
return b.toString();
6665
}
6766

68-
public JsonExpression withColumn(Column column) {
69-
this.setColumn(column);
67+
public JsonExpression withExpression(Expression expr) {
68+
this.setExpression(expr);
7069
return this;
7170
}
7271
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ public void visit(TimeValue timeValue) {
604604

605605
@Override
606606
public void visit(CaseExpression caseExpression) {
607-
buffer.append("CASE ");
607+
buffer.append(caseExpression.isUsingBrackets() ? "(" : "").append("CASE ");
608608
Expression switchExp = caseExpression.getSwitchExpression();
609609
if (switchExp != null) {
610610
switchExp.accept(this);
@@ -622,7 +622,7 @@ public void visit(CaseExpression caseExpression) {
622622
buffer.append(" ");
623623
}
624624

625-
buffer.append("END");
625+
buffer.append("END").append(caseExpression.isUsingBrackets() ? ")" : "");
626626
}
627627

628628
@Override

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ public void visit(RegExpMySQLOperator rexpr) {
454454

455455
@Override
456456
public void visit(JsonExpression jsonExpr) {
457-
validateOptionalExpression(jsonExpr.getColumn());
457+
validateOptionalExpression(jsonExpr.getExpression());
458458
}
459459

460460
@Override

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

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ import java.util.*;
6767
* The parser generated by JavaCC
6868
*/
6969
public class CCJSqlParser extends AbstractJSqlParser<CCJSqlParser> {
70+
public int bracketsCounter = 0;
71+
public int caseCounter = 0;
7072

7173
public CCJSqlParser withConfiguration(FeatureConfiguration configuration) {
7274
token_source.configuration = configuration;
@@ -3481,18 +3483,28 @@ ArrayConstructor ArrayConstructor(final boolean arrayKeyword) : {
34813483

34823484
JsonExpression JsonExpression() : {
34833485
JsonExpression result = new JsonExpression();
3484-
Column column;
3486+
Expression expr;
34853487
Token token;
3488+
ColDataType type = null;
3489+
CastExpression castExpr = null;
34863490
}
34873491
{
3488-
column=Column() (
3492+
expr=Column()
3493+
( "::" type=ColDataType() {
3494+
castExpr = new CastExpression();
3495+
castExpr.setUseCastKeyword(false);
3496+
castExpr.setLeftExpression(expr);
3497+
castExpr.setType(type);
3498+
expr=castExpr;
3499+
} )*
3500+
(
34893501
"->" (token=<S_CHAR_LITERAL> | token=<S_LONG>) {result.addIdent(token.image,"->");} |
34903502
"->>" (token=<S_CHAR_LITERAL> | token=<S_LONG>) {result.addIdent(token.image,"->>");} |
34913503
"#>" token=<S_CHAR_LITERAL> {result.addIdent(token.image,"#>");} |
34923504
"#>>" token=<S_CHAR_LITERAL> {result.addIdent(token.image,"#>>");}
34933505
)+
34943506
{
3495-
result.setColumn(column);
3507+
result.setExpression(expr);
34963508
return result;
34973509
}
34983510
}
@@ -3685,11 +3697,14 @@ Expression CaseWhenExpression() #CaseWhenExpression:
36853697
Expression elseExp = null;
36863698
}
36873699
{
3688-
<K_CASE>
3700+
<K_CASE> { caseCounter++; }
36893701
[ switchExp=Condition() ]
36903702
( clause=WhenThenSearchCondition() { whenClauses.add(clause); } )+
3691-
[<K_ELSE> elseExp=Condition()]
3692-
<K_END>
3703+
[<K_ELSE> (LOOKAHEAD( ["("] CaseWhenExpression() [")"] ) ["("] elseExp=CaseWhenExpression() [")" { ((CaseExpression) elseExp).setUsingBrackets(true); } ]
3704+
| elseExp=Condition()
3705+
)
3706+
]
3707+
<K_END> { caseCounter--; }
36933708
{
36943709
caseExp.setSwitchExpression(switchExp);
36953710
caseExp.setWhenClauses(whenClauses);
@@ -3705,8 +3720,10 @@ WhenClause WhenThenSearchCondition():
37053720
Expression thenExp = null;
37063721
}
37073722
{
3708-
<K_WHEN> (LOOKAHEAD(Expression()) whenExp=Expression() | whenExp=SimpleExpression())
3709-
<K_THEN> thenExp=Expression()
3723+
<K_WHEN> whenExp=Expression()
3724+
<K_THEN> (LOOKAHEAD( ["("] CaseWhenExpression() [")"] ) ["("] thenExp=CaseWhenExpression() [")" { ((CaseExpression) thenExp).setUsingBrackets(true); }]
3725+
| thenExp=Expression()
3726+
)
37103727
{
37113728
whenThen.setWhenExpression(whenExp);
37123729
whenThen.setThenExpression(thenExp);

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

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,73 @@ public void testIssue235() throws JSQLParserException {
3838
assertSqlCanBeParsedAndDeparsed("SELECT CASE WHEN ( CASE WHEN ( CASE WHEN ( CASE WHEN ( 1 ) THEN 0 END ) THEN 0 END ) THEN 0 END ) THEN 0 END FROM a", true);
3939
}
4040

41-
@Test(timeout = 100000)
41+
@Test
42+
public void testNestedCaseWhenWithoutBracketsIssue1162() throws JSQLParserException {
43+
assertSqlCanBeParsedAndDeparsed("CREATE VIEW VIEW_NAME1 AS\n" +
44+
"SELECT CASE\n" +
45+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
46+
"ELSE CASE\n" +
47+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
48+
"ELSE CASE\n" +
49+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
50+
"ELSE CASE\n" +
51+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
52+
"ELSE CASE\n" +
53+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
54+
"ELSE CASE\n" +
55+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
56+
"ELSE CASE\n" +
57+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
58+
"ELSE CASE\n" +
59+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
60+
"ELSE CASE\n" +
61+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
62+
"ELSE CASE\n" +
63+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
64+
"ELSE CASE\n" +
65+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
66+
"ELSE CASE\n" +
67+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
68+
"ELSE CASE\n" +
69+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
70+
"ELSE CASE WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT' ELSE '0' END END END END END END END END END END END END END END COLUMNALIAS\n" +
71+
"FROM TABLE1", true);
72+
}
73+
74+
@Test
75+
public void testNestedCaseWhenWithBracketsIssue1162() throws JSQLParserException {
76+
assertSqlCanBeParsedAndDeparsed("CREATE VIEW VIEW_NAME1 AS\n" +
77+
"SELECT CASE\n" +
78+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
79+
"ELSE (CASE\n" +
80+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
81+
"ELSE (CASE\n" +
82+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
83+
"ELSE (CASE\n" +
84+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
85+
"ELSE (CASE\n" +
86+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
87+
"ELSE (CASE\n" +
88+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
89+
"ELSE (CASE\n" +
90+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
91+
"ELSE (CASE\n" +
92+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
93+
"ELSE (CASE\n" +
94+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
95+
"ELSE (CASE\n" +
96+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
97+
"ELSE (CASE\n" +
98+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
99+
"ELSE (CASE\n" +
100+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
101+
"ELSE (CASE\n" +
102+
"WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT'\n" +
103+
"ELSE (CASE WHEN WDGFLD.PORTTYPE = 1 THEN 'INPUT PORT' ELSE '0' END) END) END) END) END) END) END) END) END) END) END) END) END) END COLUMNALIAS\n" +
104+
"FROM TABLE1", true);
105+
}
106+
107+
@Test(timeout = 200000)
42108
@Ignore
43109
public void testIssue496() throws JSQLParserException {
44110
assertSqlCanBeParsedAndDeparsed("select isNull(charLen(TEST_ID,0)+ isNull(charLen(TEST_DVC,0)+ isNull(charLen(TEST_NO,0)+ isNull(charLen(ATEST_ID,0)+ isNull(charLen(TESTNO,0)+ isNull(charLen(TEST_CTNT,0)+ isNull(charLen(TEST_MESG_CTNT,0)+ isNull(charLen(TEST_DTM,0)+ isNull(charLen(TEST_DTT,0)+ isNull(charLen(TEST_ADTT,0)+ isNull(charLen(TEST_TCD,0)+ isNull(charLen(TEST_PD,0)+ isNull(charLen(TEST_VAL,0)+ isNull(charLen(TEST_YN,0)+ isNull(charLen(TEST_DTACM,0)+ isNull(charLen(TEST_MST,0) from test_info_m");

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,7 +1358,12 @@ public void testCase() throws JSQLParserException {
13581358
+ // "WHEN (SELECT c FROM tab2 WHERE d = 2) = 3 THEN 'AAA' " +
13591359
"END) FROM tab1";
13601360
assertSqlCanBeParsedAndDeparsed(statement);
1361+
}
13611362

1363+
@Test
1364+
public void testNestedCaseCondition() throws JSQLParserException {
1365+
assertSqlCanBeParsedAndDeparsed("SELECT CASE WHEN CASE WHEN 1 THEN 10 ELSE 20 END > 15 THEN 'BBB' END FROM tab1");
1366+
assertSqlCanBeParsedAndDeparsed("SELECT (CASE WHEN (CASE a WHEN 1 THEN 10 ELSE 20 END) > 15 THEN 'BBB' END) FROM tab1");
13621367
}
13631368

13641369
@Test
@@ -2723,6 +2728,11 @@ public void testJsonExpression() throws JSQLParserException {
27232728
}
27242729
}
27252730

2731+
@Test
2732+
public void testJsonExpressionWithCastExpression() throws JSQLParserException {
2733+
assertSqlCanBeParsedAndDeparsed("SELECT id FROM tbl WHERE p.company::json->'info'->>'country' = 'test'");
2734+
}
2735+
27262736
@Test
27272737
public void testJsonExpressionWithIntegerParameterIssue909() throws JSQLParserException {
27282738
assertSqlCanBeParsedAndDeparsed("select uc.\"id\", u.nickname, u.avatar, b.title, uc.images, uc.created_at as createdAt from library.ugc_comment uc INNER JOIN library.book b on (uc.books_id ->> 0)::INTEGER = b.\"id\" INNER JOIN library.users u ON uc.user_id = u.user_id where uc.id = 1", true);

0 commit comments

Comments
 (0)