improved oracle pl/sql parser.

This commit is contained in:
wenshao
2017-05-13 19:19:34 +08:00
parent a5e4bdd645
commit 06064b76b6
21 changed files with 1258 additions and 48 deletions
@@ -24,6 +24,7 @@ public class SQLParameter extends SQLObjectImpl {
private SQLExpr defaultValue;
private ParameterType paramType;
private boolean noCopy = false;
private boolean constant = false;
public SQLExpr getDefaultValue() {
return defaultValue;
@@ -81,4 +82,12 @@ public class SQLParameter extends SQLObjectImpl {
public void setNoCopy(boolean noCopy) {
this.noCopy = noCopy;
}
public boolean isConstant() {
return constant;
}
public void setConstant(boolean constant) {
this.constant = constant;
}
}
@@ -46,11 +46,14 @@ public class SQLBlockStatement extends SQLStatementImpl {
this.labelName = labelName;
}
public SQLStatement exception;
@Override
public void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, parameters);
acceptChild(visitor, statementList);
acceptChild(visitor, exception);
}
visitor.endVisit(this);
}
@@ -63,4 +66,11 @@ public class SQLBlockStatement extends SQLStatementImpl {
this.parameters = parameters;
}
public SQLStatement getException() {
return exception;
}
public void setException(SQLStatement exception) {
this.exception = exception;
}
}
@@ -37,6 +37,8 @@ public class SQLCreateProcedureStatement extends SQLStatementImpl {
// for oracle
private String javaCallSpec;
private SQLName authid;
@Override
public void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
@@ -75,6 +77,17 @@ public class SQLCreateProcedureStatement extends SQLStatementImpl {
this.block = block;
}
public SQLName getAuthid() {
return authid;
}
public void setAuthid(SQLName authid) {
if (authid != null) {
authid.setParent(this);
}
this.authid = authid;
}
public boolean isOrReplace() {
return orReplace;
}
@@ -3194,6 +3194,7 @@ public class MySqlStatementParser extends SQLStatementParser {
* CREATE OR REPALCE PROCEDURE SP_NAME(parameter_list) BEGIN block_statement END
*/
SQLCreateProcedureStatement stmt = new SQLCreateProcedureStatement();
stmt.setDbType(dbType);
if (lexer.token() != Token.PROCEDURE) {
if (identifierEquals("DEFINER")) {
@@ -42,7 +42,7 @@ public class OracleExceptionStatement extends OracleStatementImpl implements Ora
public static class Item extends OracleSQLObjectImpl {
private SQLExpr when;
private SQLStatement statement;
private List<SQLStatement> statements = new ArrayList<SQLStatement>();
public SQLExpr getWhen() {
return when;
@@ -52,22 +52,22 @@ public class OracleExceptionStatement extends OracleStatementImpl implements Ora
this.when = when;
}
public SQLStatement getStatement() {
return statement;
public List<SQLStatement> getStatements() {
return statements;
}
public void setStatement(SQLStatement statement) {
if (statement != null) {
statement.setParent(this);
this.statements.add(statement);
}
this.statement = statement;
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, when);
acceptChild(visitor, statement);
acceptChild(visitor, statements);
}
visitor.endVisit(this);
}
@@ -158,30 +158,30 @@ public class OracleExprParser extends SQLExprParser {
}
public SQLDataType parseDataType() {
if (lexer.token() == Token.CONSTRAINT || lexer.token() == Token.COMMA) {
return null;
}
if (lexer.token() == Token.DEFAULT || lexer.token() == Token.NOT || lexer.token() == Token.NULL) {
return null;
}
if (lexer.token() == Token.INTERVAL) {
lexer.nextToken();
if (identifierEquals("YEAR")) {
lexer.nextToken();
OracleDataTypeIntervalYear interval = new OracleDataTypeIntervalYear();
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
interval.addArgument(this.expr());
accept(Token.RPAREN);
}
accept(Token.TO);
acceptIdentifier("MONTH");
return interval;
} else {
acceptIdentifier("DAY");
@@ -191,22 +191,25 @@ public class OracleExprParser extends SQLExprParser {
interval.addArgument(this.expr());
accept(Token.RPAREN);
}
accept(Token.TO);
acceptIdentifier("SECOND");
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
interval.getFractionalSeconds().add(this.expr());
accept(Token.RPAREN);
}
return interval;
}
}
String typeName;
if (identifierEquals("LONG")) {
if (lexer.token() == Token.EXCEPTION) {
typeName = "EXCEPTION";
lexer.nextToken();
} else if (identifierEquals("LONG")) {
lexer.nextToken();
acceptIdentifier("RAW");
typeName = "LONG RAW";
@@ -62,7 +62,7 @@ public class OracleStatementParser extends SQLStatementParser {
}
}
public void parseStatementList(List<SQLStatement> statementList, int max, SQLStatement parent) {
public void parseStatementList(List<SQLStatement> statementList, int max, SQLObject parent) {
for (;;) {
if (max != -1) {
if (statementList.size() >= max) {
@@ -176,7 +176,12 @@ public class OracleStatementParser extends SQLStatementParser {
}
if (lexer.token() == Token.EXCEPTION) {
statementList.add(this.parseException());
OracleExceptionStatement stmt = this.parseException();
if (parent instanceof SQLBlockStatement) {
((SQLBlockStatement) parent).setException(stmt);
} else {
statementList.add(stmt);
}
continue;
}
@@ -215,13 +220,15 @@ public class OracleStatementParser extends SQLStatementParser {
if (identifierEquals("ROLLBACK")) {
SQLRollbackStatement stmt = parseRollback();
stmt.setParent(parent);
statementList.add(stmt);
continue;
}
if (lexer.token() == Token.EXPLAIN) {
statementList.add(this.parseExplain());
OracleExplainStatement stmt = this.parseExplain();
stmt.setParent(parent);
statementList.add(stmt);
continue;
}
@@ -240,6 +247,7 @@ public class OracleStatementParser extends SQLStatementParser {
SQLExpr expr = exprParser.expr();
OracleExprStatement stmt = new OracleExprStatement(expr);
stmt.setParent(parent);
statementList.add(stmt);
continue;
}
@@ -477,7 +485,13 @@ public class OracleStatementParser extends SQLStatementParser {
continue;
}
if (lexer.token() == Token.ELSIF && parent instanceof SQLIfStatement) {
if (lexer.token() == Token.ELSIF
&& parent instanceof SQLIfStatement) {
break;
}
if (lexer.token() == Token.WHEN
&& parent instanceof OracleExceptionStatement.Item) {
break;
}
@@ -1111,6 +1125,7 @@ public class OracleStatementParser extends SQLStatementParser {
public SQLBlockStatement parseBlock() {
SQLBlockStatement block = new SQLBlockStatement();
block.setDbType(JdbcConstants.ORACLE);
if (lexer.token() == Token.DECLARE) {
lexer.nextToken();
@@ -1125,7 +1140,7 @@ public class OracleStatementParser extends SQLStatementParser {
accept(Token.BEGIN);
parseStatementList(block.getStatementList());
parseStatementList(block.getStatementList(), -1, block);
accept(Token.END);
@@ -1214,6 +1229,11 @@ public class OracleStatementParser extends SQLStatementParser {
parameter.setNoCopy(true);
}
if (identifierEquals("CONSTANT")) {
lexer.nextToken();
parameter.setConstant(true);
}
dataType = this.exprParser.parseDataType();
if (lexer.token() == Token.COLONEQ) {
@@ -1340,11 +1360,15 @@ public class OracleStatementParser extends SQLStatementParser {
OracleExceptionStatement.Item item = new OracleExceptionStatement.Item();
item.setWhen(this.exprParser.expr());
accept(Token.THEN);
SQLStatement thenStmt = this.parseStatement();
item.setStatement(thenStmt);
this.parseStatementList(item.getStatements(), -1, item);
stmt.addItem(item);
if (lexer.token() == Token.SEMI) {
lexer.nextToken();
}
if (lexer.token() != Token.WHEN) {
break;
}
@@ -1671,6 +1695,7 @@ public class OracleStatementParser extends SQLStatementParser {
public SQLCreateProcedureStatement parseCreateProcedure() {
SQLCreateProcedureStatement stmt = new SQLCreateProcedureStatement();
stmt.setDbType(dbType);
if (lexer.token() == Token.CREATE) {
lexer.nextToken();
@@ -1694,6 +1719,18 @@ public class OracleStatementParser extends SQLStatementParser {
accept(Token.RPAREN);
}
if (identifierEquals("AUTHID")) {
lexer.nextToken();
String strVal = lexer.stringVal();
if (identifierEquals("CURRENT_USER")) {
lexer.nextToken();
} else {
acceptIdentifier("DEFINER");
}
SQLName authid = new SQLIdentifierExpr(strVal);
stmt.setAuthid(authid);
}
if (lexer.token() == Token.IS) {
lexer.nextToken();
} else {
@@ -104,30 +104,29 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
return;
}
SQLObject parent = x.getParent();
if ((!isPrintPostSemi()) //
&& (!(x.getParent() instanceof SQLBlockStatement))) {
&& (!(parent instanceof SQLBlockStatement))
&& (!(parent instanceof OracleForStatement))) {
return;
}
if (x instanceof OraclePLSQLCommitStatement
|| x instanceof OracleLabelStatement
|| x instanceof OracleExceptionStatement.Item) {
|| x instanceof OracleExceptionStatement.Item
|| x instanceof OracleExceptionStatement) {
return;
}
SQLObject parent = x.getParent();
if (parent instanceof SQLCreateProcedureStatement) {
if (parent instanceof SQLCreateProcedureStatement
|| parent instanceof OracleExceptionStatement.Item
|| parent instanceof OracleForStatement) {
return;
}
if (isPrettyFormat()) {
if (parent instanceof OracleForStatement) {
OracleForStatement forStatement = (OracleForStatement) parent;
if (forStatement.isAll()) {
return;
}
}
if (parent != null) {
print(';');
} else {
@@ -1367,6 +1366,9 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public boolean visit(SQLBlockStatement x) {
if (x.getParameters().size() != 0) {
incrementIndent();
if (x.getParent() instanceof SQLCreateProcedureStatement) {
printIndent();
}
if (!(x.getParent() instanceof SQLCreateProcedureStatement)) {
print0(ucase ? "DECLARE" : "declare");
println();
@@ -1396,6 +1398,13 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
stmt.accept(this);
}
decrementIndent();
SQLStatement exception = x.getException();
if (exception != null) {
println();
exception.accept(this);
}
println();
print0(ucase ? "END" : "end");
return false;
@@ -1497,9 +1506,23 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public boolean visit(com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExceptionStatement.Item x) {
print0(ucase ? "WHEN " : "when ");
x.getWhen().accept(this);
print0(ucase ? " THEN " : " then ");
print0(ucase ? " THEN" : " then");
incrementIndent();
x.getStatement().accept(this);
if (x.getStatements().size() > 1) {
println();
} else {
print(' ');
}
for (int i = 0, size = x.getStatements().size(); i < size; ++i) {
if (i != 0 && size > 1) {
println();
}
SQLStatement stmt = x.getStatements().get(i);
stmt.accept(this);
print(";");
}
decrementIndent();
return false;
@@ -1509,8 +1532,10 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public boolean visit(OracleExceptionStatement x) {
print0(ucase ? "EXCEPTION" : "exception");
incrementIndent();
for (OracleExceptionStatement.Item item : x.getItems()) {
List<OracleExceptionStatement.Item> items = x.getItems();
for (int i = 0, size = items.size(); i < size; ++i) {
println();
OracleExceptionStatement.Item item = items.get(i);
item.accept(this);
}
decrementIndent();
@@ -2590,6 +2615,12 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
print(')');
}
SQLName authid = x.getAuthid();
if (authid != null) {
print(ucase ? " AUTHID " : " authid ");
authid.accept(this);
}
SQLStatement block = x.getBlock();
if (!create) {
@@ -2599,8 +2630,8 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
println();
if (block instanceof SQLBlockStatement) {
SQLBlockStatement blockStatement = (SQLBlockStatement) block;
if (blockStatement.getParameters().size() > 0) {
println("AS");
if (blockStatement.getParameters().size() > 0 || authid != null) {
println(ucase ? "AS" : "as");
}
}
}
@@ -84,7 +84,7 @@ public class SQLStatementParser extends SQLParser {
parseStatementList(statementList, max, null);
}
public void parseStatementList(List<SQLStatement> statementList, int max, SQLStatement parent) {
public void parseStatementList(List<SQLStatement> statementList, int max, SQLObject parent) {
for (;;) {
if (max != -1) {
if (statementList.size() >= max) {
@@ -3390,6 +3390,10 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
print0(ucase ? "NOCOPY " : "nocopy ");
}
if (x.isConstant()) {
print0(ucase ? "CONSTANT " : "constant ");
}
if (printType) {
print0(ucase ? "IS " : "is ");
}