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:
@@ -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(){
|
||||
|
||||
|
||||
+6
-6
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+7
-6
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+11
-5
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+146
-3
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -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);
|
||||
}
|
||||
|
||||
+4
-3
@@ -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);
|
||||
}
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user