增加oracle对execute immediate sql bulk Collect的支持,以及存储过程中使用 record(字段 类型)的解析支持

This commit is contained in:
fanglei
2020-11-03 12:32:30 +08:00
parent 48af6f39ef
commit 563f158903
6 changed files with 153 additions and 104 deletions
@@ -26,6 +26,8 @@ import java.util.List;
public class OracleExecuteImmediateStatement extends OracleStatementImpl {
private SQLExpr dynamicSql;
private boolean bulkCollect;
private final List<SQLArgument> arguments = new ArrayList<SQLArgument>();
@@ -86,6 +88,14 @@ public class OracleExecuteImmediateStatement extends OracleStatementImpl {
}
this.dynamicSql = dynamicSql;
}
public boolean isBulkCollect() {
return bulkCollect;
}
public void setBulkCollect(boolean bulkCollect) {
this.bulkCollect = bulkCollect;
}
public void setDynamicSql(String dynamicSql) {
this.setDynamicSql(new SQLCharExpr(dynamicSql));
@@ -49,7 +49,8 @@ public class OracleLexer extends Lexer {
map.put("GOTO", Token.GOTO);
map.put("IF", Token.IF);
map.put("ELSIF", Token.ELSIF);
map.put("RECORD", Token.RECORD);
map.put("LIMIT", Token.LIMIT);
map.put("LOOP", Token.LOOP);
map.put("MATCHED", Token.MATCHED);
@@ -788,7 +788,11 @@ public class OracleStatementParser extends SQLStatementParser {
SQLExpr dyanmiacSql = this.exprParser.primary();
stmt.setDynamicSql(dyanmiacSql);
if (lexer.identifierEquals("BULK")) {
lexer.nextToken();
acceptIdentifier("COLLECT");
stmt.setBulkCollect(true);
}
if (lexer.token() == Token.INTO) {
lexer.nextToken();
@@ -1979,6 +1983,18 @@ public class OracleStatementParser extends SQLStatementParser {
} else {
throw new ParserException("TODO : " + lexer.info());
}
} else if (lexer.token() == Token.RECORD) {
lexer.nextToken();
String typeName = "RECORD";
SQLRecordDataType sqlRecordDataType = new SQLRecordDataType();
sqlRecordDataType.setDbType(dbType);
sqlRecordDataType.setName(typeName);
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
this.parseColumnsList(sqlRecordDataType.getColumns(), sqlRecordDataType);
accept(Token.RPAREN);
}
dataType = sqlRecordDataType;
} else {
throw new ParserException("TODO : " + lexer.info());
}
@@ -2104,7 +2120,19 @@ public class OracleStatementParser extends SQLStatementParser {
break;
}
}
private void parseColumnsList(List<SQLColumnDefinition> columns, SQLObject parent) {
for ( ; ; ) {
SQLColumnDefinition columnDefinition = this.exprParser.parseColumn();
columns.add(columnDefinition);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
}
public OracleSelectParser createSQLSelectParser() {
return new OracleSelectParser(this.exprParser, selectListCache);
}
@@ -2612,7 +2612,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public boolean visit(OracleExecuteImmediateStatement x) {
print0(ucase ? "EXECUTE IMMEDIATE " : "execute immediate ");
x.getDynamicSql().accept(this);
if (x.isBulkCollect()) {
print0(ucase ? " BULK COLLECT " : " bulk collect ");
}
List<SQLExpr> into = x.getInto();
if (into.size() > 0) {
print0(ucase ? " INTO " : " into ");
@@ -531,6 +531,11 @@ public class SQLExprParser extends SQLParser {
break;
}
}
} else if (DbType.oracle == dbType) {
lexer.nextTokenValue();
if (lexer.token == Token.BARBAR) {
sqlExpr = additiveRest(sqlExpr);
}
} else {
lexer.nextToken();
}
@@ -1307,7 +1312,7 @@ public class SQLExprParser extends SQLParser {
expr = dotRest(expr);
return primaryRest(expr);
} else if (lexer.identifierEquals(FnvHash.Constants.SETS) //
&& expr.getClass() == SQLIdentifierExpr.class //
&& expr.getClass() == SQLIdentifierExpr.class //
&& "GROUPING".equalsIgnoreCase(((SQLIdentifierExpr) expr).getName())) {
SQLGroupingSetExpr groupingSets = new SQLGroupingSetExpr();
lexer.nextToken();
@@ -16,56 +16,56 @@
package com.alibaba.druid.sql.parser;
/**
*
* SQL Token
*
* SQL Token
* @author wenshao [szujobs@hotmail.com]
*/
public enum Token {
SELECT("SELECT"),
DELETE("DELETE"),
INSERT("INSERT"),
UPDATE("UPDATE"),
SELECT("SELECT"),
DELETE("DELETE"),
INSERT("INSERT"),
UPDATE("UPDATE"),
FROM("FROM"),
HAVING("HAVING"),
WHERE("WHERE"),
ORDER("ORDER"),
FROM("FROM"),
HAVING("HAVING"),
WHERE("WHERE"),
ORDER("ORDER"),
BY("BY"),
GROUP("GROUP"),
INTO("INTO"),
AS("AS"),
GROUP("GROUP"),
INTO("INTO"),
AS("AS"),
CREATE("CREATE"),
ALTER("ALTER"),
DROP("DROP"),
SET("SET"),
ALTER("ALTER"),
DROP("DROP"),
SET("SET"),
NULL("NULL"),
NOT("NOT"),
NULL("NULL"),
NOT("NOT"),
DISTINCT("DISTINCT"),
TABLE("TABLE"),
TABLESPACE("TABLESPACE"),
VIEW("VIEW"),
SEQUENCE("SEQUENCE"),
TRIGGER("TRIGGER"),
USER("USER"),
INDEX("INDEX"),
TABLE("TABLE"),
TABLESPACE("TABLESPACE"),
VIEW("VIEW"),
SEQUENCE("SEQUENCE"),
TRIGGER("TRIGGER"),
USER("USER"),
INDEX("INDEX"),
SESSION("SESSION"),
PROCEDURE("PROCEDURE"),
FUNCTION("FUNCTION"),
PRIMARY("PRIMARY"),
KEY("KEY"),
DEFAULT("DEFAULT"),
CONSTRAINT("CONSTRAINT"),
CHECK("CHECK"),
UNIQUE("UNIQUE"),
FOREIGN("FOREIGN"),
REFERENCES("REFERENCES"),
PRIMARY("PRIMARY"),
KEY("KEY"),
DEFAULT("DEFAULT"),
CONSTRAINT("CONSTRAINT"),
CHECK("CHECK"),
UNIQUE("UNIQUE"),
FOREIGN("FOREIGN"),
REFERENCES("REFERENCES"),
EXPLAIN("EXPLAIN"),
FOR("FOR"),
EXPLAIN("EXPLAIN"),
FOR("FOR"),
IF("IF"),
@@ -73,55 +73,55 @@ public enum Token {
GLOBAL("GLOBAL"),
ALL("ALL"),
UNION("UNION"),
EXCEPT("EXCEPT"),
INTERSECT("INTERSECT"),
EXCEPT("EXCEPT"),
INTERSECT("INTERSECT"),
MINUS("MINUS"),
INNER("INNER"),
LEFT("LEFT"),
RIGHT("RIGHT"),
FULL("FULL"),
OUTER("OUTER"),
INNER("INNER"),
LEFT("LEFT"),
RIGHT("RIGHT"),
FULL("FULL"),
OUTER("OUTER"),
JOIN("JOIN"),
STRAIGHT_JOIN("STRAIGHT_JOIN"),
ON("ON"),
SCHEMA("SCHEMA"),
SCHEMA("SCHEMA"),
CAST("CAST"),
COLUMN("COLUMN"),
USE("USE"),
DATABASE("DATABASE"),
TO("TO"),
AND("AND"),
OR("OR"),
XOR("XOR"),
CASE("CASE"),
WHEN("WHEN"),
THEN("THEN"),
AND("AND"),
OR("OR"),
XOR("XOR"),
CASE("CASE"),
WHEN("WHEN"),
THEN("THEN"),
ELSE("ELSE"),
ELSIF("ELSIF"),
END("END"),
EXISTS("EXISTS"),
END("END"),
EXISTS("EXISTS"),
IN("IN"),
NEW("NEW"),
ASC("ASC"),
DESC("DESC"),
IS("IS"),
LIKE("LIKE"),
ESCAPE("ESCAPE"),
BETWEEN("BETWEEN"),
VALUES("VALUES"),
NEW("NEW"),
ASC("ASC"),
DESC("DESC"),
IS("IS"),
LIKE("LIKE"),
ESCAPE("ESCAPE"),
BETWEEN("BETWEEN"),
VALUES("VALUES"),
INTERVAL("INTERVAL"),
LOCK("LOCK"),
SOME("SOME"),
LOCK("LOCK"),
SOME("SOME"),
ANY("ANY"),
TRUNCATE("TRUNCATE"),
RETURN("RETURN"),
// mysql
TRUE("TRUE"),
TRUE("TRUE"),
FALSE("FALSE"),
LIMIT("LIMIT"),
KILL("KILL"),
@@ -211,6 +211,7 @@ public enum Token {
COMMIT("COMMIT"),
SAVEPOINT("SAVEPOINT"),
CROSS("CROSS"),
RECORD("RECORD"),
PCTFREE("PCTFREE"),
INITRANS("INITRANS"),
@@ -253,7 +254,7 @@ public enum Token {
// hive
EOF,
EOF,
ERROR,
IDENTIFIER,
HINT,
@@ -298,19 +299,19 @@ public enum Token {
UPSERT("UPSERT"), // Phoenix
LPAREN("("),
RPAREN(")"),
LBRACE("{"),
RBRACE("}"),
LBRACKET("["),
RBRACKET("]"),
SEMI(";"),
COMMA(","),
DOT("."),
DOTDOT(".."),
DOTDOTDOT("..,"),
EQ("="),
GT(">"),
LPAREN("("),
RPAREN(")"),
LBRACE("{"),
RBRACE("}"),
LBRACKET("["),
RBRACKET("]"),
SEMI(";"),
COMMA(","),
DOT("."),
DOTDOT(".."),
DOTDOTDOT("..,"),
EQ("="),
GT(">"),
LT("<"),
LT_SUB_GT("<->"),
BANG("!"),
@@ -324,34 +325,34 @@ public enum Token {
QUESQUES("??"),
QUESBAR("?|"),
QUESAMP("?&"),
COLON(":"),
COLONCOLON("::"),
COLONEQ(":="),
COLON(":"),
COLONCOLON("::"),
COLONEQ(":="),
EQEQ("=="),
EQGT("=>"),
LTEQ("<="),
LTEQGT("<=>"),
LTGT("<>"),
GTEQ(">="),
BANGEQ("!="),
BANGGT("!>"),
LTEQ("<="),
LTEQGT("<=>"),
LTGT("<>"),
GTEQ(">="),
BANGEQ("!="),
BANGGT("!>"),
BANGLT("!<"),
AMPAMP("&&"),
BARBAR("||"),
BARBARSLASH("||/"),
BARSLASH("|/"),
PLUS("+"),
SUB("-"),
SUBGT("->"),
SUBGTGT("->>"),
STAR("*"),
SLASH("/"),
AMP("&"),
BAR("|"),
AMPAMP("&&"),
BARBAR("||"),
BARBARSLASH("||/"),
BARSLASH("|/"),
PLUS("+"),
SUB("-"),
SUBGT("->"),
SUBGTGT("->>"),
STAR("*"),
SLASH("/"),
AMP("&"),
BAR("|"),
CARET("^"),
CARETEQ("^="),
PERCENT("%"),
LTLT("<<"),
PERCENT("%"),
LTLT("<<"),
GTGT(">>"),
MONKEYS_AT("@"),
MONKEYS_AT_AT("@@"),