mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
增加oracle对execute immediate sql bulk Collect的支持,以及存储过程中使用 record(字段 类型)的解析支持
This commit is contained in:
+10
@@ -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);
|
||||
|
||||
+30
-2
@@ -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("@@"),
|
||||
|
||||
Reference in New Issue
Block a user