Skip to content

Commit 6b45218

Browse files
committed
introduced partial / nonpartial parse for CCJSqlParserUtil methods
1 parent 0aa229d commit 6b45218

File tree

5 files changed

+87
-22
lines changed

5 files changed

+87
-22
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Also I would like to know about needed examples or documentation stuff.
4949
## Extensions in the latest SNAPSHOT version 1.2
5050

5151
* introduced alias for subquery in combination with a pivot definition (this **changes** alias handling within the library for pivot sqls)
52+
* force the parser to fully parse a String using parseCondExpression or parseExpression
5253

5354
## Extensions of JSqlParser releases
5455

src/main/java/net/sf/jsqlparser/parser/CCJSqlParserUtil.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,20 @@ public static Statement parse(InputStream is, String encoding) throws JSQLParser
9393
* @throws JSQLParserException
9494
*/
9595
public static Expression parseExpression(String expression) throws JSQLParserException {
96+
return parseExpression(expression, true);
97+
}
98+
99+
public static Expression parseExpression(String expression, boolean allowPartialParse) throws JSQLParserException {
96100
CCJSqlParser parser = new CCJSqlParser(new StringReader(expression));
97101
try {
98-
return parser.SimpleExpression();
99-
} catch (Exception ex) {
102+
Expression expr = parser.SimpleExpression();
103+
if (!allowPartialParse && parser.getNextToken().kind != CCJSqlParserTokenManager.EOF) {
104+
throw new JSQLParserException("could only parse partial expression " + expr.toString());
105+
}
106+
return expr;
107+
} catch (JSQLParserException ex) {
108+
throw ex;
109+
} catch (ParseException ex) {
100110
throw new JSQLParserException(ex);
101111
}
102112
}
@@ -109,10 +119,27 @@ public static Expression parseExpression(String expression) throws JSQLParserExc
109119
* @throws JSQLParserException
110120
*/
111121
public static Expression parseCondExpression(String condExpr) throws JSQLParserException {
122+
return parseCondExpression(condExpr, true);
123+
}
124+
125+
/**
126+
* Parse an conditional expression. This is the expression after a where clause.
127+
*
128+
* @param condExpr
129+
* @param allowPartialParse false: needs the whole string to be processed.
130+
* @return
131+
*/
132+
public static Expression parseCondExpression(String condExpr, boolean allowPartialParse) throws JSQLParserException {
112133
CCJSqlParser parser = new CCJSqlParser(new StringReader(condExpr));
113134
try {
114-
return parser.Expression();
115-
} catch (Exception ex) {
135+
Expression expr = parser.Expression();
136+
if (!allowPartialParse && parser.getNextToken().kind != CCJSqlParserTokenManager.EOF) {
137+
throw new JSQLParserException("could only parse partial expression " + expr.toString());
138+
}
139+
return expr;
140+
} catch (JSQLParserException ex) {
141+
throw ex;
142+
} catch (ParseException ex) {
116143
throw new JSQLParserException(ex);
117144
}
118145
}

src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.sf.jsqlparser.parser;
22

3+
import net.sf.jsqlparser.JSQLParserException;
34
import net.sf.jsqlparser.expression.Expression;
45
import net.sf.jsqlparser.expression.LongValue;
56
import net.sf.jsqlparser.expression.Parenthesis;
@@ -60,10 +61,39 @@ public void testParseExpression2() throws Exception {
6061
assertTrue(mult.getLeftExpression() instanceof LongValue);
6162
assertTrue(mult.getRightExpression() instanceof Parenthesis);
6263
}
64+
65+
@Test(expected = JSQLParserException.class)
66+
public void testParseExpressionNonPartial() throws Exception {
67+
Expression result = CCJSqlParserUtil.parseExpression("a+", false);
68+
}
69+
70+
@Test
71+
public void testParseExpressionNonPartial2() throws Exception {
72+
Expression result = CCJSqlParserUtil.parseExpression("a+", true);
73+
assertEquals("a", result.toString());
74+
}
6375

6476
@Test
6577
public void testParseCondExpression() throws Exception {
6678
Expression result = CCJSqlParserUtil.parseCondExpression("a+b>5 and c<3");
6779
assertEquals("a + b > 5 AND c < 3", result.toString());
6880
}
81+
82+
@Test
83+
public void testParseCondExpressionNonPartial() throws Exception {
84+
Expression result = CCJSqlParserUtil.parseCondExpression("x=92 and y=29", false);
85+
assertEquals("x = 92 AND y = 29", result.toString());
86+
}
87+
88+
@Test(expected = JSQLParserException.class)
89+
public void testParseCondExpressionNonPartial2() throws Exception {
90+
Expression result = CCJSqlParserUtil.parseCondExpression("x=92 lasd y=29", false);
91+
System.out.println(result.toString());
92+
}
93+
94+
@Test
95+
public void testParseCondExpressionPartial2() throws Exception {
96+
Expression result = CCJSqlParserUtil.parseCondExpression("x=92 lasd y=29", true);
97+
assertEquals("x = 92", result.toString());
98+
}
6999
}

src/test/java/net/sf/jsqlparser/test/create/CreateTableTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void testCreateTable3() throws JSQLParserException {
3636
assertSqlCanBeParsedAndDeparsed(statement);
3737
}
3838

39-
public void testCreateTableAsSelect() throws JSQLParserException {
39+
public void testCreateTableAsSelect() throws JSQLParserException, JSQLParserException, JSQLParserException, JSQLParserException {
4040
String statement = "CREATE TABLE a AS SELECT col1, col2 FROM b";
4141
assertSqlCanBeParsedAndDeparsed(statement);
4242
}
@@ -264,6 +264,10 @@ public void testTimestampWithTimezone() throws JSQLParserException {
264264
"last_change_date TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP (0), " +
265265
"CONSTRAINT region_name_unique UNIQUE (region_name))");
266266
}
267+
268+
public void testCreateTableAsSelect3() throws JSQLParserException {
269+
assertSqlCanBeParsedAndDeparsed("CREATE TABLE public.sales1 AS (SELECT * FROM public.sales)");
270+
}
267271

268272
public void testRUBiSCreateList() throws Exception {
269273
BufferedReader in = new BufferedReader(new InputStreamReader(CreateTableTest.class.

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

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,10 @@ public void testBrackets2() throws JSQLParserException {
14671467
assertSqlCanBeParsedAndDeparsed(stmt);
14681468
}
14691469

1470+
public void testBrackets3() throws JSQLParserException {
1471+
assertSqlCanBeParsedAndDeparsed("SELECT * FROM \"2016\"");
1472+
}
1473+
14701474
public void testProblemSqlServer_Modulo_Proz() throws Exception {
14711475
String stmt = "SELECT 5 % 2 FROM A";
14721476
assertSqlCanBeParsedAndDeparsed(stmt);
@@ -1928,26 +1932,26 @@ public void testPivotXmlSubquery1() throws JSQLParserException {
19281932
public void testPivotFunction() throws JSQLParserException {
19291933
assertSqlCanBeParsedAndDeparsed("SELECT to_char((SELECT col1 FROM (SELECT times_purchased, state_code FROM customers t) PIVOT (count(state_code) FOR state_code IN ('NY', 'CT', 'NJ', 'FL', 'MO')) ORDER BY times_purchased)) FROM DUAL");
19301934
}
1931-
1935+
19321936
public void testPivotWithAlias() throws JSQLParserException {
19331937
assertSqlCanBeParsedAndDeparsed("SELECT * FROM (SELECT * FROM mytable LEFT JOIN mytable2 ON Factor_ID = Id) f PIVOT (max(f.value) FOR f.factoryCode IN (ZD, COD, SW, PH))");
19341938
}
1935-
1939+
19361940
public void testPivotWithAlias2() throws JSQLParserException {
19371941
assertSqlCanBeParsedAndDeparsed("SELECT * FROM (SELECT * FROM mytable LEFT JOIN mytable2 ON Factor_ID = Id) f PIVOT (max(f.value) FOR f.factoryCode IN (ZD, COD, SW, PH)) d");
19381942
}
1939-
1943+
19401944
public void testPivotWithAlias3() throws JSQLParserException {
19411945
assertSqlCanBeParsedAndDeparsed("SELECT * FROM (SELECT * FROM mytable LEFT JOIN mytable2 ON Factor_ID = Id) PIVOT (max(f.value) FOR f.factoryCode IN (ZD, COD, SW, PH)) d");
19421946
}
1943-
1947+
19441948
public void testPivotWithAlias4() throws JSQLParserException {
1945-
assertSqlCanBeParsedAndDeparsed("SELECT * FROM (" +
1946-
"SELECT a.Station_ID stationId, b.Factor_Code factoryCode, a.Value value" +
1947-
" FROM T_Data_Real a" +
1948-
" LEFT JOIN T_Bas_Factor b ON a.Factor_ID = b.Id" +
1949-
") f " +
1950-
"PIVOT (max(f.value) FOR f.factoryCode IN (ZD, COD, SW, PH)) d");
1949+
assertSqlCanBeParsedAndDeparsed("SELECT * FROM ("
1950+
+ "SELECT a.Station_ID stationId, b.Factor_Code factoryCode, a.Value value"
1951+
+ " FROM T_Data_Real a"
1952+
+ " LEFT JOIN T_Bas_Factor b ON a.Factor_ID = b.Id"
1953+
+ ") f "
1954+
+ "PIVOT (max(f.value) FOR f.factoryCode IN (ZD, COD, SW, PH)) d");
19511955
}
19521956

19531957
public void testRegexpLike1() throws JSQLParserException {
@@ -2142,7 +2146,7 @@ public void testSelectJoin2() throws JSQLParserException {
21422146
public void testAnyConditionSubSelect() throws JSQLParserException {
21432147
assertSqlCanBeParsedAndDeparsed("SELECT e1.empno, e1.sal FROM emp e1 WHERE e1.sal > ANY (SELECT e2.sal FROM emp e2 WHERE e2.deptno = 10)");
21442148
}
2145-
2149+
21462150
public void testAllConditionSubSelect() throws JSQLParserException {
21472151
assertSqlCanBeParsedAndDeparsed("SELECT e1.empno, e1.sal FROM emp e1 WHERE e1.sal > ALL (SELECT e2.sal FROM emp e2 WHERE e2.deptno = 10)");
21482152
}
@@ -2578,8 +2582,8 @@ public void testForUpdateWaitParseDeparse() throws JSQLParserException {
25782582
}
25792583

25802584
/**
2581-
* Validates that a SELECT with FOR UPDATE WAIT <TIMEOUT> correctly sets a {@link Wait} with the
2582-
* correct timeout value.
2585+
* Validates that a SELECT with FOR UPDATE WAIT <TIMEOUT> correctly sets a {@link Wait} with the correct timeout
2586+
* value.
25832587
*/
25842588
public void testForUpdateWaitWithTimeout() throws JSQLParserException {
25852589
String statement = "SELECT * FROM mytable FOR UPDATE WAIT 60";
@@ -2599,7 +2603,6 @@ public void testForUpdateWaitWithTimeout() throws JSQLParserException {
25992603
// public void testSubSelectFailsIssue394_2() throws JSQLParserException {
26002604
// assertSqlCanBeParsedAndDeparsed("select * from all");
26012605
// }
2602-
26032606
public void testMysqlIndexHints() throws JSQLParserException {
26042607
assertSqlCanBeParsedAndDeparsed("SELECT column FROM testtable AS t0 USE INDEX (index1)");
26052608
assertSqlCanBeParsedAndDeparsed("SELECT column FROM testtable AS t0 IGNORE INDEX (index1)");
@@ -2617,15 +2620,15 @@ public void testMysqlMultipleIndexHints() throws JSQLParserException {
26172620
assertSqlCanBeParsedAndDeparsed("SELECT column FROM testtable AS t0 IGNORE INDEX (index1,index2)");
26182621
assertSqlCanBeParsedAndDeparsed("SELECT column FROM testtable AS t0 FORCE INDEX (index1,index2)");
26192622
}
2620-
2623+
26212624
public void testProblemIssue435() throws JSQLParserException {
26222625
assertSqlCanBeParsedAndDeparsed("SELECT if(z, 'a', 'b') AS business_type FROM mytable1");
26232626
}
2624-
2627+
26252628
public void testProblemIssue437Index() throws JSQLParserException {
26262629
assertSqlCanBeParsedAndDeparsed("select count(id) from p_custom_data ignore index(pri) where tenant_id=28257 and entity_id=92609 and delete_flg=0 and ( (dbc_relation_2 = 52701) and (dbc_relation_2 in ( select id from a_order where tenant_id = 28257 and 1=1 ) ) ) order by id desc, id desc", true);
26272630
}
2628-
2631+
26292632
public void testProblemIssue445() throws JSQLParserException {
26302633
assertSqlCanBeParsedAndDeparsed("SELECT E.ID_NUMBER, row_number() OVER (PARTITION BY E.ID_NUMBER ORDER BY E.DEFINED_UPDATED DESC) rn FROM T_EMPLOYMENT E");
26312634
}

0 commit comments

Comments
 (0)