From 2b2b4a587330e3987b5d64d6c73af22667d08193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Wed, 16 May 2012 14:56:56 +0800 Subject: [PATCH] refactor --- .../sql/ast/statement/SQLAlterTableItem.java | 7 + .../ast/statement/SQLAlterTableStatement.java | 31 ++++ .../statement/MySqlAlterTableStatement.java | 8 + .../mysql/parser/MySqlStatementParser.java | 5 + .../oracle/ast/stmt/OracleAlterTableItem.java | 3 +- .../ast/stmt/OracleAlterTableStatement.java | 44 ++---- .../oracle/visitor/OracleOutputVisitor.java | 4 +- .../druid/sql/parser/SQLStatementParser.java | 12 +- .../druid/bvt/sql/cobar/DDLParserTest.java | 149 ++++++++++++++++++ 9 files changed, 228 insertions(+), 35 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableItem.java create mode 100644 src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableStatement.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlAlterTableStatement.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/cobar/DDLParserTest.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableItem.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableItem.java new file mode 100644 index 0000000000..4e4a8684ae --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableItem.java @@ -0,0 +1,7 @@ +package com.alibaba.druid.sql.ast.statement; + +import com.alibaba.druid.sql.ast.SQLObject; + +public interface SQLAlterTableItem extends SQLObject { + +} 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 new file mode 100644 index 0000000000..77cc5ac99f --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLAlterTableStatement.java @@ -0,0 +1,31 @@ +package com.alibaba.druid.sql.ast.statement; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLStatementImpl; + +public class SQLAlterTableStatement extends SQLStatementImpl { + + private static final long serialVersionUID = 1L; + + private SQLExprTableSource tableSource; + private List items = new ArrayList(); + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + public SQLExprTableSource getTableSource() { + return tableSource; + } + + public void setTableSource(SQLExprTableSource tableSource) { + this.tableSource = tableSource; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlAlterTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlAlterTableStatement.java new file mode 100644 index 0000000000..2430569058 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlAlterTableStatement.java @@ -0,0 +1,8 @@ +package com.alibaba.druid.sql.dialect.mysql.ast.statement; + + +public class MySqlAlterTableStatement extends MySqlStatementImpl { + + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index 9ed736b79b..961842d6fc 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -1785,4 +1785,9 @@ public class MySqlStatementParser extends SQLStatementParser { return null; } + + public SQLSetStatement parseAlter() { + accept(Token.ALTER); + throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableItem.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableItem.java index f0d8d50866..ff6c7dcda7 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableItem.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableItem.java @@ -1,8 +1,9 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; +import com.alibaba.druid.sql.ast.statement.SQLAlterTableItem; import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl; -public abstract class OracleAlterTableItem extends OracleSQLObjectImpl { +public abstract class OracleAlterTableItem extends OracleSQLObjectImpl implements SQLAlterTableItem { private static final long serialVersionUID = 1L; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableStatement.java index 977f7bd741..012d903bf0 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleAlterTableStatement.java @@ -1,26 +1,27 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; -import java.util.ArrayList; -import java.util.List; - import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; -public class OracleAlterTableStatement extends OracleStatementImpl { +public class OracleAlterTableStatement extends SQLAlterTableStatement implements OracleStatement { - private static final long serialVersionUID = 1L; - private SQLExprTableSource tableSource; - private List items = new ArrayList(); + private static final long serialVersionUID = 1L; - private boolean updateGlobalIndexes = false; - private boolean invalidateGlobalIndexes = false; + private boolean updateGlobalIndexes = false; + private boolean invalidateGlobalIndexes = false; + + protected void accept0(SQLASTVisitor visitor) { + accept0((OracleASTVisitor) visitor); + } @Override public void accept0(OracleASTVisitor visitor) { if (visitor.visit(this)) { - acceptChild(visitor, tableSource); - acceptChild(visitor, items); + acceptChild(visitor, getTableSource()); + acceptChild(visitor, getItems()); } visitor.endVisit(this); } @@ -42,30 +43,13 @@ public class OracleAlterTableStatement extends OracleStatementImpl { } public SQLName getName() { - if (tableSource == null) { + if (getTableSource() == null) { return null; } - return (SQLName) tableSource.getExpr(); + return (SQLName) getTableSource().getExpr(); } public void setName(SQLName name) { this.setTableSource(new SQLExprTableSource(name)); } - - public SQLExprTableSource getTableSource() { - return tableSource; - } - - public void setTableSource(SQLExprTableSource tableSource) { - this.tableSource = tableSource; - } - - public List getItems() { - return items; - } - - public void setItems(List items) { - this.items = items; - } - } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java index 70f2f7e2b3..b52957e4f2 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java @@ -29,6 +29,7 @@ import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; +import com.alibaba.druid.sql.ast.statement.SQLAlterTableItem; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; @@ -90,7 +91,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterSynonymStatement import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableAddColumn; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableAddConstaint; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableDropPartition; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableItem; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableModify; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableMoveTablespace; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableRenameTo; @@ -2045,7 +2045,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS print("ALTER TABLE "); x.getName().accept(this); incrementIndent(); - for (OracleAlterTableItem item : x.getItems()) { + for (SQLAlterTableItem item : x.getItems()) { println(); item.accept(this); } 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 a303f86b30..2955108ffd 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -109,7 +109,8 @@ public class SQLStatementParser extends SQLParser { } if (lexer.token() == Token.ALTER) { - throw new ParserException("TODO"); + statementList.add(parseAlter()); + continue; } if (lexer.token() == Token.DROP) { @@ -162,6 +163,11 @@ public class SQLStatementParser extends SQLParser { stmt.setDatabase(this.exprParser.name()); return stmt; } + + public SQLSetStatement parseAlter() { + accept(Token.ALTER); + throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + } protected SQLDropTableStatement parseDropTable(boolean acceptDrop) { if (acceptDrop) { @@ -185,7 +191,9 @@ public class SQLStatementParser extends SQLParser { public SQLStatement parseTruncate() { accept(Token.TRUNCATE); - accept(Token.TABLE); + if (lexer.token() == Token.TABLE) { + lexer.nextToken(); + } SQLTruncateStatement stmt = new SQLTruncateStatement(); for (;;) { diff --git a/src/test/java/com/alibaba/druid/bvt/sql/cobar/DDLParserTest.java b/src/test/java/com/alibaba/druid/bvt/sql/cobar/DDLParserTest.java new file mode 100644 index 0000000000..5836f3aed4 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/cobar/DDLParserTest.java @@ -0,0 +1,149 @@ +/** + * (created at 2011-7-18) + */ +package com.alibaba.druid.bvt.sql.cobar; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.parser.Token; + +/** + * @author YU Danping + */ +public class DDLParserTest extends TestCase { + + public void testTruncate() throws Exception { + String sql = "Truncate table tb1"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("TRUNCATE TABLE tb1", output); + } + + public void testTruncate_1() throws Exception { + String sql = "Truncate tb1"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("TRUNCATE TABLE tb1", output); + } + + public void testAlterTable0() throws Exception { + String sql = "alTer ignore table tb_name"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("ALTER ignore table tb_name", output); + } + +// public void testDDLStmt() throws Exception { +// String sql = "alTer ignore table tb_name"; +// SQLLexer lexer = new SQLLexer(sql); +// DDLParser parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// DDLStatement dst = parser.ddlStmt(); +// +// sql = "alTeR table tb_name"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// +// sql = "crEate temporary tabLe if not exists tb_name"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// +// sql = "crEate tabLe if not exists tb_name"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// +// sql = "crEate temporary tabLe tb_name"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// +// sql = "crEate unique index index_name on tb(col(id)) desc"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// +// sql = "crEate fulltext index index_name on tb(col(id))"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// +// sql = "crEate spatial index index_name on tb(col(id))"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// +// sql = "crEate index index_name using hash on tb(col(id))"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// +// sql = "drop index index_name on tb1"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// String output = output2MySQL(dst, sql); +// Assert.assertEquals("DROP INDEX index_name ON tb1", output); +// +// sql = "drop temporary tabLe if exists tb1,tb2,tb3 restrict"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// output = output2MySQL(dst, sql); +// Assert.assertEquals("DROP TEMPORARY TABLE IF EXISTS tb1, tb2, tb3 RESTRICT", output); +// +// sql = "drop temporary tabLe if exists tb1,tb2,tb3 cascade"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// output = output2MySQL(dst, sql); +// Assert.assertEquals("DROP TEMPORARY TABLE IF EXISTS tb1, tb2, tb3 CASCADE", output); +// +// sql = "drop temporary tabLe if exists tb1 cascade"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// output = output2MySQL(dst, sql); +// Assert.assertEquals("DROP TEMPORARY TABLE IF EXISTS tb1 CASCADE", output); +// +// sql = "drop tabLe if exists tb1 cascade"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// output = output2MySQL(dst, sql); +// Assert.assertEquals("DROP TABLE IF EXISTS tb1 CASCADE", output); +// +// sql = "drop temporary tabLe tb1 cascade"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// output = output2MySQL(dst, sql); +// Assert.assertEquals("DROP TEMPORARY TABLE tb1 CASCADE", output); +// +// sql = "rename table tb1 to ntb1,tb2 to ntb2"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// output = output2MySQL(dst, sql); +// Assert.assertEquals("RENAME TABLE tb1 TO ntb1, tb2 TO ntb2", output); +// +// sql = "rename table tb1 to ntb1"; +// lexer = new SQLLexer(sql); +// parser = new DDLParser(lexer, new SQLExprParser(lexer)); +// dst = parser.ddlStmt(); +// output = output2MySQL(dst, sql); +// Assert.assertEquals("RENAME TABLE tb1 TO ntb1", output); +// } +}