Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implement UnsupportedStatement
- Add Feature allowUnsupportedStatement, default=false
- Fully implement UnsupportedStatement for the Statement() production
- Partially implement UnsupportedStatement for the Statements() production, works only when UnsupportedStatement comes first
  • Loading branch information
manticore-projects committed Apr 24, 2022
commit d30613ad55d99467f7521a3a85ee69daa3bf09b8
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ public P withSquareBracketQuotation(boolean allowSquareBracketQuotation) {
public P withAllowComplexParsing(boolean allowComplexParsing) {
return withFeature(Feature.allowComplexParsing, allowComplexParsing);
}

public P withUnsupportedStatements(boolean allowUnsupportedStatements) {
return withFeature(Feature.allowUnsupportedStatements, allowUnsupportedStatements);
}

public P withFeature(Feature f, boolean enabled) {
getConfiguration().setValue(f, enabled);
return me();
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/net/sf/jsqlparser/parser/CCJSqlParserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -271,16 +271,31 @@ public Statement call() throws Exception {
* @return the statements parsed
*/
public static Statements parseStatements(String sqls) throws JSQLParserException {
return parseStatements(sqls, null);
}

/**
* Parse a statement list.
*
* @return the statements parsed
*/
public static Statements parseStatements(String sqls, Consumer<CCJSqlParser> consumer) throws JSQLParserException {
Statements statements = null;

// first, try to parse fast and simple
try {
CCJSqlParser parser = newParser(sqls).withAllowComplexParsing(false);
if (consumer != null) {
consumer.accept(parser);
}
statements = parseStatements(parser);
} catch (JSQLParserException ex) {
// when fast simple parsing fails, try complex parsing but only if it has a chance to succeed
if (getNestingDepth(sqls)<=ALLOWED_NESTING_DEPTH) {
CCJSqlParser parser = newParser(sqls).withAllowComplexParsing(true);
if (consumer != null) {
consumer.accept(parser);
}
statements = parseStatements(parser);
}
}
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/net/sf/jsqlparser/parser/feature/Feature.java
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,13 @@ public enum Feature {
* allows complex expression parameters or named parameters for functions
* will be switched off, when deep nesting of functions is detected
*/
allowComplexParsing(true)
allowComplexParsing(true),

/**
* allows passing through Unsupported Statements as a plain List of Tokens
* needs to be switched off, when VALIDATING statements or parsing blocks
*/
allowUnsupportedStatements(false),
;

private Object value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,6 @@ public interface StatementVisitor {
void visit(PurgeStatement purgeStatement);

void visit(AlterSystemStatement alterSystemStatement);

void visit(UnsupportedStatement unsupportedStatement);
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,9 @@ public void visit(PurgeStatement purgeStatement) {
@Override
public void visit(AlterSystemStatement alterSystemStatement) {
}

@Override
public void visit(UnsupportedStatement unsupportedStatement) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2021 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/

package net.sf.jsqlparser.statement;

import java.util.List;
import java.util.Objects;

/**
*
* @author <a href="mailto:andreas@manticore-projects.com">Andreas Reichel</a>
*/

public class UnsupportedStatement implements Statement {
private List<String> declarations;

public UnsupportedStatement(List<String> declarations) {
this.declarations = Objects.requireNonNull(declarations, "The List of Tokens must not be null.");
}

@Override
public void accept(StatementVisitor statementVisitor) {
statementVisitor.visit(this);
}

@SuppressWarnings({"PMD.MissingBreakInSwitch", "PMD.SwitchStmtsShouldHaveDefault", "PMD.CyclomaticComplexity"})
public StringBuilder appendTo(StringBuilder builder) {
int i=0;
for (String s:declarations) {
if (i>0) {
builder.append(" ");
}
builder.append(s);
i++;
}
return builder;
}

@Override
public String toString() {
return appendTo(new StringBuilder()).toString();
}

public boolean isEmpty() {
return declarations.isEmpty();
}
}
5 changes: 5 additions & 0 deletions src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,11 @@ public void visit(AlterSystemStatement alterSystemStatement) {
// no tables involved in this statement
}

@Override
public void visit(UnsupportedStatement unsupportedStatement) {
// no tables involved in this statement
}

@Override
public void visit(GeometryDistance geometryDistance) {
visitBinaryExpression(geometryDistance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.StatementVisitor;
import net.sf.jsqlparser.statement.Statements;
import net.sf.jsqlparser.statement.UnsupportedStatement;
import net.sf.jsqlparser.statement.UseStatement;
import net.sf.jsqlparser.statement.alter.Alter;
import net.sf.jsqlparser.statement.alter.AlterSession;
Expand Down Expand Up @@ -373,4 +374,9 @@ public void visit(PurgeStatement purgeStatement) {
public void visit(AlterSystemStatement alterSystemStatement) {
alterSystemStatement.appendTo(buffer);
}

@Override
public void visit(UnsupportedStatement unsupportedStatement) {
unsupportedStatement.appendTo(buffer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.StatementVisitor;
import net.sf.jsqlparser.statement.Statements;
import net.sf.jsqlparser.statement.UnsupportedStatement;
import net.sf.jsqlparser.statement.UseStatement;
import net.sf.jsqlparser.statement.alter.Alter;
import net.sf.jsqlparser.statement.alter.AlterSession;
Expand Down Expand Up @@ -303,4 +304,9 @@ public void visit(PurgeStatement purgeStatement) {
public void visit(AlterSystemStatement alterSystemStatement) {
//TODO: not yet implemented
}

@Override
public void visit(UnsupportedStatement unsupportedStatement) {

}
}
55 changes: 43 additions & 12 deletions src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ Statement Statement() #Statement:
stm = SingleStatement() { ifElseStatement = new IfElseStatement(condition, stm); }
[ <ST_SEMICOLON> { ifElseStatement.setUsingSemicolonForIfStatement(true); } ]
[ LOOKAHEAD(2)
<K_ELSE> stm2 = SingleStatement() { ifElseStatement.setElseStatement(stm2); }
<K_ELSE> stm2 = SingleStatement() { ifElseStatement.setElseStatement(stm2); }
[ <ST_SEMICOLON> { ifElseStatement.setUsingSemicolonForElseStatement(true); }]
]
<EOF>
Expand All @@ -519,6 +519,8 @@ Statement Statement() #Statement:
[ <ST_SEMICOLON> ]
<EOF>
)
|
LOOKAHEAD( { getAsBoolean(Feature.allowUnsupportedStatements) } ) stm = UnsupportedStatement()
} catch (ParseException e) {
if (errorRecovery) {
parseErrors.add(e);
Expand Down Expand Up @@ -707,33 +709,35 @@ Statements Statements() #Statements : {

[ LOOKAHEAD(2) <ST_SEMICOLON> ]
) { list.add(stm); }
|
LOOKAHEAD( { getAsBoolean(Feature.allowUnsupportedStatements) } ) stm = UnsupportedStatement()
{ if ( !((UnsupportedStatement) stm).isEmpty() ) list.add(stm); }
)


(
<ST_SEMICOLON> { if (stm2!=null)
ifElseStatement.setUsingSemicolonForElseStatement(true);
else if (ifElseStatement!=null)
ifElseStatement.setUsingSemicolonForIfStatement(true); }
(
<ST_SEMICOLON> { if (stm2!=null)
ifElseStatement.setUsingSemicolonForElseStatement(true);
else if (ifElseStatement!=null)
ifElseStatement.setUsingSemicolonForIfStatement(true); }
[
(
<K_IF> condition=Condition()
<K_IF> condition=Condition()
stm = SingleStatement() { ifElseStatement = new IfElseStatement(condition, stm); }
[ LOOKAHEAD(2)
[ LOOKAHEAD(2)
[ <ST_SEMICOLON> { ifElseStatement.setUsingSemicolonForIfStatement(true); } ]
<K_ELSE> stm2 = SingleStatement() { ifElseStatement.setElseStatement(stm2); }
<K_ELSE> stm2 = SingleStatement() { ifElseStatement.setElseStatement(stm2); }
]

{ list.add( ifElseStatement ); }
)
|
(
stm = SingleStatement()
stm = SingleStatement()
| stm = Block()

[ LOOKAHEAD(2) <ST_SEMICOLON> ]
) { list.add(stm); }
]
]
)*
<EOF>
} catch (ParseException e) {
Expand Down Expand Up @@ -6286,6 +6290,17 @@ Synonym Synonym() #Synonym :
}
}

UnsupportedStatement UnsupportedStatement():
{
List<String> tokens = new LinkedList<String>();
}
{
tokens=captureUnsupportedStatementDeclaration()
{
return new UnsupportedStatement(tokens);
}
}

JAVACODE
List<String> captureRest() {
List<String> tokens = new LinkedList<String>();
Expand All @@ -6300,3 +6315,19 @@ List<String> captureRest() {
}
return tokens;
}

JAVACODE
List<String> captureUnsupportedStatementDeclaration() {
List<String> tokens = new LinkedList<String>();
Token tok;

while(true) {
tok = getToken(1);
if(tok.kind == EOF || tok.kind== ST_SEMICOLON) {
break;
}
tokens.add(tok.image);
tok = getNextToken();
}
return tokens;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package net.sf.jsqlparser.statement;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.select.Select;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;

import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;

public class UnsupportedStatementTest {
@Test
public void testSingleUnsupportedStatement() throws JSQLParserException {
String sqlStr = "this is an unsupported statement";

assertSqlCanBeParsedAndDeparsed(sqlStr, true, parser -> parser.withUnsupportedStatements(true) );

Assertions.assertThrowsExactly(JSQLParserException.class, new Executable() {
@Override
public void execute() throws Throwable {
CCJSqlParserUtil.parse(sqlStr, parser -> parser.withUnsupportedStatements(false) );
}
});
}

@Test
public void testUnsupportedStatementsFirstInBlock() throws JSQLParserException {
String sqlStr = "This is an unsupported statement; Select * from dual; Select * from dual;";

Statements statements = CCJSqlParserUtil.parseStatements(sqlStr, parser -> parser.withUnsupportedStatements(true));
Assertions.assertEquals(3, statements.getStatements().size());
Assertions.assertInstanceOf(UnsupportedStatement.class, statements.getStatements().get(0));
Assertions.assertInstanceOf(Select.class, statements.getStatements().get(1));
Assertions.assertInstanceOf(Select.class, statements.getStatements().get(2));

Assertions.assertThrowsExactly(JSQLParserException.class, new Executable() {
@Override
public void execute() throws Throwable {
CCJSqlParserUtil.parseStatements(sqlStr, parser -> parser.withUnsupportedStatements(false) );
}
});
}

@Test
@Disabled
public void testUnsupportedStatementsMiddleInBlock() throws JSQLParserException {
String sqlStr = "Select * from dual; This is an unsupported statement; Select * from dual;";

Statements statements = CCJSqlParserUtil.parseStatements(sqlStr, parser -> parser.withUnsupportedStatements(true));
Assertions.assertEquals(3, statements.getStatements().size());

Assertions.assertInstanceOf(Select.class, statements.getStatements().get(0));
Assertions.assertInstanceOf(UnsupportedStatement.class, statements.getStatements().get(1));
Assertions.assertInstanceOf(Select.class, statements.getStatements().get(2));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ public void testCreateTableUniqueConstraint() throws JSQLParserException {
CreateTable createTable
= (CreateTable) CCJSqlParserUtil.parseStatements(sqlStr).getStatements().get(0);

System.out.println(createTable.toString());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ select time_id, product



--@FAILURE: Encountered unexpected token: "(" "(" recorded first on Aug 3, 2021, 7:20:07 AM
--@FAILURE: Encountered unexpected token: "(" "(" recorded first on Aug 3, 2021, 7:20:07 AM
--@FAILURE: select time_id,product,last_value(quantity ignore nulls)over(partition by product order by time_id)quantity,last_value recorded first on 23 Apr 2022, 16:44:21
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ select times.time_id, product, quantity from inventory



--@FAILURE: Encountered unexpected token: "by" "BY" recorded first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: Encountered unexpected token: "by" "BY" recorded first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: select times.time_id,product,quantity from inventory partition recorded first on 23 Apr 2022, 16:44:21
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@
update customers_demo
set cust_address_ntab = cust_address_ntab multiset union cust_address_ntab

--@FAILURE: Encountered unexpected token: "multiset" <S_IDENTIFIER> recorded first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: Encountered unexpected token: "multiset" <S_IDENTIFIER> recorded first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: update customers_demo set cust_address_ntab=cust_address_ntab recorded first on 23 Apr 2022, 16:44:21
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ select customer_id, cust_address_ntab
multiset except distinct cust_address2_ntab multiset_except
from customers_demo

--@FAILURE: Encountered unexpected token: "except" "EXCEPT" recorded first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: Encountered unexpected token: "except" "EXCEPT" recorded first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: select customer_id,cust_address_ntab multiset recorded first on 23 Apr 2022, 16:44:21
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ multiset intersect all cust_address2_ntab multiset_intersect
from customers_demo
order by customer_id

--@FAILURE: Encountered unexpected token: "intersect" "INTERSECT" recorded first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: Encountered unexpected token: "intersect" "INTERSECT" recorded first on Aug 3, 2021, 7:20:08 AM
--@FAILURE: select customer_id,cust_address_ntab multiset recorded first on 23 Apr 2022, 16:44:21
Loading