mysql parser ddl support

This commit is contained in:
温少
2012-05-16 16:51:03 +08:00
parent af75c60219
commit 953fa70373
13 changed files with 263 additions and 70 deletions
@@ -0,0 +1,56 @@
package com.alibaba.druid.sql.ast.statement;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLStatementImpl;
public class SQLCreateIndexStatement extends SQLStatementImpl implements SQLDDLStatement {
/**
*
*/
private static final long serialVersionUID = 1L;
private SQLName name;
private SQLName table;
private List<SQLSelectOrderByItem> items = new ArrayList<SQLSelectOrderByItem>();
private String type;
public SQLName getTable() {
return table;
}
public void setTable(SQLName table) {
this.table = table;
}
public List<SQLSelectOrderByItem> getItems() {
return items;
}
public void setItems(List<SQLSelectOrderByItem> items) {
this.items = items;
}
public SQLName getName() {
return name;
}
public void setName(SQLName name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
@@ -0,0 +1,37 @@
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class MySqlCreateIndexStatement extends SQLCreateIndexStatement implements MySqlStatement {
/**
*
*/
private static final long serialVersionUID = 1L;
private String using;
public String getUsing() {
return using;
}
public void setUsing(String using) {
this.using = using;
}
protected void accept0(SQLASTVisitor visitor) {
accept0((MySqlASTVisitor) visitor);
}
@Override
public void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, getName());
acceptChild(visitor, getTable());
acceptChild(visitor, getItems());
}
visitor.endVisit(this);
}
}
@@ -31,6 +31,7 @@ import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
@@ -41,6 +42,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableAddColum
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlBinlogStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateIndexStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement;
@@ -212,6 +214,10 @@ public class MySqlStatementParser extends SQLStatementParser {
MySqlCreateTableParser parser = new MySqlCreateTableParser(lexer);
return parser.parseCrateTable(false);
}
if (lexer.token() == Token.UNIQUE || lexer.token() == Token.INDEX || identifierEquals("FULLTEXT") || identifierEquals("SPATIAL")) {
return parseCreateIndex();
}
if (identifierEquals("USER")) {
return parseCreateUser();
@@ -219,8 +225,64 @@ public class MySqlStatementParser extends SQLStatementParser {
throw new ParserException("TODO " + lexer.token());
}
public SQLStatement parseCreateIndex() throws ParserException {
MySqlCreateIndexStatement stmt = new MySqlCreateIndexStatement();
if (lexer.token() == Token.UNIQUE) {
stmt.setType("UNIQUE");
lexer.nextToken();
} else if (identifierEquals("FULLTEXT")) {
stmt.setType("FULLTEXT");
lexer.nextToken();
} else if (identifierEquals("SPATIAL")) {
stmt.setType("SPATIAL");
lexer.nextToken();
}
accept(Token.INDEX);
stmt.setName(this.exprParser.name());
if (identifierEquals("USING")) {
lexer.nextToken();
if (identifierEquals("BTREE")) {
stmt.setType("BTREE");
lexer.nextToken();
} else if (identifierEquals("HASH")) {
stmt.setType("HASH");
lexer.nextToken();
} else {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
}
accept(Token.ON);
stmt.setTable(this.exprParser.name());
accept(Token.LPAREN);
for (;;) {
SQLSelectOrderByItem item = this.exprParser.parseSelectOrderByItem();
stmt.getItems().add(item);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
accept(Token.RPAREN);
return stmt;
}
public SQLStatement parseCreateUser() throws ParserException {
if (lexer.token() == Token.CREATE) {
lexer.nextToken();
}
acceptIdentifier("USER");
MySqlCreateUserStatement stmt = new MySqlCreateUserStatement();
@@ -29,6 +29,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableAddColum
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlBinlogStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateIndexStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement;
@@ -426,4 +427,8 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
boolean visit(MySqlAlterTableAddColumn x);
void endVisit(MySqlAlterTableAddColumn x);
boolean visit(MySqlCreateIndexStatement x);
void endVisit(MySqlCreateIndexStatement x);
}
@@ -14,6 +14,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableAddColum
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlBinlogStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateIndexStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement.UserSpecification;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
@@ -926,4 +927,14 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements
public void endVisit(MySqlAlterTableAddColumn x) {
}
@Override
public boolean visit(MySqlCreateIndexStatement x) {
return true;
}
@Override
public void endVisit(MySqlCreateIndexStatement x) {
}
}
@@ -46,6 +46,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableAddColum
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlBinlogStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateIndexStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement.UserSpecification;
@@ -2210,4 +2211,34 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
@Override
public boolean visit(MySqlCreateIndexStatement x) {
print("CREATE ");
if (x.getType() != null) {
print(x.getType());
print(" ");
}
print("INDEX ");
if (x.getUsing() != null) {
print("USING ");
print(x.getUsing());
print(' ');
}
x.getName().accept(this);
print(" ON ");
x.getTable().accept(this);
print(" (");
printAndAccept(x.getItems(), ", ");
print(")");
return false;
}
@Override
public void endVisit(MySqlCreateIndexStatement x) {
}
}
@@ -23,6 +23,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableAddColum
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlBinlogStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateIndexStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement.UserSpecification;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
@@ -989,4 +990,14 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
public void endVisit(MySqlAlterTableAddColumn x) {
}
@Override
public boolean visit(MySqlCreateIndexStatement x) {
return false;
}
@Override
public void endVisit(MySqlCreateIndexStatement x) {
}
}
@@ -1,34 +1,32 @@
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import java.util.ArrayList;
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.SQLCreateIndexStatement;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class OracleCreateIndexStatement extends OracleStatementImpl {
public class OracleCreateIndexStatement extends SQLCreateIndexStatement implements OracleDDLStatement {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
private SQLName name;
private boolean online = false;
private SQLName table;
private boolean indexOnlyTopLevel = false;
private List<SQLSelectOrderByItem> items = new ArrayList<SQLSelectOrderByItem>();
private boolean noParallel;
private SQLName tablespace;
private SQLExpr parallel;
private Type type;
private SQLName tablespace;
private boolean online = false;
public SQLName getTablespace() {
return tablespace;
}
private boolean indexOnlyTopLevel = false;
private boolean noParallel;
private SQLExpr parallel;
public void setTablespace(SQLName tablespace) {
this.tablespace = tablespace;
}
public SQLExpr getParallel() {
return parallel;
@@ -46,14 +44,6 @@ public class OracleCreateIndexStatement extends OracleStatementImpl {
this.noParallel = noParallel;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public boolean isIndexOnlyTopLevel() {
return indexOnlyTopLevel;
}
@@ -62,53 +52,25 @@ public class OracleCreateIndexStatement extends OracleStatementImpl {
this.indexOnlyTopLevel = indexOnlyTopLevel;
}
protected void accept0(SQLASTVisitor visitor) {
accept0((OracleASTVisitor) visitor);
}
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, name);
acceptChild(visitor, table);
acceptChild(visitor, items);
acceptChild(visitor, tablespace);
acceptChild(visitor, getName());
acceptChild(visitor, getTable());
acceptChild(visitor, getItems());
acceptChild(visitor, getTablespace());
acceptChild(visitor, parallel);
}
visitor.endVisit(this);
}
public static enum Type {
UNIQUE, BITMAP
}
public SQLName getName() {
return name;
}
public void setName(SQLName name) {
this.name = name;
}
public SQLName getTable() {
return table;
}
public void setTable(SQLName table) {
this.table = table;
}
public List<SQLSelectOrderByItem> getItems() {
return items;
}
public void setItems(List<SQLSelectOrderByItem> items) {
this.items = items;
}
public SQLName getTablespace() {
return tablespace;
}
public void setTablespace(SQLName tablespace) {
this.tablespace = tablespace;
}
// public static enum Type {
// UNIQUE, BITMAP
// }
public boolean isOnline() {
return online;
@@ -1483,10 +1483,10 @@ public class OracleStatementParser extends SQLStatementParser {
OracleCreateIndexStatement stmt = new OracleCreateIndexStatement();
if (lexer.token() == Token.UNIQUE) {
stmt.setType(OracleCreateIndexStatement.Type.UNIQUE);
stmt.setType("UNIQUE");
lexer.nextToken();
} else if (identifierEquals("BITMAP")) {
stmt.setType(OracleCreateIndexStatement.Type.BITMAP);
stmt.setType("BITMAP");
lexer.nextToken();
}
@@ -16,7 +16,6 @@
package com.alibaba.druid.sql.dialect.oracle.visitor;
import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddColumn;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
@@ -2180,11 +2180,13 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
@Override
public boolean visit(OracleCreateIndexStatement x) {
print("CREATE INDEX ");
print("CREATE ");
if (x.getType() != null) {
print(x.getType().name());
print(x.getType());
print(" ");
}
print("INDEX ");
x.getName().accept(this);
print(" ON ");
@@ -11,7 +11,6 @@ import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddColumn;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
@@ -81,6 +81,24 @@ public class DDLParserTest extends TestCase {
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("CREATE TEMPORARY TABLE IF NOT EXISTS tb_name (\n\tfid int\n)", output);
}
public void test_createTable_1() throws Exception {
String sql = "crEate tabLe if not exists tb_name (fid int)";
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement stmt = parser.parseStatementList().get(0);
parser.match(Token.EOF);
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("CREATE TABLE IF NOT EXISTS tb_name (\n\tfid int\n)", output);
}
public void test_createIndex_0() throws Exception {
String sql = "create index `idx1` ON tb1 (`fname` ASC) ;";
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement stmt = parser.parseStatementList().get(0);
parser.match(Token.EOF);
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("CREATE INDEX `idx1` ON tb1 (`fname` ASC)", output);
}
// public void testDDLStmt() throws Exception {
// String sql = "alTer ignore table tb_name";