improved sql parser.

This commit is contained in:
wenshao
2017-08-01 17:15:04 +08:00
parent f505f76b5c
commit 512b8dbabd
17 changed files with 734 additions and 80 deletions
@@ -16,6 +16,7 @@
package com.alibaba.druid.sql.ast.expr;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLCharExpr extends SQLTextLiteralExpr implements SQLValuableExpr{
@@ -30,13 +31,11 @@ public class SQLCharExpr extends SQLTextLiteralExpr implements SQLValuableExpr{
@Override
public void output(StringBuffer buf) {
if ((this.text == null) || (this.text.length() == 0)) {
buf.append("NULL");
} else {
buf.append("'");
buf.append(this.text.replaceAll("'", "''"));
buf.append("'");
}
output((Appendable) buf);
}
public void output(Appendable buf) {
this.accept(new SQLASTOutputVisitor(buf));
}
protected void accept0(SQLASTVisitor visitor) {
@@ -16,6 +16,7 @@
package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -35,6 +36,20 @@ public class SQLAlterTableRename extends SQLObjectImpl implements SQLAlterTableI
return to;
}
public SQLName getToName() {
if (to == null) {
return null;
}
SQLExpr expr = to.expr;
if (expr instanceof SQLName) {
return (SQLName) expr;
}
return null;
}
public void setTo(SQLExprTableSource to) {
if (to != null) {
to.setParent(this);
@@ -96,6 +96,14 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen
return name;
}
public String getNameAsString() {
if (name == null) {
return null;
}
return name.toString();
}
public void setName(SQLName name) {
this.name = name;
}
@@ -26,7 +26,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.MySqlKey;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlUnique;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlShowColumnOutpuVisitor;
import com.alibaba.druid.util.ListDG;
import com.alibaba.druid.util.lang.Consumer;
@@ -263,27 +262,32 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
public SQLTableElement findIndex(String columnName) {
for (SQLTableElement element : tableElementList) {
List<SQLExpr> keyColumns = null;
if (element instanceof SQLUniqueConstraint) {
SQLUniqueConstraint unique = (SQLUniqueConstraint) element;
keyColumns = unique.getColumns();
for (SQLExpr columnExpr : unique.getColumns()) {
if (columnExpr instanceof SQLIdentifierExpr) {
String keyColumName = ((SQLIdentifierExpr) columnExpr).getName();
keyColumName = SQLUtils.normalize(keyColumName);
if (keyColumName.equalsIgnoreCase(columnName)) {
return element;
}
}
}
} else if (element instanceof MySqlTableIndex) {
keyColumns = ((MySqlTableIndex) element).getColumns();
}
if (keyColumns == null) {
continue;
}
for (SQLExpr columnExpr : keyColumns) {
if (columnExpr instanceof SQLIdentifierExpr) {
String keyColumName = ((SQLIdentifierExpr) columnExpr).getName();
keyColumName = SQLUtils.normalize(keyColumName);
if (keyColumName.equalsIgnoreCase(columnName)) {
return element;
List<SQLSelectOrderByItem> indexColumns = ((MySqlTableIndex) element).getColumns();
for (SQLSelectOrderByItem orderByItem : indexColumns) {
SQLExpr columnExpr = orderByItem.getExpr();
if (columnExpr instanceof SQLIdentifierExpr) {
String keyColumName = ((SQLIdentifierExpr) columnExpr).getName();
keyColumName = SQLUtils.normalize(keyColumName);
if (keyColumName.equalsIgnoreCase(columnName)) {
return element;
}
}
}
}
}
return null;
@@ -529,20 +533,153 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
int applyCount = 0;
for (SQLAlterTableItem item : alter.getItems()) {
if (item instanceof SQLAlterTableDropColumnItem) {
if (apply((SQLAlterTableDropColumnItem) item)) {
applyCount++;
}
} else if (item instanceof SQLAlterTableAddColumn) {
if (apply((SQLAlterTableAddColumn) item)) {
applyCount++;
}
if (alterApply(item)) {
applyCount++;
}
}
return applyCount > 0;
}
protected boolean alterApply(SQLAlterTableItem item) {
if (item instanceof SQLAlterTableDropColumnItem) {
return apply((SQLAlterTableDropColumnItem) item);
} else if (item instanceof SQLAlterTableAddColumn) {
return apply((SQLAlterTableAddColumn) item);
} else if (item instanceof SQLAlterTableAddConstraint) {
return apply((SQLAlterTableAddConstraint) item);
} else if (item instanceof SQLAlterTableDropPrimaryKey) {
return apply((SQLAlterTableDropPrimaryKey) item);
} else if (item instanceof SQLAlterTableDropIndex) {
return apply((SQLAlterTableDropIndex) item);
} else if (item instanceof SQLAlterTableDropConstraint) {
return apply((SQLAlterTableDropConstraint) item);
} else if (item instanceof SQLAlterTableDropKey) {
return apply((SQLAlterTableDropKey) item);
} else if (item instanceof SQLAlterTableDropForeignKey) {
return apply((SQLAlterTableDropForeignKey) item);
} else if (item instanceof SQLAlterTableRename) {
return apply((SQLAlterTableRename) item);
} else if (item instanceof SQLAlterTableRenameColumn) {
return apply((SQLAlterTableRenameColumn) item);
}
return false;
}
// SQLAlterTableRenameColumn
private boolean apply(SQLAlterTableRenameColumn item) {
int columnIndex = columnIndexOf(item.getColumn());
if (columnIndex == -1) {
return false;
}
SQLColumnDefinition column = (SQLColumnDefinition) tableElementList.get(columnIndex);
column.setName(item.getTo().clone());
return true;
}
private boolean apply(SQLAlterTableRename item) {
SQLName name = item.getToName();
if (name == null) {
return false;
}
this.setName(name.clone());
return true;
}
private boolean apply(SQLAlterTableDropForeignKey item) {
for (int i = tableElementList.size() - 1; i >= 0; i--) {
SQLTableElement e = tableElementList.get(i);
if (e instanceof SQLUniqueConstraint) {
SQLForeignKeyConstraint fk = (SQLForeignKeyConstraint) e;
if (SQLUtils.nameEquals(fk.getName(), item.getIndexName())) {
tableElementList.remove(i);
return true;
}
}
}
return false;
}
private boolean apply(SQLAlterTableDropKey item) {
for (int i = tableElementList.size() - 1; i >= 0; i--) {
SQLTableElement e = tableElementList.get(i);
if (e instanceof SQLUniqueConstraint) {
SQLUniqueConstraint unique = (SQLUniqueConstraint) e;
if (SQLUtils.nameEquals(unique.getName(), item.getKeyName())) {
tableElementList.remove(i);
return true;
}
}
}
return false;
}
private boolean apply(SQLAlterTableDropConstraint item) {
for (int i = tableElementList.size() - 1; i >= 0; i--) {
SQLTableElement e = tableElementList.get(i);
if (e instanceof SQLConstraint) {
SQLConstraint constraint = (SQLConstraint) e;
if (SQLUtils.nameEquals(constraint.getName(), item.getConstraintName())) {
tableElementList.remove(i);
return true;
}
}
}
return false;
}
private boolean apply(SQLAlterTableDropIndex item) {
for (int i = tableElementList.size() - 1; i >= 0; i--) {
SQLTableElement e = tableElementList.get(i);
if (e instanceof SQLUniqueConstraint) {
SQLUniqueConstraint unique = (SQLUniqueConstraint) e;
if (SQLUtils.nameEquals(unique.getName(), item.getIndexName())) {
tableElementList.remove(i);
return true;
}
} else if (e instanceof MySqlTableIndex) {
MySqlTableIndex tableIndex = (MySqlTableIndex) e;
if (SQLUtils.nameEquals(tableIndex.getName(), item.getIndexName())) {
tableElementList.remove(i);
return true;
}
}
}
return false;
}
private boolean apply(SQLAlterTableDropPrimaryKey item) {
for (int i = tableElementList.size() - 1; i >= 0; i--) {
SQLTableElement e = tableElementList.get(i);
if (e instanceof SQLPrimaryKey) {
tableElementList.remove(i);
return true;
}
}
return false;
}
private boolean apply(SQLAlterTableAddConstraint item) {
tableElementList.add((SQLTableElement) item.getConstraint());
return true;
}
private boolean apply(SQLAlterTableDropColumnItem item) {
for (SQLName column : item.getColumns()) {
String columnName = column.getSimpleName();
@@ -583,7 +720,7 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
return true;
}
private int columnIndexOf(SQLName column) {
protected int columnIndexOf(SQLName column) {
if (column == null) {
return -1;
}
@@ -18,7 +18,7 @@ package com.alibaba.druid.sql.dialect.mysql.ast;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
public class MySqlUnique extends MySqlKey implements SQLPrimaryKey {
public class MySqlUnique extends MySqlKey {
public MySqlUnique(){
@@ -30,8 +30,8 @@ public class MySqlAlterTableChangeColumn extends MySqlObjectImpl implements SQLA
private boolean first;
private SQLExpr firstColumn;
private SQLExpr afterColumn;
private SQLName firstColumn;
private SQLName afterColumn;
@Override
public void accept0(MySqlASTVisitor visitor) {
@@ -44,19 +44,19 @@ public class MySqlAlterTableChangeColumn extends MySqlObjectImpl implements SQLA
}
}
public SQLExpr getFirstColumn() {
public SQLName getFirstColumn() {
return firstColumn;
}
public void setFirstColumn(SQLExpr firstColumn) {
public void setFirstColumn(SQLName firstColumn) {
this.firstColumn = firstColumn;
}
public SQLExpr getAfterColumn() {
public SQLName getAfterColumn() {
return afterColumn;
}
public void setAfterColumn(SQLExpr afterColumn) {
public void setAfterColumn(SQLName afterColumn) {
this.afterColumn = afterColumn;
}
@@ -16,6 +16,7 @@
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableItem;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl;
@@ -27,8 +28,8 @@ public class MySqlAlterTableModifyColumn extends MySqlObjectImpl implements SQLA
private boolean first;
private SQLExpr firstColumn;
private SQLExpr afterColumn;
private SQLName firstColumn;
private SQLName afterColumn;
@Override
public void accept0(MySqlASTVisitor visitor) {
@@ -40,19 +41,19 @@ public class MySqlAlterTableModifyColumn extends MySqlObjectImpl implements SQLA
}
}
public SQLExpr getFirstColumn() {
public SQLName getFirstColumn() {
return firstColumn;
}
public void setFirstColumn(SQLExpr firstColumn) {
public void setFirstColumn(SQLName firstColumn) {
this.firstColumn = firstColumn;
}
public SQLExpr getAfterColumn() {
public SQLName getAfterColumn() {
return afterColumn;
}
public void setAfterColumn(SQLExpr afterColumn) {
public void setAfterColumn(SQLName afterColumn) {
this.afterColumn = afterColumn;
}
@@ -15,6 +15,8 @@
*/
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableItem;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
@@ -22,11 +24,15 @@ import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
public class MySqlAlterTableOption extends MySqlObjectImpl implements SQLAlterTableItem {
private String name;
private Object value;
private SQLObject value;
public MySqlAlterTableOption(String name, Object value){
public MySqlAlterTableOption(String name, String value){
this(name, new SQLIdentifierExpr(value));
}
public MySqlAlterTableOption(String name, SQLObject value){
this.name = name;
this.value = value;
this.setValue(value);
}
public MySqlAlterTableOption(){
@@ -46,11 +52,11 @@ public class MySqlAlterTableOption extends MySqlObjectImpl implements SQLAlterTa
this.name = name;
}
public Object getValue() {
public SQLObject getValue() {
return value;
}
public void setValue(Object value) {
public void setValue(SQLObject value) {
this.value = value;
}
@@ -27,11 +27,10 @@ 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.SQLPartitionBy;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlShowColumnOutpuVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
@@ -192,6 +191,57 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement implement
return false;
}
protected boolean alterApply(SQLAlterTableItem item) {
if (item instanceof MySqlAlterTableAlterColumn) {
return apply((MySqlAlterTableAlterColumn) item);
} else if (item instanceof MySqlAlterTableChangeColumn) {
return apply((MySqlAlterTableChangeColumn) item);
} else if (item instanceof MySqlAlterTableCharacter) {
return apply((MySqlAlterTableCharacter) item);
} else if (item instanceof MySqlAlterTableModifyColumn) {
return apply((MySqlAlterTableModifyColumn) item);
} else if (item instanceof MySqlAlterTableOption) {
return apply((MySqlAlterTableOption) item);
}
return super.alterApply(item);
}
public boolean apply(SQLAlterTableAddIndex x) {
MySqlTableIndex index = new MySqlTableIndex();
index.setName(x.getName());
for (SQLSelectOrderByItem orderByItem : x.getItems()) {
index.addColumn(orderByItem.clone());
}
index.setParent(this);
this.tableElementList.add(index);
return true;
}
public boolean apply(MySqlAlterTableOption item) {
this.tableOptions.put(item.getName(), item.getValue());
return true;
}
public boolean apply(MySqlAlterTableCharacter item) {
SQLExpr charset = item.getCharacterSet();
if (charset != null) {
this.tableOptions.put("CHARACTER SET", charset);
}
SQLExpr collate = item.getCollate();
if (collate != null) {
this.tableOptions.put("COLLATE", collate);
}
return true;
}
public boolean apply(MySqlRenameTableStatement.Item item) {
if (!SQLUtils.nameEquals((SQLName) item.getName(), this.getName())) {
return false;
@@ -199,4 +249,97 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement implement
this.setName((SQLName) item.getTo().clone());
return true;
}
public boolean apply(MySqlAlterTableAlterColumn x) {
int columnIndex = columnIndexOf(x.getColumn());
if (columnIndex == -1) {
return false;
}
SQLExpr defaultExpr = x.getDefaultExpr();
SQLColumnDefinition column = (SQLColumnDefinition) tableElementList.get(columnIndex);
if (x.isDropDefault()) {
column.setDefaultExpr(null);
} else if (defaultExpr != null) {
column.setDefaultExpr(defaultExpr);
}
return true;
}
public boolean apply(MySqlAlterTableChangeColumn item) {
SQLName columnName = item.getColumnName();
int columnIndex = columnIndexOf(columnName);
if (columnIndex == -1) {
return false;
}
int afterIndex = columnIndexOf(item.getAfterColumn());
int beforeIndex = columnIndexOf(item.getFirstColumn());
int insertIndex = -1;
if (beforeIndex != -1) {
insertIndex = beforeIndex;
} else if (afterIndex != -1) {
insertIndex = afterIndex + 1;
}
SQLColumnDefinition column = item.getNewColumnDefinition().clone();
column.setParent(this);
if (insertIndex == -1 || insertIndex == columnIndex) {
tableElementList.set(columnIndex, column);
return true;
} else {
if (insertIndex > columnIndex) {
tableElementList.add(insertIndex, column);
tableElementList.remove(columnIndex);
} else {
tableElementList.remove(columnIndex);
tableElementList.add(insertIndex, column);
}
}
return true;
}
public boolean apply(MySqlAlterTableModifyColumn item) {
SQLColumnDefinition column = item.getNewColumnDefinition().clone();
SQLName columnName = column.getName();
int columnIndex = columnIndexOf(columnName);
if (columnIndex == -1) {
return false;
}
int afterIndex = columnIndexOf(item.getAfterColumn());
int beforeIndex = columnIndexOf(item.getFirstColumn());
int insertIndex = -1;
if (beforeIndex != -1) {
insertIndex = beforeIndex;
} else if (afterIndex != -1) {
insertIndex = afterIndex + 1;
}
column.setParent(this);
if (insertIndex == -1 || insertIndex == columnIndex) {
tableElementList.set(columnIndex, column);
return true;
} else {
if (insertIndex > columnIndex) {
tableElementList.add(insertIndex, column);
tableElementList.remove(columnIndex);
} else {
tableElementList.remove(columnIndex);
tableElementList.add(insertIndex, column);
}
}
return true;
}
public void output(StringBuffer buf) {
this.accept(new MySqlOutputVisitor(buf));
}
}
@@ -16,11 +16,12 @@
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
public class MySqlShowCreateTableStatement extends MySqlStatementImpl implements MySqlShowStatement {
private SQLExpr name;
private SQLName name;
public void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
@@ -29,11 +30,11 @@ public class MySqlShowCreateTableStatement extends MySqlStatementImpl implements
visitor.endVisit(this);
}
public SQLExpr getName() {
public SQLName getName() {
return name;
}
public void setName(SQLExpr name) {
public void setName(SQLName name) {
if (name != null) {
name.setParent(this);
}
@@ -20,6 +20,7 @@ import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
@@ -28,7 +29,7 @@ public class MySqlTableIndex extends MySqlObjectImpl implements SQLTableElement
private SQLName name;
private String indexType;
private List<SQLExpr> columns = new ArrayList<SQLExpr>();
private List<SQLSelectOrderByItem> columns = new ArrayList<SQLSelectOrderByItem>();
public MySqlTableIndex(){
@@ -50,11 +51,11 @@ public class MySqlTableIndex extends MySqlObjectImpl implements SQLTableElement
this.name = name;
}
public List<SQLExpr> getColumns() {
public List<SQLSelectOrderByItem> getColumns() {
return columns;
}
public void addColumn(SQLExpr column) {
public void addColumn(SQLSelectOrderByItem column) {
if (column != null) {
column.setParent(this);
}
@@ -140,7 +140,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
accept(Token.LPAREN);
for (;;) {
idx.addColumn(this.exprParser.expr());
idx.addColumn(this.exprParser.parseSelectOrderByItem());
if (!(lexer.token() == (Token.COMMA))) {
break;
} else {
@@ -2843,7 +2843,7 @@ public class MySqlStatementParser extends SQLStatementParser {
} else if (identifierEquals(AUTO_INCREMENT)) {
lexer.nextToken();
accept(Token.EQ);
stmt.addItem(new MySqlAlterTableOption(AUTO_INCREMENT, lexer.integerValue()));
stmt.addItem(new MySqlAlterTableOption(AUTO_INCREMENT, new SQLIntegerExpr(lexer.integerValue())));
lexer.nextToken();
} else if (identifierEquals(COLLATE2)) {
lexer.nextToken();
@@ -24,8 +24,12 @@ 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.mysql.ast.statement.MySqlCreateTableStatement;
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.util.JdbcConstants;
import java.util.LinkedHashMap;
import java.util.List;
@@ -42,12 +46,18 @@ public class Schema {
private final Map<String, SchemaObject> functions = new ConcurrentSkipListMap<String, SchemaObject>();
private final Schema.SchemaVisitor visitor = new Schema.SchemaVisitor();
private final SQLASTVisitor visitor;
private SchemaRepository repository;
public Schema(SchemaRepository repository) {
this.repository = repository;
if (JdbcConstants.MYSQL.equals(repository.dbType)) {
visitor = new MySqlSchemaVisitor();
} else {
visitor = new OracleSchemaVisitor();
}
}
public String getName() {
@@ -59,7 +69,6 @@ public class Schema {
}
public SchemaObject findTable(String tableName) {
String lowerName = tableName.toLowerCase();
SchemaObject object = objects.get(lowerName);
@@ -109,7 +118,7 @@ public class Schema {
&& object.getType() == SchemaObjectType.Sequence;
}
public class SchemaVisitor extends OracleASTVisitorAdapter {
public class OracleSchemaVisitor extends OracleASTVisitorAdapter {
public boolean visit(SQLDropSequenceStatement x) {
String name = x.getName().getSimpleName();
@@ -175,6 +184,72 @@ public class Schema {
}
}
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) {
visit((SQLCreateTableStatement) x);
return false;
}
public boolean visit(SQLCreateTableStatement x) {
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 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 SchemaObject findTable(SQLTableSource tableSource, String alias) {
if (tableSource instanceof SQLExprTableSource) {
if (alias.equalsIgnoreCase(tableSource.computeAlias())) {
@@ -15,6 +15,7 @@
*/
package com.alibaba.druid.sql.repository;
import com.alibaba.druid.DruidRuntimeException;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
@@ -24,9 +25,14 @@ 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.mysql.ast.statement.MySqlCreateTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCreateTableStatement;
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.io.IOException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
@@ -38,6 +44,15 @@ import java.util.concurrent.ConcurrentSkipListMap;
*/
public class SchemaRepository {
private Schema defaultSchema;
protected String dbType;
public SchemaRepository() {
}
public SchemaRepository(String dbType) {
this.dbType = dbType;
}
private Map<String, Schema> schemas = new LinkedHashMap<String, Schema>();
@@ -136,6 +151,10 @@ public class SchemaRepository {
return getDefaultSchema().findFunction(functionName);
}
public void acceptDDL(String ddl) {
acceptDDL(ddl, dbType);
}
public void acceptDDL(String ddl, String dbType) {
getDefaultSchema().acceptDDL(ddl, dbType);
}
@@ -183,4 +202,53 @@ public class SchemaRepository {
public int getViewCount() {
return getDefaultSchema().getViewCount();
}
public String console(String input) {
try {
StringBuffer buf = new StringBuffer();
List<SQLStatement> stmtList = SQLUtils.parseStatements(input, dbType);
for (SQLStatement stmt : stmtList) {
if (stmt instanceof MySqlShowColumnsStatement) {
MySqlShowColumnsStatement showColumns = ((MySqlShowColumnsStatement) stmt);
SQLName table = showColumns.getTable();
SchemaObject schemaObject = findSchemaObject(table);
MySqlCreateTableStatement createTableStmt = (MySqlCreateTableStatement) schemaObject.getStatement();
createTableStmt.showCoumns(buf);
} else if (stmt instanceof MySqlShowCreateTableStatement) {
MySqlShowCreateTableStatement showCreateTableStmt = (MySqlShowCreateTableStatement) stmt;
SQLName table = showCreateTableStmt.getName();
SchemaObject schemaObject = findSchemaObject(table);
MySqlCreateTableStatement createTableStmt = (MySqlCreateTableStatement) schemaObject.getStatement();
createTableStmt.output(buf);
}
}
return buf.toString();
} catch (IOException ex) {
throw new DruidRuntimeException("exeucte command error.", ex);
}
}
private SchemaObject findSchemaObject(SQLName name) {
if (name instanceof SQLIdentifierExpr) {
return findTable(((SQLIdentifierExpr) name).getName());
}
if (name instanceof SQLPropertyExpr) {
SQLPropertyExpr propertyExpr = (SQLPropertyExpr) name;
String schema = propertyExpr.getOwnernName();
String table = propertyExpr.getName();
Schema schemaObj = findSchema(schema);
if (schemaObj == null) {
return null;
}
return schemaObj.findTable(table);
}
return null;
}
}
@@ -767,6 +767,18 @@ public final class JdbcUtils implements JdbcConstants {
}
}
public static List<String> showTables(Connection conn, String dbType) throws SQLException {
if (JdbcConstants.MYSQL.equals(dbType)) {
return MySqlUtils.showTables(conn);
}
if (JdbcConstants.ORACLE.equals(dbType)) {
return OracleUtils.showTables(conn);
}
throw new SQLException("show tables dbType not support for " + dbType);
}
public static String getCreateTableScript(Connection conn, String dbType) throws SQLException {
return getCreateTableScript(conn, dbType, true, true);
}