improved oracle pl/sql parser.

This commit is contained in:
wenshao
2017-05-12 14:31:42 +08:00
parent 7cd62c0eb7
commit b70bbb2add
5 changed files with 184 additions and 6 deletions
@@ -27,6 +27,8 @@ public class SQLFetchStatement extends SQLStatementImpl {
private SQLName cursorName;
private boolean bulkCollect;
private List<SQLExpr> into = new ArrayList<SQLExpr>();
@Override
@@ -54,4 +56,11 @@ public class SQLFetchStatement extends SQLStatementImpl {
this.into = into;
}
public boolean isBulkCollect() {
return bulkCollect;
}
public void setBulkCollect(boolean bulkCollect) {
this.bulkCollect = bulkCollect;
}
}
@@ -1085,23 +1085,50 @@ public class OracleStatementParser extends SQLStatementParser {
for (;;) {
SQLParameter parameter = new SQLParameter();
SQLName name;
SQLDataType dataType;
if (lexer.token() == Token.CURSOR) {
lexer.nextToken();
parameter.setName(this.exprParser.name());
name = this.exprParser.name();
accept(Token.IS);
SQLSelect select = this.createSQLSelectParser().select();
SQLDataTypeImpl dataType = new SQLDataTypeImpl();
dataType = new SQLDataTypeImpl();
dataType.setName("CURSOR");
parameter.setDataType(dataType);
parameter.setDefaultValue(new SQLQueryExpr(select));
} else if (lexer.token() == Token.PROCEDURE) {
break;
} else if (identifierEquals("TYPE")) {
lexer.nextToken();
name = this.exprParser.name();
accept(Token.IS);
if (identifierEquals("REF")) {
lexer.nextToken();
accept(Token.CURSOR);
dataType = new SQLDataTypeImpl("REF CURSOR");
} else if (lexer.token() == Token.TABLE) {
lexer.nextToken();
accept(Token.OF);
name = this.exprParser.name();
if (lexer.token() == Token.PERCENT) {
lexer.nextToken();
acceptIdentifier("TYPE");
}
String typeName = name.toString() + "%TYPE";
dataType = new SQLDataTypeImpl(typeName);
} else {
throw new ParserException("TODO : " + lexer.info());
}
} else {
parameter.setName(this.exprParser.name());
name = this.exprParser.name();
if (lexer.token() == Token.IN) {
lexer.nextToken();
@@ -1122,7 +1149,7 @@ public class OracleStatementParser extends SQLStatementParser {
parameter.setNoCopy(true);
}
parameter.setDataType(this.exprParser.parseDataType());
dataType = this.exprParser.parseDataType();
if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
@@ -1130,6 +1157,9 @@ public class OracleStatementParser extends SQLStatementParser {
}
}
parameter.setName(name);
parameter.setDataType(dataType);
parameters.add(parameter);
if (lexer.token() == Token.COMMA || lexer.token() == Token.SEMI) {
lexer.nextToken();
@@ -2211,6 +2211,13 @@ public class SQLStatementParser extends SQLParser {
SQLFetchStatement stmt = new SQLFetchStatement();
stmt.setCursorName(this.exprParser.name());
if (identifierEquals("BULK")) {
lexer.nextToken();
acceptIdentifier("COLLECT");
stmt.setBulkCollect(true);
}
accept(Token.INTO);
for (;;) {
stmt.getInto().add(this.exprParser.name());
@@ -3216,7 +3216,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
public boolean visit(SQLFetchStatement x) {
print0(ucase ? "FETCH " : "fetch ");
x.getCursorName().accept(this);
print0(ucase ? " INTO " : " into ");
if (x.isBulkCollect()) {
print0(ucase ? " BULK COLLECT INTO " : " bulk collect into ");
} else {
print0(ucase ? " INTO " : " into ");
}
printAndAccept(x.getInto(), ", ");
return false;
}