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:
@@ -67,6 +67,10 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public void setOwner(String owner) {
|
||||
this.setOwner(new SQLIdentifierExpr(owner));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@@ -162,4 +162,17 @@ public class SQLAlterTableStatement extends SQLStatementImpl implements SQLDDLSt
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getSchema() {
|
||||
SQLName name = getName();
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name instanceof SQLPropertyExpr) {
|
||||
return ((SQLPropertyExpr) name).getOwnernName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.alibaba.druid.sql.ast.statement;
|
||||
|
||||
import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -153,4 +154,17 @@ public class SQLCreateFunctionStatement extends SQLStatementImpl {
|
||||
public void setDeterministic(boolean deterministic) {
|
||||
this.deterministic = deterministic;
|
||||
}
|
||||
|
||||
public String getSchema() {
|
||||
SQLName name = getName();
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name instanceof SQLPropertyExpr) {
|
||||
return ((SQLPropertyExpr) name).getOwnernName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,4 +115,24 @@ public class SQLCreateIndexStatement extends SQLStatementImpl implements SQLDDLS
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public String getSchema() {
|
||||
SQLName name = null;
|
||||
if (table instanceof SQLExprTableSource) {
|
||||
SQLExpr expr = ((SQLExprTableSource) table).getExpr();
|
||||
if (expr instanceof SQLName) {
|
||||
name = (SQLName) expr;
|
||||
}
|
||||
}
|
||||
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name instanceof SQLPropertyExpr) {
|
||||
return ((SQLPropertyExpr) name).getOwnernName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ 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.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
@@ -130,4 +131,17 @@ public class SQLCreateSequenceStatement extends SQLStatementImpl {
|
||||
public void setNoMinValue(boolean noMinValue) {
|
||||
this.noMinValue = noMinValue;
|
||||
}
|
||||
|
||||
public String getSchema() {
|
||||
SQLName name = getName();
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name instanceof SQLPropertyExpr) {
|
||||
return ((SQLPropertyExpr) name).getOwnernName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,26 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
|
||||
return (SQLName) tableSource.getExpr();
|
||||
}
|
||||
|
||||
public String getSchema() {
|
||||
SQLName name = getName();
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name instanceof SQLPropertyExpr) {
|
||||
return ((SQLPropertyExpr) name).getOwnernName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setSchema(String name) {
|
||||
if (this.tableSource == null) {
|
||||
return;
|
||||
}
|
||||
tableSource.setSchema(name);
|
||||
}
|
||||
|
||||
public void setName(SQLName name) {
|
||||
this.setTableSource(new SQLExprTableSource(name));
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLStatement {
|
||||
@@ -73,6 +74,19 @@ public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLSt
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getSchema() {
|
||||
SQLName name = getName();
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name instanceof SQLPropertyExpr) {
|
||||
return ((SQLPropertyExpr) name).getOwnernName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isOrReplace() {
|
||||
return orReplace;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.ast.statement;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLDropSequenceStatement extends SQLStatementImpl implements SQLDDLStatement {
|
||||
@@ -55,4 +56,17 @@ public class SQLDropSequenceStatement extends SQLStatementImpl implements SQLDDL
|
||||
public void setIfExists(boolean ifExists) {
|
||||
this.ifExists = ifExists;
|
||||
}
|
||||
|
||||
public String getSchema() {
|
||||
SQLName name = getName();
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name instanceof SQLPropertyExpr) {
|
||||
return ((SQLPropertyExpr) name).getOwnernName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,11 +18,14 @@ package com.alibaba.druid.sql.ast.statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLDropTableStatement extends SQLStatementImpl implements SQLDDLStatement {
|
||||
private List<SQLCommentHint> hints;
|
||||
|
||||
protected List<SQLExprTableSource> tableSources = new ArrayList<SQLExprTableSource>();
|
||||
|
||||
@@ -129,4 +132,11 @@ public class SQLDropTableStatement extends SQLStatementImpl implements SQLDDLSta
|
||||
this.temporary = temporary;
|
||||
}
|
||||
|
||||
public List<SQLCommentHint> getHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
public void setHints(List<SQLCommentHint> hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ 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.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.repository.SchemaObject;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@@ -57,6 +58,43 @@ public class SQLExprTableSource extends SQLTableSourceImpl {
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
public SQLName getName() {
|
||||
if (expr instanceof SQLName) {
|
||||
return (SQLName) expr;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getSchema() {
|
||||
if (expr == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (expr instanceof SQLPropertyExpr) {
|
||||
return ((SQLPropertyExpr) expr).getOwnernName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setSchema(String schema) {
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
if (schema == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String ident = ((SQLIdentifierExpr) expr).getName();
|
||||
this.setExpr(new SQLPropertyExpr(schema, ident));
|
||||
} else if (expr instanceof SQLPropertyExpr) {
|
||||
SQLPropertyExpr propertyExpr = (SQLPropertyExpr) expr;
|
||||
if (schema == null) {
|
||||
setExpr(new SQLIdentifierExpr(propertyExpr.getName()));
|
||||
} else {
|
||||
propertyExpr.setOwner(schema);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<SQLName> getPartitions() {
|
||||
if (this.partitions == null) {
|
||||
this.partitions = new ArrayList<SQLName>(2);
|
||||
|
||||
@@ -19,11 +19,7 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLHint;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLObject;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
@@ -396,8 +392,18 @@ public class SQLStatementParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
|
||||
final SQLStatement stmt;
|
||||
|
||||
List<SQLCommentHint> hints = null;
|
||||
if (lexer.token() == Token.HINT) {
|
||||
hints = this.exprParser.parseHints();
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.TABLE || identifierEquals("TEMPORARY")) {
|
||||
stmt = parseDropTable(false);
|
||||
SQLDropTableStatement dropTable = parseDropTable(false);
|
||||
if (hints != null) {
|
||||
dropTable.setHints(hints);
|
||||
}
|
||||
stmt = dropTable;
|
||||
} else if (lexer.token() == Token.USER) {
|
||||
stmt = parseDropUser();
|
||||
} else if (lexer.token() == Token.INDEX) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitorAdapter;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -45,20 +46,17 @@ public class Schema {
|
||||
|
||||
protected final Map<String, SchemaObject> objects = new ConcurrentSkipListMap<String, SchemaObject>();
|
||||
|
||||
private final Map<String, SchemaObject> functions = new ConcurrentSkipListMap<String, SchemaObject>();
|
||||
|
||||
private final SQLASTVisitor visitor;
|
||||
protected final Map<String, SchemaObject> functions = new ConcurrentSkipListMap<String, SchemaObject>();
|
||||
|
||||
private SchemaRepository repository;
|
||||
|
||||
public Schema(SchemaRepository repository) {
|
||||
this.repository = repository;
|
||||
this(repository, null);
|
||||
}
|
||||
|
||||
if (JdbcConstants.MYSQL.equals(repository.dbType)) {
|
||||
visitor = new MySqlSchemaVisitor();
|
||||
} else {
|
||||
visitor = new OracleSchemaVisitor();
|
||||
}
|
||||
public Schema(SchemaRepository repository, String name) {
|
||||
this.repository = repository;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -102,208 +100,12 @@ public class Schema {
|
||||
return functions.get(lowerName);
|
||||
}
|
||||
|
||||
public void acceptDDL(String ddl, String dbType) {
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(ddl, dbType);
|
||||
for (SQLStatement stmt : stmtList) {
|
||||
accept(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
public void accept(SQLStatement stmt) {
|
||||
stmt.accept(visitor);
|
||||
}
|
||||
|
||||
public boolean isSequence(String name) {
|
||||
SchemaObject object = objects.get(name);
|
||||
return object != null
|
||||
&& object.getType() == SchemaObjectType.Sequence;
|
||||
}
|
||||
|
||||
public class OracleSchemaVisitor extends OracleASTVisitorAdapter {
|
||||
|
||||
public boolean visit(SQLDropSequenceStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
objects.remove(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateSequenceStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Sequence);
|
||||
|
||||
objects.put(name.toLowerCase(), object);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(OracleCreateTableStatement x) {
|
||||
visit((SQLCreateTableStatement) x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateTableStatement x) {
|
||||
acceptCreateTable(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateViewStatement x) {
|
||||
String name = x.computeName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.View, x);
|
||||
|
||||
String name_lower = name.toLowerCase();
|
||||
if (objects.containsKey(name_lower)) {
|
||||
return false;
|
||||
}
|
||||
objects.put(name_lower, object);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateIndexStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Index);
|
||||
|
||||
objects.put(name.toLowerCase(), object);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateFunctionStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Function, x);
|
||||
|
||||
functions.put(name.toLowerCase(), object);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLAlterTableStatement x) {
|
||||
SQLName table = x.getName();
|
||||
SchemaObject object = repository.findTable(table);
|
||||
if (object != null) {
|
||||
SQLCreateTableStatement stmt = (SQLCreateTableStatement) object.getStatement();
|
||||
if (stmt != null) {
|
||||
stmt.apply(x);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean acceptCreateTable(SQLCreateTableStatement x) {
|
||||
SQLSelect select = x.getSelect();
|
||||
if (select != null) {
|
||||
select.accept(
|
||||
repository.createResolveVisitor());
|
||||
|
||||
SQLSelectQueryBlock queryBlock = select.getFirstQueryBlock();
|
||||
if (queryBlock != null) {
|
||||
List<SQLSelectItem> selectList = queryBlock.getSelectList();
|
||||
for (SQLSelectItem selectItem : selectList) {
|
||||
String name = selectItem.computeAlias();
|
||||
SQLDataType dataType = selectItem.computeDataType();
|
||||
SQLColumnDefinition column = new SQLColumnDefinition();
|
||||
column.setName(name);
|
||||
column.setDataType(dataType);
|
||||
column.setDbType(repository.dbType);
|
||||
x.getTableElementList().add(column);
|
||||
}
|
||||
x.setSelect(null);
|
||||
}
|
||||
}
|
||||
|
||||
String name = x.computeName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Table, x);
|
||||
|
||||
String name_lower = name.toLowerCase();
|
||||
if (objects.containsKey(name_lower)) {
|
||||
return false;
|
||||
}
|
||||
objects.put(name_lower, object);
|
||||
return true;
|
||||
}
|
||||
|
||||
private class MySqlSchemaVisitor extends MySqlASTVisitorAdapter {
|
||||
|
||||
public boolean visit(SQLDropSequenceStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
objects.remove(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateSequenceStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Sequence);
|
||||
|
||||
objects.put(name.toLowerCase(), object);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(MySqlCreateTableStatement x) {
|
||||
SQLExprTableSource like = x.getLike();
|
||||
if (like != null) {
|
||||
SchemaObject table = repository.findTable((SQLName) like.getExpr());
|
||||
if (table != null) {
|
||||
MySqlCreateTableStatement stmt = (MySqlCreateTableStatement) table.getStatement();
|
||||
MySqlCreateTableStatement stmtCloned = stmt.clone();
|
||||
stmtCloned.setName(x.getName().clone());
|
||||
acceptCreateTable(stmtCloned);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
acceptCreateTable(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateTableStatement x) {
|
||||
acceptCreateTable(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateViewStatement x) {
|
||||
String name = x.computeName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.View, x);
|
||||
|
||||
String name_lower = name.toLowerCase();
|
||||
if (objects.containsKey(name_lower)) {
|
||||
return false;
|
||||
}
|
||||
objects.put(name_lower, object);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateIndexStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Index);
|
||||
|
||||
objects.put(name.toLowerCase(), object);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateFunctionStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Function, x);
|
||||
|
||||
functions.put(name.toLowerCase(), object);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLAlterTableStatement x) {
|
||||
SQLName table = x.getName();
|
||||
SchemaObject object = repository.findTable(table);
|
||||
if (object != null) {
|
||||
SQLCreateTableStatement stmt = (SQLCreateTableStatement) object.getStatement();
|
||||
if (stmt != null) {
|
||||
stmt.apply(x);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public SchemaObject findTable(SQLTableSource tableSource, String alias) {
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
@@ -499,4 +301,14 @@ public class Schema {
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public List<String> showTables() {
|
||||
List<String> tables = new ArrayList<String>(objects.size());
|
||||
for (SchemaObject object : objects.values()) {
|
||||
if (object.getType() == SchemaObjectType.Table) {
|
||||
tables.add(object.getName());
|
||||
}
|
||||
}
|
||||
return tables;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.repository;
|
||||
|
||||
import com.alibaba.druid.DruidRuntimeException;
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
@@ -34,6 +35,7 @@ import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitorAdapter;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
@@ -47,6 +49,7 @@ import java.util.concurrent.ConcurrentSkipListMap;
|
||||
public class SchemaRepository {
|
||||
private Schema defaultSchema;
|
||||
protected String dbType;
|
||||
protected SQLASTVisitor consoleVisitor;
|
||||
|
||||
public SchemaRepository() {
|
||||
|
||||
@@ -54,6 +57,14 @@ public class SchemaRepository {
|
||||
|
||||
public SchemaRepository(String dbType) {
|
||||
this.dbType = dbType;
|
||||
|
||||
if (JdbcConstants.MYSQL.equals(dbType)) {
|
||||
consoleVisitor = new MySqlConsoleSchemaVisitor();
|
||||
} else if (JdbcConstants.ORACLE.equals(dbType)) {
|
||||
consoleVisitor = new OracleConsoleSchemaVisitor();
|
||||
} else {
|
||||
consoleVisitor = new DefaultConsoleSchemaVisitor();
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Schema> schemas = new LinkedHashMap<String, Schema>();
|
||||
@@ -94,13 +105,22 @@ public class SchemaRepository {
|
||||
}
|
||||
|
||||
public Schema findSchema(String schema) {
|
||||
if (schema == null) {
|
||||
return null;
|
||||
return findSchema(schema, false);
|
||||
}
|
||||
|
||||
protected Schema findSchema(String name, boolean create) {
|
||||
if (name == null || name.length() == 0) {
|
||||
return getDefaultSchema();
|
||||
}
|
||||
|
||||
return schemas.get(
|
||||
SQLUtils.normalize(schema)
|
||||
.toLowerCase());
|
||||
String normalizedName = SQLUtils.normalize(name)
|
||||
.toLowerCase();
|
||||
Schema schema = schemas.get(normalizedName);
|
||||
if (schema == null) {
|
||||
schema = new Schema(this, name);
|
||||
schemas.put(normalizedName, schema);
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
|
||||
public Schema getDefaultSchema() {
|
||||
@@ -158,11 +178,14 @@ public class SchemaRepository {
|
||||
}
|
||||
|
||||
public void acceptDDL(String ddl, String dbType) {
|
||||
getDefaultSchema().acceptDDL(ddl, dbType);
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(ddl, dbType);
|
||||
for (SQLStatement stmt : stmtList) {
|
||||
accept(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
public void accept(SQLStatement stmt) {
|
||||
getDefaultSchema().accept(stmt);
|
||||
stmt.accept(consoleVisitor);
|
||||
}
|
||||
|
||||
public boolean isSequence(String name) {
|
||||
@@ -224,11 +247,32 @@ public class SchemaRepository {
|
||||
SchemaObject schemaObject = findTable(table);
|
||||
MySqlCreateTableStatement createTableStmt = (MySqlCreateTableStatement) schemaObject.getStatement();
|
||||
createTableStmt.output(buf);
|
||||
} else if (stmt instanceof SQLShowTablesStatement) {
|
||||
SQLShowTablesStatement showTables = (SQLShowTablesStatement) stmt;
|
||||
SQLName database = showTables.getDatabase();
|
||||
|
||||
Schema schema;
|
||||
if (database == null) {
|
||||
schema = getDefaultSchema();
|
||||
} else {
|
||||
schema = findSchema(database.getSimpleName());
|
||||
}
|
||||
if (schema != null) {
|
||||
for (String table : schema.showTables()) {
|
||||
buf.append(table);
|
||||
buf.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
this.getDefaultSchema().accept(stmt);
|
||||
stmt.accept(consoleVisitor);
|
||||
}
|
||||
}
|
||||
|
||||
if (buf.length() == 0) {
|
||||
return "\n";
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
} catch (IOException ex) {
|
||||
throw new DruidRuntimeException("exeucte command error.", ex);
|
||||
@@ -371,4 +415,288 @@ public class SchemaRepository {
|
||||
public class OracleResolveVisitor extends OracleASTVisitorAdapter {
|
||||
|
||||
}
|
||||
|
||||
public class MySqlConsoleSchemaVisitor extends MySqlASTVisitorAdapter {
|
||||
public boolean visit(SQLDropSequenceStatement x) {
|
||||
acceptDropSequence(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateSequenceStatement x) {
|
||||
acceptCreateSequence(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(MySqlCreateTableStatement x) {
|
||||
acceptCreateTable(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateTableStatement x) {
|
||||
acceptCreateTable(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLDropTableStatement x) {
|
||||
acceptDropTable(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateViewStatement x) {
|
||||
acceptView(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateIndexStatement x) {
|
||||
acceptCreateIndex(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateFunctionStatement x) {
|
||||
acceptCreateFunction(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLAlterTableStatement x) {
|
||||
acceptAlterTable(x);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class OracleConsoleSchemaVisitor extends OracleASTVisitorAdapter {
|
||||
public boolean visit(SQLDropSequenceStatement x) {
|
||||
acceptDropSequence(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateSequenceStatement x) {
|
||||
acceptCreateSequence(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(OracleCreateTableStatement x) {
|
||||
visit((SQLCreateTableStatement) x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateTableStatement x) {
|
||||
acceptCreateTable(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLDropTableStatement x) {
|
||||
acceptDropTable(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateViewStatement x) {
|
||||
acceptView(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateIndexStatement x) {
|
||||
acceptCreateIndex(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateFunctionStatement x) {
|
||||
acceptCreateFunction(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLAlterTableStatement x) {
|
||||
acceptAlterTable(x);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class DefaultConsoleSchemaVisitor extends SQLASTVisitorAdapter {
|
||||
public boolean visit(SQLDropSequenceStatement x) {
|
||||
acceptDropSequence(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateSequenceStatement x) {
|
||||
acceptCreateSequence(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateTableStatement x) {
|
||||
acceptCreateTable(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLDropTableStatement x) {
|
||||
acceptDropTable(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateViewStatement x) {
|
||||
acceptView(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateIndexStatement x) {
|
||||
acceptCreateIndex(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateFunctionStatement x) {
|
||||
acceptCreateFunction(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLAlterTableStatement x) {
|
||||
acceptAlterTable(x);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean acceptCreateTable(MySqlCreateTableStatement x) {
|
||||
SQLExprTableSource like = x.getLike();
|
||||
if (like != null) {
|
||||
SchemaObject table = findTable((SQLName) like.getExpr());
|
||||
if (table != null) {
|
||||
MySqlCreateTableStatement stmt = (MySqlCreateTableStatement) table.getStatement();
|
||||
MySqlCreateTableStatement stmtCloned = stmt.clone();
|
||||
stmtCloned.setName(x.getName().clone());
|
||||
acceptCreateTable((SQLCreateTableStatement) stmtCloned);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return acceptCreateTable((SQLCreateTableStatement) x);
|
||||
}
|
||||
|
||||
boolean acceptCreateTable(SQLCreateTableStatement x) {
|
||||
String schemaName = x.getSchema();
|
||||
|
||||
Schema schema = findSchema(schemaName, true);
|
||||
|
||||
SQLSelect select = x.getSelect();
|
||||
if (select != null) {
|
||||
select.accept(createResolveVisitor());
|
||||
|
||||
SQLSelectQueryBlock queryBlock = select.getFirstQueryBlock();
|
||||
if (queryBlock != null) {
|
||||
List<SQLSelectItem> selectList = queryBlock.getSelectList();
|
||||
for (SQLSelectItem selectItem : selectList) {
|
||||
String name = selectItem.computeAlias();
|
||||
SQLDataType dataType = selectItem.computeDataType();
|
||||
SQLColumnDefinition column = new SQLColumnDefinition();
|
||||
column.setName(name);
|
||||
column.setDataType(dataType);
|
||||
column.setDbType(dbType);
|
||||
x.getTableElementList().add(column);
|
||||
}
|
||||
x.setSelect(null);
|
||||
}
|
||||
}
|
||||
|
||||
x.setSchema(null);
|
||||
|
||||
String name = x.computeName();
|
||||
SchemaObject table = schema.findTableOrView(name);
|
||||
if (table != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
table = new SchemaObjectImpl(name, SchemaObjectType.Table, x);
|
||||
String name_lower = SQLUtils.normalize(name).toLowerCase();
|
||||
schema.objects.put(name_lower, table);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean acceptDropTable(SQLDropTableStatement x) {
|
||||
for (SQLExprTableSource table : x.getTableSources()) {
|
||||
String schemaName = table.getSchema();
|
||||
Schema schema = findSchema(schemaName, false);
|
||||
if (schema == null) {
|
||||
continue;
|
||||
}
|
||||
String name = table.getName().getSimpleName();
|
||||
String name_lower = SQLUtils.normalize(name).toLowerCase();
|
||||
schema.objects.remove(name_lower);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean acceptView(SQLCreateViewStatement x) {
|
||||
String schemaName = x.getSchema();
|
||||
|
||||
Schema schema = findSchema(schemaName, true);
|
||||
|
||||
String name = x.computeName();
|
||||
SchemaObject view = schema.findTableOrView(name);
|
||||
if (view != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.View, x);
|
||||
String name_lower = SQLUtils.normalize(name).toLowerCase();
|
||||
schema.objects.put(name_lower, object);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean acceptCreateIndex(SQLCreateIndexStatement x) {
|
||||
String schemaName = x.getSchema();
|
||||
|
||||
Schema schema = findSchema(schemaName, true);
|
||||
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Index);
|
||||
String name_lower = SQLUtils.normalize(name).toLowerCase();
|
||||
schema.objects.put(name_lower, object);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean acceptCreateFunction(SQLCreateFunctionStatement x) {
|
||||
String schemaName = x.getSchema();
|
||||
Schema schema = findSchema(schemaName, true);
|
||||
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Function);
|
||||
String name_lower = SQLUtils.normalize(name).toLowerCase();
|
||||
schema.functions.put(name_lower, object);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean acceptAlterTable(SQLAlterTableStatement x) {
|
||||
String schemaName = x.getSchema();
|
||||
Schema schema = findSchema(schemaName, true);
|
||||
|
||||
SchemaObject object = schema.findTable(x.getTableName());
|
||||
if (object != null) {
|
||||
SQLCreateTableStatement stmt = (SQLCreateTableStatement) object.getStatement();
|
||||
if (stmt != null) {
|
||||
stmt.apply(x);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean acceptCreateSequence(SQLCreateSequenceStatement x) {
|
||||
String schemaName = x.getSchema();
|
||||
Schema schema = findSchema(schemaName, true);
|
||||
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Sequence);
|
||||
String name_lower = SQLUtils.normalize(name).toLowerCase();
|
||||
schema.objects.put(name_lower, object);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean acceptDropSequence(SQLDropSequenceStatement x) {
|
||||
String schemaName = x.getSchema();
|
||||
Schema schema = findSchema(schemaName, true);
|
||||
|
||||
String name = x.getName().getSimpleName();
|
||||
String name_lower = SQLUtils.normalize(name).toLowerCase();
|
||||
schema.objects.remove(name_lower);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+20
-2
@@ -456,12 +456,30 @@ public class MySqlCreateTable_showColumns_repository_test extends MysqlTest {
|
||||
"\tc_longblob longblob\n" +
|
||||
")", repository.console("show create table test5"));
|
||||
|
||||
repository.console("CREATE TABLE test6 as select a.id, c_tinyint, 'a' f3, 3 f4 from test2 a");
|
||||
repository.console("CREATE TABLE sc01.test6 as select a.id, c_tinyint, 'a' f3, 3 f4 from test2 a");
|
||||
assertEquals("CREATE TABLE test6 (\n" +
|
||||
"\tid bigint(20),\n" +
|
||||
"\tc_tinyint tinyint(4),\n" +
|
||||
"\tf3 varchar,\n" +
|
||||
"\tf4 bigint\n" +
|
||||
")", repository.console("show create table test6"));
|
||||
")", repository.console("show create table sc01.test6"));
|
||||
|
||||
assertEquals("test1\n" +
|
||||
"test2\n" +
|
||||
"test3\n" +
|
||||
"test4\n" +
|
||||
"test5\n", repository.console("show tables"));
|
||||
|
||||
assertEquals("test1\n" +
|
||||
"test2\n" +
|
||||
"test3\n" +
|
||||
"test4\n" +
|
||||
"test5\n", repository.console("show tables"));
|
||||
|
||||
assertEquals("test6\n", repository.console("show tables from sc01"));
|
||||
|
||||
repository.console("DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `sc01`.`test6`;");
|
||||
|
||||
assertEquals("\n", repository.console("show tables from sc01"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user