diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlDropTableStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlDropTableStatement.java index 5e3dd96f21..acbf5dd4d1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlDropTableStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlDropTableStatement.java @@ -7,9 +7,12 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class MySqlDropTableStatement extends SQLDropTableStatement implements MySqlStatement { private static final long serialVersionUID = 1L; + private boolean temporary = false; private boolean ifExists = false; + private String option; + @Override protected void accept0(SQLASTVisitor visitor) { if (visitor instanceof MySqlASTVisitor) { @@ -34,4 +37,20 @@ public class MySqlDropTableStatement extends SQLDropTableStatement implements My this.ifExists = ifExists; } + public boolean isTemporary() { + return temporary; + } + + public void setTemporary(boolean temporary) { + this.temporary = temporary; + } + + public String getOption() { + return option; + } + + public void setOption(String option) { + this.option = option; + } + } 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 709540a3aa..e768de0633 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 @@ -214,8 +214,9 @@ 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")) { + + if (lexer.token() == Token.UNIQUE || lexer.token() == Token.INDEX || identifierEquals("FULLTEXT") + || identifierEquals("SPATIAL")) { return parseCreateIndex(); } @@ -225,10 +226,10 @@ 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(); @@ -239,17 +240,17 @@ public class MySqlStatementParser extends SQLStatementParser { stmt.setType("SPATIAL"); lexer.nextToken(); } - + accept(Token.INDEX); - + stmt.setName(this.exprParser.name()); - + parseCreateIndexUsing(stmt); - + accept(Token.ON); - + stmt.setTable(this.exprParser.name()); - + accept(Token.LPAREN); for (;;) { @@ -262,16 +263,16 @@ public class MySqlStatementParser extends SQLStatementParser { break; } accept(Token.RPAREN); - + parseCreateIndexUsing(stmt); - + return stmt; } private void parseCreateIndexUsing(MySqlCreateIndexStatement stmt) { if (identifierEquals("USING")) { lexer.nextToken(); - + if (identifierEquals("BTREE")) { stmt.setUsing("BTREE"); lexer.nextToken(); @@ -288,7 +289,7 @@ public class MySqlStatementParser extends SQLStatementParser { if (lexer.token() == Token.CREATE) { lexer.nextToken(); } - + acceptIdentifier("USER"); MySqlCreateUserStatement stmt = new MySqlCreateUserStatement(); @@ -1698,10 +1699,16 @@ public class MySqlStatementParser extends SQLStatementParser { if (acceptDrop) { accept(Token.DROP); } - accept(Token.TABLE); MySqlDropTableStatement stmt = new MySqlDropTableStatement(); + if (identifierEquals("TEMPORARY")) { + lexer.nextToken(); + stmt.setTemporary(true); + } + + accept(Token.TABLE); + if (lexer.token() == Token.IF) { lexer.nextToken(); accept(Token.EXISTS); @@ -1717,6 +1724,15 @@ public class MySqlStatementParser extends SQLStatementParser { } break; } + + if (identifierEquals("RESTRICT")) { + stmt.setOption("RESTRICT"); + lexer.nextToken(); + } else if (identifierEquals("CASCADE")) { + stmt.setOption("CASCADE"); + lexer.nextToken(); + } + return stmt; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index 0e78f5e718..444eabdeb3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -1355,12 +1355,21 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public boolean visit(MySqlDropTableStatement x) { - print("DROP TABLE "); + if (x.isTemporary()) { + print("DROP TEMPORARY TABLE "); + } else { + print("DROP TABLE "); + } if (x.isIfExists()) { print("IF EXISTS "); } printAndAccept(x.getTableSources(), ", "); + + if (x.getOption() != null) { + print(' '); + print(x.getOption()); + } return false; } 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 277937a984..73ea0eefa3 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -117,7 +117,7 @@ public class SQLStatementParser extends SQLParser { if (lexer.token() == Token.DROP) { lexer.nextToken(); - if (lexer.token() == Token.TABLE) { + if (lexer.token() == Token.TABLE || identifierEquals("TEMPORARY")) { SQLDropTableStatement stmt = parseDropTable(false); 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 index 08d937e91f..7da97ded36 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/cobar/DDLParserTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/cobar/DDLParserTest.java @@ -153,52 +153,37 @@ public class DDLParserTest extends TestCase { String output = SQLUtils.toMySqlString(stmt); Assert.assertEquals("DROP INDEX `PRIMARY` ON t", output); } + + public void test_drop_table_0() throws Exception { + String sql = "DROP TEMPORARY TABLE IF EXISTS tb1, tb2, tb3 RESTRICT"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("DROP TEMPORARY TABLE IF EXISTS tb1, tb2, tb3 RESTRICT", output); + } + + public void test_drop_table_1() throws Exception { + String sql = "DROP TEMPORARY TABLE IF EXISTS tb1, tb2, tb3 CASCADE"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("DROP TEMPORARY TABLE IF EXISTS tb1, tb2, tb3 CASCADE", output); + } + + public void test_drop_table_2() throws Exception { + String sql = "DROP TABLE t1"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("DROP TABLE t1", output); + } // public void testDDLStmt() throws Exception { // - // 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));