mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved oracle pl/sql parser.
This commit is contained in:
@@ -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")) {
|
||||
|
||||
+5
-5
@@ -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";
|
||||
|
||||
+45
-8
@@ -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 {
|
||||
|
||||
+47
-16
@@ -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 ");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user