mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser.
This commit is contained in:
@@ -425,7 +425,7 @@ public class SQLUtils {
|
||||
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType);
|
||||
List<SQLStatement> stmtList = parser.parseStatementList();
|
||||
if (parser.getLexer().token() != Token.EOF) {
|
||||
throw new DruidRuntimeException("syntax error : " + sql);
|
||||
throw new ParserException("syntax error : " + sql);
|
||||
}
|
||||
return stmtList;
|
||||
}
|
||||
@@ -434,7 +434,7 @@ public class SQLUtils {
|
||||
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType, keepComments);
|
||||
List<SQLStatement> stmtList = parser.parseStatementList();
|
||||
if (parser.getLexer().token() != Token.EOF) {
|
||||
throw new DruidRuntimeException("syntax error : " + sql);
|
||||
throw new ParserException("syntax error : " + sql);
|
||||
}
|
||||
return stmtList;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,21 @@ public class SQLDeclareItem extends SQLObjectImpl {
|
||||
|
||||
protected List<SQLTableElement> tableElementList = new ArrayList<SQLTableElement>();
|
||||
|
||||
public SQLDeclareItem() {
|
||||
|
||||
}
|
||||
|
||||
public SQLDeclareItem(SQLExpr name, SQLDataType dataType) {
|
||||
this.setName(name);
|
||||
this.setDataType(dataType);
|
||||
}
|
||||
|
||||
public SQLDeclareItem(SQLExpr name, SQLDataType dataType, SQLExpr value) {
|
||||
this.setName(name);
|
||||
this.setDataType(dataType);
|
||||
this.setValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
@@ -49,6 +64,9 @@ public class SQLDeclareItem extends SQLObjectImpl {
|
||||
}
|
||||
|
||||
public void setName(SQLExpr name) {
|
||||
if (name != null) {
|
||||
name.setParent(this);
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -57,6 +75,9 @@ public class SQLDeclareItem extends SQLObjectImpl {
|
||||
}
|
||||
|
||||
public void setDataType(SQLDataType dataType) {
|
||||
if (dataType != null) {
|
||||
dataType.setParent(this);
|
||||
}
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
@@ -65,6 +86,9 @@ public class SQLDeclareItem extends SQLObjectImpl {
|
||||
}
|
||||
|
||||
public void setValue(SQLExpr value) {
|
||||
if (value != null) {
|
||||
value.setParent(this);
|
||||
}
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@ public class SQLParameter extends SQLObjectImpl {
|
||||
}
|
||||
|
||||
public void setDefaultValue(SQLExpr deaultValue) {
|
||||
if (deaultValue != null) {
|
||||
deaultValue.setParent(this);
|
||||
}
|
||||
this.defaultValue = deaultValue;
|
||||
}
|
||||
|
||||
@@ -45,6 +48,9 @@ public class SQLParameter extends SQLObjectImpl {
|
||||
}
|
||||
|
||||
public void setName(SQLExpr name) {
|
||||
if (name != null) {
|
||||
name.setParent(this);
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,12 @@ public class SQLCreateFunctionStatement extends SQLStatementImpl {
|
||||
|
||||
SQLDataType returnDataType;
|
||||
|
||||
// for mysql
|
||||
|
||||
private String comment;
|
||||
|
||||
private boolean deterministic = false;
|
||||
|
||||
@Override
|
||||
public void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
@@ -131,4 +137,20 @@ public class SQLCreateFunctionStatement extends SQLStatementImpl {
|
||||
}
|
||||
this.returnDataType = returnDataType;
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public boolean isDeterministic() {
|
||||
return deterministic;
|
||||
}
|
||||
|
||||
public void setDeterministic(boolean deterministic) {
|
||||
this.deterministic = deterministic;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,7 @@ package com.alibaba.druid.sql.ast.statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDeclareItem;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerObjectImpl;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerStatement;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor;
|
||||
@@ -30,7 +28,17 @@ public class SQLDeclareStatement extends SQLStatementImpl {
|
||||
|
||||
protected List<SQLDeclareItem> items = new ArrayList<SQLDeclareItem>();
|
||||
|
||||
private String dbType;
|
||||
public SQLDeclareStatement() {
|
||||
|
||||
}
|
||||
|
||||
public SQLDeclareStatement(SQLExpr name, SQLDataType dataType) {
|
||||
this.addItem(new SQLDeclareItem(name, dataType));
|
||||
}
|
||||
|
||||
public SQLDeclareStatement(SQLExpr name, SQLDataType dataType, SQLExpr value) {
|
||||
this.addItem(new SQLDeclareItem(name, dataType, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(SQLASTVisitor visitor) {
|
||||
@@ -50,12 +58,4 @@ public class SQLDeclareStatement extends SQLStatementImpl {
|
||||
}
|
||||
this.items.add(item);
|
||||
}
|
||||
|
||||
public String getDbType() {
|
||||
return dbType;
|
||||
}
|
||||
|
||||
public void setDbType(String dbType) {
|
||||
this.dbType = dbType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,17 +57,15 @@ public class SQLIfStatement extends SQLStatementImpl {
|
||||
return statements;
|
||||
}
|
||||
|
||||
public void setStatements(List<SQLStatement> statements) {
|
||||
this.statements = statements;
|
||||
}
|
||||
|
||||
public List<ElseIf> getElseIfList() {
|
||||
return elseIfList;
|
||||
public void addStatement(SQLStatement statement) {
|
||||
if (statement != null) {
|
||||
statement.setParent(this);
|
||||
}
|
||||
this.statements.add(statement);
|
||||
}
|
||||
|
||||
|
||||
public void setElseIfList(List<ElseIf> elseIfList) {
|
||||
this.elseIfList = elseIfList;
|
||||
public List<ElseIf> getElseIfList() {
|
||||
return elseIfList;
|
||||
}
|
||||
|
||||
public Else getElseItem() {
|
||||
|
||||
@@ -30,7 +30,7 @@ public abstract class SQLInsertInto extends SQLObjectImpl {
|
||||
protected final List<SQLExpr> columns = new ArrayList<SQLExpr>();
|
||||
protected SQLSelect query;
|
||||
|
||||
protected List<ValuesClause> valuesList = new ArrayList<ValuesClause>();
|
||||
protected final List<ValuesClause> valuesList = new ArrayList<ValuesClause>();
|
||||
|
||||
public SQLInsertInto(){
|
||||
|
||||
@@ -105,7 +105,10 @@ public abstract class SQLInsertInto extends SQLObjectImpl {
|
||||
return valuesList;
|
||||
}
|
||||
|
||||
public void setValuesList(List<ValuesClause> valuesList) {
|
||||
this.valuesList = valuesList;
|
||||
public void addValueCause(ValuesClause valueClause) {
|
||||
if (valueClause != null) {
|
||||
valueClause.setParent(this);
|
||||
}
|
||||
valuesList.add(valueClause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,4 +48,10 @@ public class SQLLoopStatement extends SQLStatementImpl {
|
||||
this.labelName = labelName;
|
||||
}
|
||||
|
||||
public void addStatement(SQLStatement stmt) {
|
||||
if (stmt != null) {
|
||||
stmt.setParent(this);
|
||||
}
|
||||
statements.add(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,14 @@ public class SQLSelect extends SQLObjectImpl {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
public SQLSelectQueryBlock getQueryBlock() {
|
||||
if (query instanceof SQLSelectQueryBlock) {
|
||||
return (SQLSelectQueryBlock) query;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public SQLOrderBy getOrderBy() {
|
||||
return this.orderBy;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,11 @@ import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLSetStatement extends SQLStatementImpl {
|
||||
@@ -45,6 +49,11 @@ public class SQLSetStatement extends SQLStatementImpl {
|
||||
this.items.add(new SQLAssignItem(target, value));
|
||||
}
|
||||
|
||||
public static SQLSetStatement plus(SQLName target) {
|
||||
SQLExpr value = new SQLBinaryOpExpr(target.clone(), SQLBinaryOperator.Add, new SQLIntegerExpr(1));
|
||||
return new SQLSetStatement(target, value);
|
||||
}
|
||||
|
||||
public List<SQLAssignItem> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
+9
-1
@@ -25,7 +25,15 @@ import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
public class MySqlLeaveStatement extends MySqlStatementImpl {
|
||||
|
||||
private String labelName;
|
||||
|
||||
|
||||
public MySqlLeaveStatement() {
|
||||
|
||||
}
|
||||
|
||||
public MySqlLeaveStatement(String labelName) {
|
||||
this.labelName = labelName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
|
||||
+67
-12
@@ -15,16 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.mysql.parser;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLDeclareItem;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderBy;
|
||||
import com.alibaba.druid.sql.ast.SQLParameter;
|
||||
import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.ast.SQLParameter.ParameterType;
|
||||
import com.alibaba.druid.sql.ast.SQLPartition;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
@@ -355,6 +347,13 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
return parseCreateProcedure();
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.FUNCTION) {
|
||||
if (replace) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
}
|
||||
return parseCreateFunction();
|
||||
}
|
||||
|
||||
throw new ParserException("TODO " + lexer.info());
|
||||
}
|
||||
|
||||
@@ -1750,6 +1749,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
lexer.nextToken();
|
||||
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
|
||||
values.setParent(stmt);
|
||||
stmt.getValuesList().add(values);
|
||||
for (; ; ) {
|
||||
stmt.addColumn(this.exprParser.name());
|
||||
@@ -2100,7 +2100,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
lexer.nextToken();
|
||||
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
|
||||
insertStatement.getValuesList().add(values);
|
||||
insertStatement.addValueCause(values);
|
||||
|
||||
for (; ; ) {
|
||||
SQLName name = this.exprParser.name();
|
||||
@@ -3141,6 +3141,61 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
}
|
||||
|
||||
|
||||
public SQLCreateFunctionStatement parseCreateFunction() {
|
||||
SQLCreateFunctionStatement stmt = new SQLCreateFunctionStatement();
|
||||
stmt.setDbType(dbType);
|
||||
|
||||
if (lexer.token() != Token.FUNCTION) {
|
||||
if (identifierEquals("DEFINER")) {
|
||||
lexer.nextToken();
|
||||
accept(Token.EQ);
|
||||
SQLName definer = this.exprParser.name();
|
||||
stmt.setDefiner(definer);
|
||||
} else {
|
||||
accept(Token.CREATE);
|
||||
if (lexer.token() == Token.OR) {
|
||||
lexer.nextToken();
|
||||
accept(Token.REPLACE);
|
||||
stmt.setOrReplace(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
accept(Token.FUNCTION);
|
||||
|
||||
stmt.setName(this.exprParser.name());
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {// match "("
|
||||
lexer.nextToken();
|
||||
parserParameters(stmt.getParameters(), stmt);
|
||||
accept(Token.RPAREN);// match ")"
|
||||
}
|
||||
|
||||
acceptIdentifier("RETURNS");
|
||||
SQLDataType dataType = this.exprParser.parseDataType();
|
||||
stmt.setReturnDataType(dataType);
|
||||
|
||||
for (;;) {
|
||||
if (identifierEquals("DETERMINISTIC")) {
|
||||
lexer.nextToken();
|
||||
stmt.setDeterministic(true);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
SQLStatement block;
|
||||
if (lexer.token() == Token.BEGIN) {
|
||||
block = this.parseBlock();
|
||||
} else {
|
||||
block = this.parseStatement();
|
||||
}
|
||||
|
||||
stmt.setBlock(block);
|
||||
|
||||
return stmt;
|
||||
}
|
||||
/**
|
||||
* parse create procedure statement
|
||||
*/
|
||||
@@ -3173,7 +3228,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {// match "("
|
||||
lexer.nextToken();
|
||||
parserParameters(stmt.getParameters());
|
||||
parserParameters(stmt.getParameters(), stmt);
|
||||
accept(Token.RPAREN);// match ")"
|
||||
}
|
||||
SQLStatement block;
|
||||
@@ -3194,7 +3249,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
*
|
||||
* @param parameters
|
||||
*/
|
||||
private void parserParameters(List<SQLParameter> parameters) {
|
||||
private void parserParameters(List<SQLParameter> parameters, SQLObject parent) {
|
||||
if (lexer.token() == Token.RPAREN) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3587,4 +3587,46 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLCreateFunctionStatement x) {
|
||||
print0(ucase ? "CREATE FUNCTION " : "create function ");
|
||||
x.getName().accept(this);
|
||||
|
||||
int paramSize = x.getParameters().size();
|
||||
|
||||
if (paramSize > 0) {
|
||||
print0(" (");
|
||||
incrementIndent();
|
||||
println();
|
||||
|
||||
for (int i = 0; i < paramSize; ++i) {
|
||||
if (i != 0) {
|
||||
print0(", ");
|
||||
println();
|
||||
}
|
||||
SQLParameter param = x.getParameters().get(i);
|
||||
param.accept(this);
|
||||
}
|
||||
|
||||
decrementIndent();
|
||||
println();
|
||||
print(')');
|
||||
}
|
||||
|
||||
println();
|
||||
print(ucase ? "RETURNS " : "returns ");
|
||||
x.getReturnDataType().accept(this);
|
||||
|
||||
if (x.isDeterministic()) {
|
||||
print(ucase ? " DETERMINISTIC" : " deterministic");
|
||||
}
|
||||
|
||||
SQLStatement block = x.getBlock();
|
||||
|
||||
println();
|
||||
|
||||
block.accept(this);
|
||||
return false;
|
||||
}
|
||||
} //
|
||||
|
||||
+127
-45
@@ -17,12 +17,14 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLObject;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributes;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class OracleCreateIndexStatement extends SQLCreateIndexStatement implements OracleDDLStatement {
|
||||
public class OracleCreateIndexStatement extends SQLCreateIndexStatement implements OracleDDLStatement, OracleSegmentAttributes {
|
||||
|
||||
private boolean online = false;
|
||||
|
||||
@@ -32,12 +34,22 @@ public class OracleCreateIndexStatement extends SQLCreateIndexStatement implemen
|
||||
|
||||
private SQLExpr parallel;
|
||||
|
||||
private SQLName tablespace;
|
||||
private Integer pctfree;
|
||||
private Integer pctused;
|
||||
private Integer initrans;
|
||||
|
||||
private SQLExpr ptcfree;
|
||||
private SQLExpr pctused;
|
||||
private SQLExpr initrans;
|
||||
private SQLExpr maxtrans;
|
||||
private Integer maxtrans;
|
||||
private Integer pctincrease;
|
||||
private Integer freeLists;
|
||||
private Boolean compress;
|
||||
private Integer compressLevel;
|
||||
private boolean compressForOltp;
|
||||
private Integer pctthreshold;
|
||||
|
||||
private Boolean logging;
|
||||
|
||||
protected SQLName tablespace;
|
||||
protected SQLObject storage;
|
||||
|
||||
private Boolean enable = null;
|
||||
|
||||
@@ -47,14 +59,6 @@ public class OracleCreateIndexStatement extends SQLCreateIndexStatement implemen
|
||||
super (JdbcConstants.ORACLE);
|
||||
}
|
||||
|
||||
public SQLName getTablespace() {
|
||||
return tablespace;
|
||||
}
|
||||
|
||||
public void setTablespace(SQLName tablespace) {
|
||||
this.tablespace = tablespace;
|
||||
}
|
||||
|
||||
public SQLExpr getParallel() {
|
||||
return parallel;
|
||||
}
|
||||
@@ -95,37 +99,6 @@ public class OracleCreateIndexStatement extends SQLCreateIndexStatement implemen
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public SQLExpr getPtcfree() {
|
||||
return ptcfree;
|
||||
}
|
||||
|
||||
public void setPtcfree(SQLExpr ptcfree) {
|
||||
this.ptcfree = ptcfree;
|
||||
}
|
||||
|
||||
public SQLExpr getPctused() {
|
||||
return pctused;
|
||||
}
|
||||
|
||||
public void setPctused(SQLExpr pctused) {
|
||||
this.pctused = pctused;
|
||||
}
|
||||
|
||||
public SQLExpr getInitrans() {
|
||||
return initrans;
|
||||
}
|
||||
|
||||
public void setInitrans(SQLExpr initrans) {
|
||||
this.initrans = initrans;
|
||||
}
|
||||
|
||||
public SQLExpr getMaxtrans() {
|
||||
return maxtrans;
|
||||
}
|
||||
|
||||
public void setMaxtrans(SQLExpr maxtrans) {
|
||||
this.maxtrans = maxtrans;
|
||||
}
|
||||
|
||||
public Boolean getEnable() {
|
||||
return enable;
|
||||
@@ -151,4 +124,113 @@ public class OracleCreateIndexStatement extends SQLCreateIndexStatement implemen
|
||||
this.online = online;
|
||||
}
|
||||
|
||||
//////////////
|
||||
|
||||
public SQLName getTablespace() {
|
||||
return tablespace;
|
||||
}
|
||||
|
||||
public void setTablespace(SQLName tablespace) {
|
||||
if (tablespace != null) {
|
||||
tablespace.setParent(this);
|
||||
}
|
||||
this.tablespace = tablespace;
|
||||
}
|
||||
|
||||
public Boolean getCompress() {
|
||||
return compress;
|
||||
}
|
||||
|
||||
public void setCompress(Boolean compress) {
|
||||
this.compress = compress;
|
||||
}
|
||||
|
||||
public Integer getCompressLevel() {
|
||||
return compressLevel;
|
||||
}
|
||||
|
||||
public void setCompressLevel(Integer compressLevel) {
|
||||
this.compressLevel = compressLevel;
|
||||
}
|
||||
|
||||
public Integer getPctthreshold() {
|
||||
return pctthreshold;
|
||||
}
|
||||
|
||||
public void setPctthreshold(Integer pctthreshold) {
|
||||
this.pctthreshold = pctthreshold;
|
||||
}
|
||||
|
||||
public Integer getPctfree() {
|
||||
return pctfree;
|
||||
}
|
||||
|
||||
public void setPctfree(Integer ptcfree) {
|
||||
this.pctfree = ptcfree;
|
||||
}
|
||||
|
||||
public Integer getPctused() {
|
||||
return pctused;
|
||||
}
|
||||
|
||||
public void setPctused(Integer ptcused) {
|
||||
this.pctused = ptcused;
|
||||
}
|
||||
|
||||
public Integer getInitrans() {
|
||||
return initrans;
|
||||
}
|
||||
|
||||
public void setInitrans(Integer initrans) {
|
||||
this.initrans = initrans;
|
||||
}
|
||||
|
||||
public Integer getMaxtrans() {
|
||||
return maxtrans;
|
||||
}
|
||||
|
||||
public void setMaxtrans(Integer maxtrans) {
|
||||
this.maxtrans = maxtrans;
|
||||
}
|
||||
|
||||
public Integer getPctincrease() {
|
||||
return pctincrease;
|
||||
}
|
||||
|
||||
public void setPctincrease(Integer pctincrease) {
|
||||
this.pctincrease = pctincrease;
|
||||
}
|
||||
|
||||
public Integer getFreeLists() {
|
||||
return freeLists;
|
||||
}
|
||||
|
||||
public void setFreeLists(Integer freeLists) {
|
||||
this.freeLists = freeLists;
|
||||
}
|
||||
|
||||
public Boolean getLogging() {
|
||||
return logging;
|
||||
}
|
||||
|
||||
public void setLogging(Boolean logging) {
|
||||
this.logging = logging;
|
||||
}
|
||||
|
||||
public SQLObject getStorage() {
|
||||
return storage;
|
||||
}
|
||||
|
||||
public void setStorage(SQLObject storage) {
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
public boolean isCompressForOltp() {
|
||||
return compressForOltp;
|
||||
}
|
||||
|
||||
public void setCompressForOltp(boolean compressForOltp) {
|
||||
this.compressForOltp = compressForOltp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+22
-1
@@ -77,6 +77,27 @@ public class OracleLockTableStatement extends OracleStatementImpl {
|
||||
}
|
||||
|
||||
public static enum LockMode {
|
||||
EXCLUSIVE, SHARE
|
||||
ROW_SHARE,
|
||||
ROW_EXCLUSIVE,
|
||||
SHARE_UPDATE,
|
||||
SHARE,
|
||||
SHARE_ROW_EXCLUSIVE,
|
||||
EXCLUSIVE,
|
||||
;
|
||||
|
||||
public String toString() {
|
||||
switch (this) {
|
||||
case ROW_SHARE:
|
||||
return "ROW SHARE";
|
||||
case ROW_EXCLUSIVE:
|
||||
return "ROW EXCLUSIVE";
|
||||
case SHARE_UPDATE:
|
||||
return "SHARE UPDATE";
|
||||
case SHARE_ROW_EXCLUSIVE:
|
||||
return "SHARE ROW EXCLUSIVE";
|
||||
default:
|
||||
return this.name();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+32
-20
@@ -1442,12 +1442,38 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
stmt.setTable(this.exprParser.name());
|
||||
|
||||
accept(Token.IN);
|
||||
if (lexer.token() == Token.SHARE) {
|
||||
stmt.setLockMode(LockMode.SHARE);
|
||||
|
||||
Token token = lexer.token();
|
||||
if (token == Token.SHARE) {
|
||||
lexer.nextToken();
|
||||
} else if (lexer.token() == Token.EXCLUSIVE) {
|
||||
|
||||
if (lexer.token() == Token.ROW) {
|
||||
lexer.nextToken();
|
||||
accept(Token.EXCLUSIVE);
|
||||
stmt.setLockMode(LockMode.SHARE_ROW_EXCLUSIVE);
|
||||
} else if (lexer.token() == Token.UPDATE) {
|
||||
lexer.nextToken();
|
||||
stmt.setLockMode(LockMode.SHARE_UPDATE);
|
||||
} else {
|
||||
stmt.setLockMode(LockMode.SHARE);
|
||||
}
|
||||
} else if (token == Token.EXCLUSIVE) {
|
||||
stmt.setLockMode(LockMode.EXCLUSIVE);
|
||||
lexer.nextToken();
|
||||
} else if(token == Token.ROW) {
|
||||
lexer.nextToken();
|
||||
token = lexer.token();
|
||||
if (token == Token.SHARE) {
|
||||
stmt.setLockMode(LockMode.ROW_SHARE);
|
||||
lexer.nextToken();
|
||||
} else if (token == Token.EXCLUSIVE) {
|
||||
stmt.setLockMode(LockMode.ROW_EXCLUSIVE);
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
throw new ParserException(lexer.info());
|
||||
}
|
||||
} else {
|
||||
throw new ParserException(lexer.info());
|
||||
}
|
||||
accept(Token.MODE);
|
||||
|
||||
@@ -1944,23 +1970,9 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
accept(Token.RPAREN);
|
||||
|
||||
for (;;) {
|
||||
if (lexer.token() == Token.TABLESPACE) {
|
||||
lexer.nextToken();
|
||||
stmt.setTablespace(this.exprParser.name());
|
||||
continue;
|
||||
} else if (lexer.token() == Token.PCTFREE) {
|
||||
lexer.nextToken();
|
||||
stmt.setPtcfree(this.exprParser.expr());
|
||||
continue;
|
||||
} else if (lexer.token() == Token.INITRANS) {
|
||||
lexer.nextToken();
|
||||
stmt.setInitrans(this.exprParser.expr());
|
||||
continue;
|
||||
} else if (lexer.token() == Token.MAXTRANS) {
|
||||
lexer.nextToken();
|
||||
stmt.setMaxtrans(this.exprParser.expr());
|
||||
continue;
|
||||
} else if (lexer.token() == Token.COMPUTE) {
|
||||
this.getExprParser().parseSegmentAttributes(stmt);
|
||||
|
||||
if (lexer.token() == Token.COMPUTE) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("STATISTICS");
|
||||
stmt.setComputeStatistics(true);
|
||||
|
||||
+4
-19
@@ -1363,7 +1363,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
print0(ucase ? "LOCK TABLE " : "lock table ");
|
||||
x.getTable().accept(this);
|
||||
print0(ucase ? " IN " : " in ");
|
||||
print0(x.getLockMode().name());
|
||||
print0(x.getLockMode().toString());
|
||||
print0(ucase ? " MODE " : " mode ");
|
||||
if (x.isNoWait()) {
|
||||
print0(ucase ? "NOWAIT" : "nowait");
|
||||
@@ -1752,24 +1752,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
print0(ucase ? "INDEX ONLY TOPLEVEL" : "index only toplevel");
|
||||
}
|
||||
|
||||
if (x.getPtcfree() != null) {
|
||||
println();
|
||||
print0(ucase ? "PCTFREE " : "pctfree ");
|
||||
x.getPtcfree().accept(this);
|
||||
}
|
||||
|
||||
if (x.getInitrans() != null) {
|
||||
println();
|
||||
print0(ucase ? "INITRANS " : "initrans ");
|
||||
x.getInitrans().accept(this);
|
||||
}
|
||||
|
||||
if (x.getMaxtrans() != null) {
|
||||
println();
|
||||
print0(ucase ? "MAXTRANS " : "maxtrans ");
|
||||
x.getMaxtrans().accept(this);
|
||||
}
|
||||
|
||||
if (x.isComputeStatistics()) {
|
||||
println();
|
||||
print0(ucase ? "COMPUTE STATISTICS" : "compute statistics");
|
||||
@@ -1791,6 +1773,9 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
print0(ucase ? " PARALLEL " : " parallel ");
|
||||
x.getParallel().accept(this);
|
||||
}
|
||||
|
||||
this.printOracleSegmentAttributes(x);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
-21
@@ -27,33 +27,12 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLServerInsertStatement extends SQLInsertStatement implements SQLServerObject {
|
||||
|
||||
private List<ValuesClause> valuesList = new ArrayList<ValuesClause>();
|
||||
|
||||
private boolean defaultValues;
|
||||
|
||||
private SQLServerTop top;
|
||||
|
||||
private SQLServerOutput output;
|
||||
|
||||
public ValuesClause getValues() {
|
||||
if (valuesList.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
return valuesList.get(0);
|
||||
}
|
||||
|
||||
public void setValues(ValuesClause values) {
|
||||
if (valuesList.size() == 0) {
|
||||
valuesList.add(values);
|
||||
} else {
|
||||
valuesList.set(0, values);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ValuesClause> getValuesList() {
|
||||
return valuesList;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
this.accept0((SQLServerASTVisitor) visitor);
|
||||
|
||||
+1
-1
@@ -283,7 +283,7 @@ public class SQLServerStatementParser extends SQLStatementParser {
|
||||
accept(Token.LPAREN);
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
|
||||
this.exprParser.exprList(values.getValues(), values);
|
||||
insertStatement.getValuesList().add(values);
|
||||
insertStatement.addValueCause(values);
|
||||
accept(Token.RPAREN);
|
||||
|
||||
if (!parseCompleteValues && insertStatement.getValuesList().size() >= parseValuesSize) {
|
||||
|
||||
@@ -361,6 +361,12 @@ public class SQLStatementParser extends SQLParser {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (identifierEquals("RETURN")) {
|
||||
SQLStatement stmt = parseReturn();
|
||||
statementList.add(stmt);
|
||||
continue;
|
||||
}
|
||||
|
||||
// throw new ParserException("syntax error, " + lexer.token() + " "
|
||||
// + lexer.stringVal() + ", pos "
|
||||
// + lexer.pos());
|
||||
@@ -368,6 +374,24 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
}
|
||||
|
||||
public SQLStatement parseReturn() {
|
||||
if (lexer.token() == Token.RETURN
|
||||
|| identifierEquals("RETURN")) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
SQLReturnStatement stmt = new SQLReturnStatement();
|
||||
if (lexer.token() != Token.SEMI) {
|
||||
SQLExpr expr = this.exprParser.expr();
|
||||
stmt.setExpr(expr);
|
||||
}
|
||||
|
||||
accept(Token.SEMI);
|
||||
stmt.setAfterSemi(true);
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
public SQLStatement parseUpsert() {
|
||||
SQLInsertStatement insertStatement = new SQLInsertStatement();
|
||||
|
||||
@@ -1539,7 +1563,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
accept(Token.LPAREN);
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
|
||||
this.exprParser.exprList(values.getValues(), values);
|
||||
insertStatement.getValuesList().add(values);
|
||||
insertStatement.addValueCause(values);
|
||||
accept(Token.RPAREN);
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
|
||||
@@ -42,7 +42,7 @@ public class SchemaObject {
|
||||
}
|
||||
|
||||
public static enum Type {
|
||||
Sequence, Table, Index
|
||||
Sequence, Table, Index, Function
|
||||
}
|
||||
|
||||
public SQLStatement getStatement() {
|
||||
|
||||
@@ -17,13 +17,17 @@ package com.alibaba.druid.sql.repository;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitorAdapter;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
@@ -33,9 +37,11 @@ import java.util.concurrent.ConcurrentSkipListMap;
|
||||
* Created by wenshao on 03/06/2017.
|
||||
*/
|
||||
public class SchemaRepository {
|
||||
public Map<String, SchemaObject> objects = new ConcurrentSkipListMap<String, SchemaObject>();
|
||||
private final Map<String, SchemaObject> objects = new ConcurrentSkipListMap<String, SchemaObject>();
|
||||
|
||||
public final SchemaVisitor visitor = new SchemaVisitor();
|
||||
private final Map<String, SchemaObject> functions = new ConcurrentSkipListMap<String, SchemaObject>();
|
||||
|
||||
private final SchemaVisitor visitor = new SchemaVisitor();
|
||||
|
||||
public SchemaObject findTable(String tableName) {
|
||||
String lowerName = tableName.toLowerCase();
|
||||
@@ -48,6 +54,11 @@ public class SchemaRepository {
|
||||
return null;
|
||||
}
|
||||
|
||||
public SchemaObject findFunction(String functionName) {
|
||||
String lowerName = functionName.toLowerCase();
|
||||
return functions.get(lowerName);
|
||||
}
|
||||
|
||||
public void acceptDDL(String ddl, String dbType) {
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(ddl, dbType);
|
||||
for (SQLStatement stmt : stmtList) {
|
||||
@@ -103,6 +114,15 @@ public class SchemaRepository {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateFunctionStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObject(name, SchemaObject.Type.Function, x);
|
||||
|
||||
functions.put(name.toLowerCase(), object);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public SchemaObject findTable(SQLTableSource tableSource, String alias) {
|
||||
@@ -134,4 +154,103 @@ public class SchemaRepository {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public SQLColumnDefinition findColumn(SQLTableSource tableSource, SQLSelectItem selectItem) {
|
||||
if (selectItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return findColumn(tableSource, selectItem.getExpr());
|
||||
}
|
||||
|
||||
public SQLColumnDefinition findColumn(SQLTableSource tableSource, SQLExpr expr) {
|
||||
SchemaObject object = findTable(tableSource, expr);
|
||||
if (object != null) {
|
||||
if (expr instanceof SQLAggregateExpr) {
|
||||
SQLAggregateExpr aggregateExpr = (SQLAggregateExpr) expr;
|
||||
String function = aggregateExpr.getMethodName();
|
||||
if ("min".equalsIgnoreCase(function)
|
||||
|| "max".equalsIgnoreCase(function)) {
|
||||
SQLExpr arg = aggregateExpr.getArguments().get(0);
|
||||
expr = arg;
|
||||
}
|
||||
}
|
||||
|
||||
if (expr instanceof SQLName) {
|
||||
return object.findColumn(((SQLName) expr).getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public SchemaObject findTable(SQLTableSource tableSource, SQLSelectItem selectItem) {
|
||||
if (selectItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return findTable(tableSource, selectItem.getExpr());
|
||||
}
|
||||
|
||||
public SchemaObject findTable(SQLTableSource tableSource, SQLExpr expr) {
|
||||
if (expr instanceof SQLAggregateExpr) {
|
||||
SQLAggregateExpr aggregateExpr = (SQLAggregateExpr) expr;
|
||||
String function = aggregateExpr.getMethodName();
|
||||
if ("min".equalsIgnoreCase(function)
|
||||
|| "max".equalsIgnoreCase(function)) {
|
||||
SQLExpr arg = aggregateExpr.getArguments().get(0);
|
||||
return findTable(tableSource, arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (expr instanceof SQLPropertyExpr) {
|
||||
String ownerName = ((SQLPropertyExpr) expr).getOwnernName();
|
||||
return findTable(tableSource, ownerName);
|
||||
}
|
||||
|
||||
if (expr instanceof SQLAllColumnExpr || expr instanceof SQLIdentifierExpr) {
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
return findTable(tableSource, tableSource.computeAlias());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String, SchemaObject> getTables(SQLTableSource x) {
|
||||
Map<String, SchemaObject> tables = new LinkedHashMap<String, SchemaObject>();
|
||||
computeTable(x, tables);
|
||||
return tables;
|
||||
}
|
||||
|
||||
private void computeTable(SQLTableSource x, Map<String, SchemaObject> tables) {
|
||||
if (x == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (x instanceof SQLExprTableSource) {
|
||||
SQLExpr expr = ((SQLExprTableSource) x).getExpr();
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
String tableName = ((SQLIdentifierExpr) expr).getName();
|
||||
SchemaObject table = findTable(tableName);
|
||||
if (table != null) {
|
||||
tables.put(tableName, table);
|
||||
|
||||
String alias = x.getAlias();
|
||||
if (alias != null && !alias.equalsIgnoreCase(tableName)) {
|
||||
tables.put(alias, table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (x instanceof SQLJoinTableSource) {
|
||||
SQLJoinTableSource join = (SQLJoinTableSource) x;
|
||||
computeTable(join.getLeft(), tables);
|
||||
computeTable(join.getRight(), tables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3606,7 +3606,12 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
} else {
|
||||
if (x.getParamType() == SQLParameter.ParameterType.IN) {
|
||||
print0(ucase ? "IN " : "in ");
|
||||
boolean skip = JdbcConstants.MYSQL.equals(dbType)
|
||||
&& x.getParent() instanceof SQLCreateFunctionStatement;
|
||||
|
||||
if (!skip) {
|
||||
print0(ucase ? "IN " : "in ");
|
||||
}
|
||||
} else if (x.getParamType() == SQLParameter.ParameterType.OUT) {
|
||||
print0(ucase ? "OUT " : "out ");
|
||||
} else if (x.getParamType() == SQLParameter.ParameterType.INOUT) {
|
||||
|
||||
Reference in New Issue
Block a user