Skip to content

Commit a7247eb

Browse files
committed
first try of error recovery for statement and statements
1 parent 1e30760 commit a7247eb

File tree

2 files changed

+136
-49
lines changed

2 files changed

+136
-49
lines changed

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

Lines changed: 93 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ import java.util.*;
8181
* The parser generated by JavaCC
8282
*/
8383
public class CCJSqlParser {
84+
boolean errorRecovery = false;
85+
List<ParseException> parseErrors = new ArrayList<ParseException>();
86+
8487
private void linkAST(ASTNodeAccess access, SimpleNode node) {
8588
access.setASTNode(node);
8689
node.jjtSetValue(access);
@@ -89,6 +92,14 @@ public class CCJSqlParser {
8992
public Node getASTRoot() {
9093
return jjtree.rootNode();
9194
}
95+
96+
public void setErrorRecovery(boolean errorRecovery) {
97+
this.errorRecovery = errorRecovery;
98+
}
99+
100+
public List<ParseException> getParseErrors() {
101+
return parseErrors;
102+
}
92103
}
93104

94105
PARSER_END(CCJSqlParser)
@@ -284,53 +295,71 @@ TOKEN:
284295
Statement Statement() #Statement:
285296
{ Statement stm; }
286297
{
287-
stm = SingleStatement()
288-
[<ST_SEMICOLON>]
289-
<EOF>
290-
{
291-
return stm;
298+
try {
299+
stm = SingleStatement()
300+
[<ST_SEMICOLON>]
301+
<EOF>
302+
{
303+
return stm;
304+
}
305+
} catch (ParseException e) {
306+
if (errorRecovery) {
307+
parseErrors.add(e);
308+
error_skipto(ST_SEMICOLON);
309+
}
310+
else
311+
throw e;
292312
}
293313
}
294314

295315
Statement SingleStatement() :
296-
{ Statement stm;}
316+
{ Statement stm = null;}
297317
{
298-
(
299-
stm = Select()
300-
|
301-
stm = Update()
302-
|
303-
stm = Insert()
304-
|
305-
stm = Delete()
306-
|
307-
stm = Replace()
308-
|
309-
LOOKAHEAD(2)
310-
stm = AlterTable()
311-
|
312-
stm = Merge()
313-
|
314-
LOOKAHEAD(CreateIndex())
315-
stm = CreateIndex()
316-
|
317-
LOOKAHEAD(2)
318-
stm = CreateTable()
319-
|
320-
LOOKAHEAD(2)
321-
stm = CreateView()
322-
|
323-
stm = AlterView()
324-
|
325-
stm = Drop()
326-
|
327-
stm = Truncate()
328-
|
329-
stm = Execute()
330-
|
331-
stm = Set()
332-
)
333-
{ return stm; }
318+
try {
319+
(
320+
stm = Select()
321+
|
322+
stm = Update()
323+
|
324+
stm = Insert()
325+
|
326+
stm = Delete()
327+
|
328+
stm = Replace()
329+
|
330+
LOOKAHEAD(2)
331+
stm = AlterTable()
332+
|
333+
stm = Merge()
334+
|
335+
LOOKAHEAD(CreateIndex())
336+
stm = CreateIndex()
337+
|
338+
LOOKAHEAD(2)
339+
stm = CreateTable()
340+
|
341+
LOOKAHEAD(2)
342+
stm = CreateView()
343+
|
344+
stm = AlterView()
345+
|
346+
stm = Drop()
347+
|
348+
stm = Truncate()
349+
|
350+
stm = Execute()
351+
|
352+
stm = Set()
353+
)
354+
} catch (ParseException e) {
355+
if (errorRecovery) {
356+
parseErrors.add(e);
357+
error_skipto(ST_SEMICOLON);
358+
}
359+
else
360+
throw e;
361+
}
362+
{ return stm; }
334363
}
335364

336365
Statements Statements() #Statements :
@@ -339,16 +368,34 @@ Statements Statements() #Statements :
339368
Statement stm; }
340369
{
341370
(<ST_SEMICOLON>)*
342-
stm = SingleStatement() { list.add(stm); }
343-
( <ST_SEMICOLON> [ stm = SingleStatement() { list.add(stm); } ] )*
344-
<EOF>
345-
371+
try {
372+
stm = SingleStatement() { list.add(stm); }
373+
( <ST_SEMICOLON> [stm = SingleStatement() { list.add(stm); }] )*
374+
<EOF>
375+
} catch (ParseException e) {
376+
if (errorRecovery) {
377+
parseErrors.add(e);
378+
error_skipto(ST_SEMICOLON);
379+
}
380+
else
381+
throw e;
382+
}
346383
{
347384
stmts.setStatements(list);
348385
return stmts;
349386
}
350387
}
351388

389+
JAVACODE
390+
void error_skipto(int kind) {
391+
ParseException e = generateParseException();
392+
System.out.println(e.toString());
393+
Token t;
394+
do {
395+
t = getNextToken();
396+
} while (t.kind != kind && t.kind != EOF);
397+
}
398+
352399
SetStatement Set(): {
353400
String name;
354401
Expression value;

src/test/java/net/sf/jsqlparser/statement/StatementsTest.java

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package net.sf.jsqlparser.statement;
22

3+
import java.io.StringReader;
34
import net.sf.jsqlparser.JSQLParserException;
5+
import net.sf.jsqlparser.parser.CCJSqlParser;
46
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
7+
import net.sf.jsqlparser.parser.ParseException;
58
import net.sf.jsqlparser.statement.select.Select;
69
import org.junit.After;
710
import org.junit.AfterClass;
@@ -35,9 +38,6 @@ public void setUp() {
3538
public void tearDown() {
3639
}
3740

38-
/**
39-
* Test of toString method, of class Statements.
40-
*/
4141
@Test
4242
public void testStatements() throws JSQLParserException {
4343
String sqls = "select * from mytable; select * from mytable2;";
@@ -59,5 +59,45 @@ public void testStatementsProblem() throws JSQLParserException {
5959
assertTrue(parseStatements.getStatements().get(0) instanceof Select);
6060
assertTrue(parseStatements.getStatements().get(1) instanceof Select);
6161
}
62+
63+
@Test
64+
public void testStatementsErrorRecovery() throws JSQLParserException, ParseException {
65+
String sqls = "select * from mytable; select * from;";
66+
CCJSqlParser parser = new CCJSqlParser(new StringReader(sqls));
67+
parser.setErrorRecovery(true);
68+
Statements parseStatements = parser.Statements();
69+
70+
assertEquals(2, parseStatements.getStatements().size());
71+
72+
assertTrue(parseStatements.getStatements().get(0) instanceof Select);
73+
assertNull(parseStatements.getStatements().get(1));
74+
}
6275

76+
@Test
77+
public void testStatementsErrorRecovery2() throws JSQLParserException, ParseException {
78+
String sqls = "select * from1 table;";
79+
CCJSqlParser parser = new CCJSqlParser(new StringReader(sqls));
80+
parser.setErrorRecovery(true);
81+
Statements parseStatements = parser.Statements();
82+
83+
assertEquals(1, parseStatements.getStatements().size());
84+
85+
assertTrue(parseStatements.getStatements().get(0) instanceof Select);
86+
assertEquals(1,parser.getParseErrors().size());
87+
}
88+
89+
@Test
90+
public void testStatementsErrorRecovery3() throws JSQLParserException, ParseException {
91+
String sqls = "select * from mytable; select * from;select * from mytable2";
92+
CCJSqlParser parser = new CCJSqlParser(new StringReader(sqls));
93+
parser.setErrorRecovery(true);
94+
Statements parseStatements = parser.Statements();
95+
96+
assertEquals(2, parseStatements.getStatements().size());
97+
98+
assertTrue(parseStatements.getStatements().get(0) instanceof Select);
99+
assertNull(parseStatements.getStatements().get(1));
100+
101+
assertEquals(2,parser.getParseErrors().size());
102+
}
63103
}

0 commit comments

Comments
 (0)