diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java index 2539118106..ed13064117 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java @@ -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; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableStatement.java index b7071e4981..d633908b7d 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableStatement.java @@ -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; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateFunctionStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateFunctionStatement.java index cbac85f3e2..797aba9770 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateFunctionStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateFunctionStatement.java @@ -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; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateIndexStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateIndexStatement.java index cdcad4d1d6..4b7f1f573b 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateIndexStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateIndexStatement.java @@ -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; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateSequenceStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateSequenceStatement.java index b9d98721d9..976f5a7fb2 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateSequenceStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateSequenceStatement.java @@ -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; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java index 97e299fe62..5c527aa66a 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateTableStatement.java @@ -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)); } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateViewStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateViewStatement.java index 261b3b9627..90d522bc36 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateViewStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateViewStatement.java @@ -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; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDropSequenceStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDropSequenceStatement.java index e0167db33d..e5756f8028 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDropSequenceStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDropSequenceStatement.java @@ -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; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDropTableStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDropTableStatement.java index 7e82d0066e..e9baac6031 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDropTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDropTableStatement.java @@ -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 hints; protected List tableSources = new ArrayList(); @@ -129,4 +132,11 @@ public class SQLDropTableStatement extends SQLStatementImpl implements SQLDDLSta this.temporary = temporary; } + public List getHints() { + return hints; + } + + public void setHints(List hints) { + this.hints = hints; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java index 8b75eee12b..fbc6d57a41 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExprTableSource.java @@ -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 getPartitions() { if (this.partitions == null) { this.partitions = new ArrayList(2); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index 735fb06e5d..48be41c963 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -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 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) { diff --git a/src/main/java/com/alibaba/druid/sql/repository/Schema.java b/src/main/java/com/alibaba/druid/sql/repository/Schema.java index 9468d8e366..c3cb74ad92 100644 --- a/src/main/java/com/alibaba/druid/sql/repository/Schema.java +++ b/src/main/java/com/alibaba/druid/sql/repository/Schema.java @@ -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 objects = new ConcurrentSkipListMap(); - private final Map functions = new ConcurrentSkipListMap(); - - private final SQLASTVisitor visitor; + protected final Map functions = new ConcurrentSkipListMap(); 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 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 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 showTables() { + List tables = new ArrayList(objects.size()); + for (SchemaObject object : objects.values()) { + if (object.getType() == SchemaObjectType.Table) { + tables.add(object.getName()); + } + } + return tables; + } } diff --git a/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java b/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java index 1922ae99ff..eff7133a9a 100644 --- a/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java +++ b/src/main/java/com/alibaba/druid/sql/repository/SchemaRepository.java @@ -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 schemas = new LinkedHashMap(); @@ -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 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 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; + } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlCreateTable_showColumns_repository_test.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlCreateTable_showColumns_repository_test.java index f19f962eb7..99ffafde40 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlCreateTable_showColumns_repository_test.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlCreateTable_showColumns_repository_test.java @@ -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")); } }