From 2b6e4bac083841a8aa2deae2066428745284e99f Mon Sep 17 00:00:00 2001 From: wenshao Date: Thu, 28 Mar 2013 21:38:54 +0800 Subject: [PATCH] mysql parser improved, support alter table add constraint primary key --- .../mysql/parser/MySqlStatementParser.java | 76 ++++++++++------- .../mysql/visitor/MySqlOutputVisitor.java | 2 +- .../mysql/MySqlAlterTableAddPrimaryKey_1.java | 39 +++++++++ .../bvt/sql/oracle/OracleSelectTest41.java | 81 +++++++++++++++++++ 4 files changed, 167 insertions(+), 31 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableAddPrimaryKey_1.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest41.java 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 8abb2aa0b8..58263c0956 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 @@ -146,35 +146,35 @@ import com.alibaba.druid.sql.parser.Token; public class MySqlStatementParser extends SQLStatementParser { private static final String AUTO_INCREMENT = "AUTO_INCREMENT"; - private static final String COLLATE2 = "COLLATE"; - private static final String CASCADE = "CASCADE"; - private static final String RESTRICT = "RESTRICT"; - private static final String CHAIN = "CHAIN"; - private static final String ENGINES = "ENGINES"; - private static final String ENGINE = "ENGINE"; - private static final String BINLOG = "BINLOG"; - private static final String EVENTS = "EVENTS"; - private static final String CHARACTER = "CHARACTER"; - private static final String SESSION = "SESSION"; - private static final String GLOBAL = "GLOBAL"; - private static final String VARIABLES = "VARIABLES"; - private static final String ERRORS = "ERRORS"; - private static final String STATUS = "STATUS"; - private static final String IGNORE = "IGNORE"; - private static final String RESET = "RESET"; - private static final String DESCRIBE = "DESCRIBE"; - private static final String DESC = "DESC"; - private static final String WRITE = "WRITE"; - private static final String READ = "READ"; - private static final String LOCAL = "LOCAL"; - private static final String TABLES = "TABLES"; - private static final String TEMPORARY = "TEMPORARY"; - private static final String USER = "USER"; - private static final String SPATIAL = "SPATIAL"; - private static final String FULLTEXT = "FULLTEXT"; - private static final String REPLACE = "REPLACE"; - private static final String DELAYED = "DELAYED"; - private static final String LOW_PRIORITY = "LOW_PRIORITY"; + private static final String COLLATE2 = "COLLATE"; + private static final String CASCADE = "CASCADE"; + private static final String RESTRICT = "RESTRICT"; + private static final String CHAIN = "CHAIN"; + private static final String ENGINES = "ENGINES"; + private static final String ENGINE = "ENGINE"; + private static final String BINLOG = "BINLOG"; + private static final String EVENTS = "EVENTS"; + private static final String CHARACTER = "CHARACTER"; + private static final String SESSION = "SESSION"; + private static final String GLOBAL = "GLOBAL"; + private static final String VARIABLES = "VARIABLES"; + private static final String ERRORS = "ERRORS"; + private static final String STATUS = "STATUS"; + private static final String IGNORE = "IGNORE"; + private static final String RESET = "RESET"; + private static final String DESCRIBE = "DESCRIBE"; + private static final String DESC = "DESC"; + private static final String WRITE = "WRITE"; + private static final String READ = "READ"; + private static final String LOCAL = "LOCAL"; + private static final String TABLES = "TABLES"; + private static final String TEMPORARY = "TEMPORARY"; + private static final String USER = "USER"; + private static final String SPATIAL = "SPATIAL"; + private static final String FULLTEXT = "FULLTEXT"; + private static final String REPLACE = "REPLACE"; + private static final String DELAYED = "DELAYED"; + private static final String LOW_PRIORITY = "LOW_PRIORITY"; public MySqlStatementParser(String sql){ super(new MySqlExprParser(sql)); @@ -2236,7 +2236,23 @@ public class MySqlStatementParser extends SQLStatementParser { } else if (lexer.token() == Token.KEY) { throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); } else if (lexer.token() == Token.CONSTRAINT) { - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + int mark = lexer.bp(); + char markChar = lexer.current(); + + lexer.nextToken(); + SQLName constraintName = this.exprParser.name(); + + if (lexer.token() == Token.PRIMARY) { + SQLPrimaryKey primaryKey = ((MySqlExprParser) this.exprParser).parsePrimaryKey(); + + primaryKey.setName(constraintName); + + SQLAlterTableAddPrimaryKey item = new SQLAlterTableAddPrimaryKey(); + item.setPrimaryKey(primaryKey); + stmt.getItems().add(item); + } else { + throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); + } } else if (identifierEquals(FULLTEXT)) { throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); } else if (identifierEquals(SPATIAL)) { 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 ba20e585ff..fd70b69674 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 @@ -490,7 +490,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV public boolean visit(MySqlPrimaryKey x) { if (x.getName() != null) { print("CONSTRAINT "); - x.accept(this); + x.getName().accept(this); print(' '); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableAddPrimaryKey_1.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableAddPrimaryKey_1.java new file mode 100644 index 0000000000..4f85296ab4 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableAddPrimaryKey_1.java @@ -0,0 +1,39 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.mysql; + +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; + +public class MySqlAlterTableAddPrimaryKey_1 extends TestCase { + + public void test_alter_first() throws Exception { + String sql = "alter table tabelname add constraint mYconstraint primary key(id)"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("ALTER TABLE tabelname" + // + "\n\tADD CONSTRAINT mYconstraint PRIAMRY KEY (id)", output); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest41.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest41.java new file mode 100644 index 0000000000..6d79c7c53c --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest41.java @@ -0,0 +1,81 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest41 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "WITH RESULTVIEW AS" + // + " (" + // + " SELECT" + // + " AA.USERID," + // + " DECODE(AA.USERTYPE," + // + " '1'," + // + " (SELECT ORG_TABLE.ORGNAME" + // + " FROM ORG_TABLE" + // + " WHERE ORG_TABLE.ORGID = AA.BELONGORG)," + // + " '2'," + // + " (SELECT CUST_TABLE.CUSTOMERNAME" + // + " FROM CUST_TABLE" + // + " WHERE CUST_TABLE.CUSTOMERID = AA.BELONGORG)) ORGNAME" + // + " FROM AA" + // + " LEFT JOIN AAPWD" + // + " ON AA.USERID = AAPWD.USERID" + // + " WHERE AA.BELONGORG IN" + // + " (1,2,3)" + // + " ORDER BY AA.USERID DESC" + // + " )" + // + "SELECT *" + // + " FROM (SELECT RESULTVIEW.*, ROWNUM AS RESULTNUMS FROM RESULTVIEW)" + // + " WHERE RESULTNUMS > 1" + // + " AND RESULTNUMS <= 10"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(4, visitor.getTables().size()); + + Assert.assertEquals(9, visitor.getColumns().size()); + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("acduser.vw_acd_info", "xzqh"))); + + // Assert.assertTrue(visitor.getOrderByColumns().contains(new TableStat.Column("employees", "last_name"))); + } +}