improve mysql sql parser ddl support

This commit is contained in:
wenshao
2012-11-17 15:44:02 +08:00
parent 340a7a945e
commit f39ca8ac14
20 changed files with 535 additions and 52 deletions
@@ -0,0 +1,27 @@
package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLAlterTableAddPrimaryKey extends SQLObjectImpl implements SQLAlterTableItem {
private static final long serialVersionUID = 1L;
private SQLPrimaryKey primaryKey;
public SQLPrimaryKey getPrimaryKey() {
return primaryKey;
}
public void setPrimaryKey(SQLPrimaryKey primaryKey) {
this.primaryKey = primaryKey;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, primaryKey);
}
visitor.endVisit(this);
}
}
@@ -0,0 +1,29 @@
package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLAlterTableDropIndex extends SQLObjectImpl implements SQLAlterTableItem {
private static final long serialVersionUID = 1L;
private SQLName indexName;
public SQLName getIndexName() {
return indexName;
}
public void setIndexName(SQLName indexName) {
this.indexName = indexName;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, indexName);
}
visitor.endVisit(this);
}
}
@@ -16,6 +16,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;
@SuppressWarnings("serial")
public class MySqlPrimaryKey extends MySqlKey implements SQLPrimaryKey {
@@ -24,4 +25,11 @@ public class MySqlPrimaryKey extends MySqlKey implements SQLPrimaryKey {
}
protected void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.getName());
acceptChild(visitor, this.getColumns());
}
visitor.endVisit(this);
}
}
@@ -25,14 +25,33 @@ public class MySqlAlterTableAddColumn extends SQLAlterTableAddColumn implements
private static final long serialVersionUID = 1L;
private SQLName after;
private SQLName firstColumn;
private SQLName afterColumn;
public SQLName getAfter() {
return after;
private boolean first;
public SQLName getFirstColumn() {
return firstColumn;
}
public void setAfter(SQLName after) {
this.after = after;
public void setFirstColumn(SQLName first) {
this.firstColumn = first;
}
public boolean isFirst() {
return first;
}
public void setFirst(boolean first) {
this.first = first;
}
public SQLName getAfterColumn() {
return afterColumn;
}
public void setAfterColumn(SQLName after) {
this.afterColumn = after;
}
@Override
@@ -47,6 +66,9 @@ public class MySqlAlterTableAddColumn extends SQLAlterTableAddColumn implements
public void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, getColumns());
acceptChild(visitor, firstColumn);
acceptChild(visitor, afterColumn);
}
visitor.endVisit(this);
}
@@ -15,6 +15,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;
@@ -29,16 +30,38 @@ public class MySqlAlterTableChangeColumn extends MySqlObjectImpl implements SQLA
private SQLColumnDefinition newColumnDefinition;
private Boolean first;
private boolean first;
private SQLExpr firstColumn;
private SQLExpr afterColumn;
@Override
public void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, columnName);
acceptChild(visitor, newColumnDefinition);
acceptChild(visitor, firstColumn);
acceptChild(visitor, afterColumn);
}
}
public SQLExpr getFirstColumn() {
return firstColumn;
}
public void setFirstColumn(SQLExpr firstColumn) {
this.firstColumn = firstColumn;
}
public SQLExpr getAfterColumn() {
return afterColumn;
}
public void setAfterColumn(SQLExpr afterColumn) {
this.afterColumn = afterColumn;
}
public SQLName getColumnName() {
return columnName;
}
@@ -55,11 +78,11 @@ public class MySqlAlterTableChangeColumn extends MySqlObjectImpl implements SQLA
this.newColumnDefinition = newColumnDefinition;
}
public Boolean getFirst() {
public boolean isFirst() {
return first;
}
public void setFirst(Boolean first) {
public void setFirst(boolean first) {
this.first = first;
}
@@ -21,7 +21,6 @@ import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLTableConstaint;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlKey;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlPrimaryKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPartitionByKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
@@ -218,31 +217,11 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
}
if (lexer.token() == (Token.PRIMARY)) {
lexer.nextToken();
accept(Token.KEY);
MySqlPrimaryKey primaryKey = new MySqlPrimaryKey();
if (identifierEquals("USING")) {
lexer.nextToken();
primaryKey.setIndexType(lexer.stringVal());
lexer.nextToken();
}
accept(Token.LPAREN);
for (;;) {
primaryKey.getColumns().add(this.exprParser.expr());
if (!(lexer.token() == (Token.COMMA))) {
break;
} else {
lexer.nextToken();
}
}
accept(Token.RPAREN);
return primaryKey;
return (SQLTableConstaint) this.exprParser.parsePrimaryKey();
}
throw new ParserException("TODO");
}
}
@@ -27,6 +27,8 @@ import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlPrimaryKey;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBinaryExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
@@ -606,5 +608,31 @@ public class MySqlExprParser extends SQLExprParser {
return null;
}
@Override
public SQLPrimaryKey parsePrimaryKey() {
accept(Token.PRIMARY);
accept(Token.KEY);
MySqlPrimaryKey primaryKey = new MySqlPrimaryKey();
if (identifierEquals("USING")) {
lexer.nextToken();
primaryKey.setIndexType(lexer.stringVal());
lexer.nextToken();
}
accept(Token.LPAREN);
for (;;) {
primaryKey.getColumns().add(this.expr());
if (!(lexer.token() == (Token.COMMA))) {
break;
} else {
lexer.nextToken();
}
}
accept(Token.RPAREN);
return primaryKey;
}
}
@@ -26,13 +26,16 @@ import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddPrimaryKey;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropColumnItem;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropIndex;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateDatabaseStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
@@ -2095,7 +2098,14 @@ public class MySqlStatementParser extends SQLStatementParser {
item.getColumns().add(columnDef);
if (identifierEquals("AFTER")) {
lexer.nextToken();
item.setAfter(this.exprParser.name());
item.setAfterColumn(this.exprParser.name());
} else if (identifierEquals("FIRST")) {
lexer.nextToken();
if (lexer.token() == Token.IDENTIFIER) {
item.setFirstColumn(this.exprParser.name());
} else {
item.setFirst(true);
}
}
stmt.getItems().add(item);
} else if (lexer.token() == Token.INDEX) {
@@ -2123,6 +2133,11 @@ public class MySqlStatementParser extends SQLStatementParser {
stmt.getItems().add(item);
} else if (lexer.token() == Token.UNIQUE) {
lexer.nextToken();
if (lexer.token() == Token.INDEX) {
lexer.nextToken();
}
MySqlAlterTableAddUnique item = new MySqlAlterTableAddUnique();
if (lexer.token() == Token.LPAREN) {
@@ -2143,6 +2158,11 @@ public class MySqlStatementParser extends SQLStatementParser {
}
accept(Token.RPAREN);
stmt.getItems().add(item);
} else if (lexer.token() == Token.PRIMARY) {
SQLPrimaryKey primaryKey = ((MySqlExprParser) this.exprParser).parsePrimaryKey();
SQLAlterTableAddPrimaryKey item = new SQLAlterTableAddPrimaryKey();
item.setPrimaryKey(primaryKey);
stmt.getItems().add(item);
} else if (lexer.token() == Token.KEY) {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
@@ -2158,7 +2178,7 @@ public class MySqlStatementParser extends SQLStatementParser {
item.getColumns().add(columnDef);
if (identifierEquals("AFTER")) {
lexer.nextToken();
item.setAfter(this.exprParser.name());
item.setAfterColumn(this.exprParser.name());
}
stmt.getItems().add(item);
}
@@ -2172,24 +2192,36 @@ public class MySqlStatementParser extends SQLStatementParser {
MySqlAlterTableChangeColumn item = new MySqlAlterTableChangeColumn();
item.setColumnName(this.exprParser.name());
item.setNewColumnDefinition(this.exprParser.parseColumn());
if (identifierEquals("FIRST")) {
if (identifierEquals("AFTER")) {
lexer.nextToken();
item.setFirst(true);
} else if (identifierEquals("AFTER")) {
item.setAfterColumn(this.exprParser.name());
} else if (identifierEquals("FIRST")) {
lexer.nextToken();
item.setFirst(false);
if (lexer.token() == Token.IDENTIFIER) {
item.setFirstColumn(this.exprParser.name());
} else {
item.setFirst(true);
}
}
stmt.getItems().add(item);
} else if (identifierEquals("MODIFY")) {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
} else if (lexer.token() == Token.DROP) {
lexer.nextToken();
if (identifierEquals("COLUMN")) {
if (lexer.token() == Token.INDEX) {
lexer.nextToken();
SQLName indexName = this.exprParser.name();
SQLAlterTableDropIndex item = new SQLAlterTableDropIndex();
item.setIndexName(indexName);
stmt.getItems().add(item);
} else {
if (identifierEquals("COLUMN")) {
lexer.nextToken();
}
SQLAlterTableDropColumnItem item = new SQLAlterTableDropColumnItem();
item.setColumnName(this.exprParser.name());
stmt.getItems().add(item);
}
SQLAlterTableDropColumnItem item = new SQLAlterTableDropColumnItem();
item.setColumnName(this.exprParser.name());
stmt.getItems().add(item);
} else if (identifierEquals("DISABLE")) {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
} else if (identifierEquals("ENABLE")) {
@@ -2264,9 +2264,14 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
public boolean visit(MySqlAlterTableAddColumn x) {
print("ADD COLUMN ");
printAndAccept(x.getColumns(), ", ");
if (x.getAfter() != null) {
if (x.getFirstColumn() != null) {
print(" FIRST ");
x.getFirstColumn().accept(this);
} else if (x.getAfterColumn() != null) {
print(" AFTER ");
x.getAfter().accept(this);
x.getAfterColumn().accept(this);
} else if (x.isFirst()) {
print(" FIRST");
}
return false;
}
@@ -2516,12 +2521,14 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
x.getColumnName().accept(this);
print(' ');
x.getNewColumnDefinition().accept(this);
if (x.getFirst() != null) {
if (x.getFirst().booleanValue()) {
print(" FIRST");
} else {
print(" AFTER");
}
if (x.getFirstColumn() != null) {
print(" FIRST ");
x.getFirstColumn().accept(this);
} else if (x.getAfterColumn() != null) {
print(" AFTER ");
x.getAfterColumn().accept(this);
} else if (x.isFirst()) {
print(" FIRST");
}
return false;
@@ -1144,7 +1144,7 @@ public class SQLExprParser extends SQLParser {
accept(Token.SET);
if (lexer.token() != Token.IDENTIFIER) {
if (lexer.token() != Token.IDENTIFIER && lexer.token() != Token.LITERAL_CHARS) {
throw new ParserException();
}
charType.setCharSetName(lexer.stringVal());
@@ -74,6 +74,8 @@ import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddPrimaryKey;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropIndex;
import com.alibaba.druid.sql.ast.statement.SQLCreateDatabaseStatement;
import com.alibaba.druid.sql.ast.statement.SQLReleaseSavePointStatement;
import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement;
@@ -1145,4 +1147,18 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter {
x.getName().accept(this);
return false;
}
@Override
public boolean visit(SQLAlterTableDropIndex x) {
print("DROP INDEX ");
x.getIndexName().accept(this);
return false;
}
@Override
public boolean visit(SQLAlterTableAddPrimaryKey x) {
print("ADD ");
x.getPrimaryKey().accept(this);
return false;
}
}
@@ -53,7 +53,9 @@ import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.NotNullConstraint;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddColumn;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddPrimaryKey;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropColumnItem;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropIndex;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
@@ -352,6 +354,14 @@ public interface SQLASTVisitor {
boolean visit(SQLAlterTableDropColumnItem x);
void endVisit(SQLAlterTableDropColumnItem x);
boolean visit(SQLAlterTableDropIndex x);
void endVisit(SQLAlterTableDropIndex x);
boolean visit(SQLAlterTableAddPrimaryKey x);
void endVisit(SQLAlterTableAddPrimaryKey x);
boolean visit(SQLDropIndexStatement x);
@@ -53,7 +53,9 @@ import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.NotNullConstraint;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddColumn;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddPrimaryKey;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropColumnItem;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropIndex;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
@@ -682,4 +684,24 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
public boolean visit(SQLCreateDatabaseStatement x) {
return true;
}
@Override
public boolean visit(SQLAlterTableDropIndex x) {
return true;
}
@Override
public void endVisit(SQLAlterTableDropIndex x) {
}
@Override
public boolean visit(SQLAlterTableAddPrimaryKey x) {
return true;
}
@Override
public void endVisit(SQLAlterTableAddPrimaryKey x) {
}
}