diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCharacterDataType.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCharacterDataType.java index 8c6276d9dc..b137bd0803 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCharacterDataType.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCharacterDataType.java @@ -24,6 +24,7 @@ public class SQLCharacterDataType extends SQLDataTypeImpl { private String collate; private String charType; + private boolean hasBinary; public final static String CHAR_TYPE_BYTE = "BYTE"; public final static String CHAR_TYPE_CHAR = "CHAR"; @@ -39,6 +40,14 @@ public class SQLCharacterDataType extends SQLDataTypeImpl { public void setCharSetName(String charSetName) { this.charSetName = charSetName; } + + public boolean isHasBinary() { + return hasBinary; + } + + public void setHasBinary(boolean hasBinary) { + this.hasBinary = hasBinary; + } public String getCollate() { return collate; 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 afeb79dbc1..361b995c08 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 @@ -376,6 +376,10 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV print(")"); } + if (x.isHasBinary()) { + print(" BINARY "); + } + if (x.getCharSetName() != null) { print(" CHARACTER SET "); print(x.getCharSetName()); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index fd09a98d79..82ef2ad0fa 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -849,6 +849,8 @@ public class SQLExprParser extends SQLParser { case OPTIMIZE: case GRANT: case REVOKE: + //binary有很多含义,lexer识别了这个token,实际上应该当做普通IDENTIFIER + case BINARY: identName = lexer.stringVal(); lexer.nextToken(); break; @@ -1420,6 +1422,11 @@ public class SQLExprParser extends SQLParser { } protected SQLDataType parseCharTypeRest(SQLCharacterDataType charType) { + if (lexer.token() == Token.BINARY) { + charType.setHasBinary(true); + lexer.nextToken(); + } + if (identifierEquals("CHARACTER")) { lexer.nextToken(); @@ -1432,6 +1439,11 @@ public class SQLExprParser extends SQLParser { lexer.nextToken(); } + if (lexer.token() == Token.BINARY) { + charType.setHasBinary(true); + lexer.nextToken(); + } + if (lexer.token() == Token.IDENTIFIER) { if (lexer.stringVal().equalsIgnoreCase("COLLATE")) { lexer.nextToken(); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTableTest57.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTableTest57.java new file mode 100644 index 0000000000..9bd77bf2f7 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTableTest57.java @@ -0,0 +1,94 @@ +/* + * 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 org.junit.Assert; +import org.junit.Test; + +import com.alibaba.druid.sql.MysqlTest; +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.dialect.mysql.visitor.MySqlSchemaStatVisitor; + +public class MySqlCreateTableTest57 extends MysqlTest { + + @Test + public void test_one() throws Exception { + String sql = "CREATE TABLE `t_cpi_driskconfig_bak` (" + "`Sequence` bigint(20) NOT NULL AUTO_INCREMENT," + + "`comcode` varchar(20) binary NOT NULL," + "`riskcode` varchar(10) binary NOT NULL," + + "`configcodehead` varchar(30) binary NOT NULL," + "`configcodebody` varchar(100) binary," + + "`configvalue` varchar(200) binary ," + "`inputdate` datetime NOT NULL," + + "`validstatus` char(1) NOT NULL," + "`remark` varchar(3000)," + "`flag` varchar(10) ," + + "PRIMARY KEY (`Sequence`)" + ") ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8;"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseCreateTable(); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(10, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("CREATE TABLE `t_cpi_driskconfig_bak` (" + "\n\t`Sequence` bigint(20) AUTO_INCREMENT NOT NULL, " + + "\n\t`comcode` varchar(20) BINARY NOT NULL, " + "\n\t`riskcode` varchar(10) BINARY NOT NULL, " + + "\n\t`configcodehead` varchar(30) BINARY NOT NULL, " + "\n\t`configcodebody` varchar(100) BINARY , " + + "\n\t`configvalue` varchar(200) BINARY , " + "\n\t`inputdate` datetime NOT NULL, " + + "\n\t`validstatus` char(1) NOT NULL, " + "\n\t`remark` varchar(3000), " + "\n\t`flag` varchar(10), " + + "\n\tPRIMARY KEY (`Sequence`)" + "\n) ENGINE = InnoDB AUTO_INCREMENT = 49 CHARSET = utf8",output); + + } + + @Test + public void test_two() throws Exception { + String sql = "CREATE TABLE `t_cpi_driskconfig_bak` (" + "`Sequence` bigint(20) NOT NULL AUTO_INCREMENT," + + "`comcode` binary(20) NOT NULL," + "`riskcode` varchar(10) binary NOT NULL," + + "`configcodehead` varchar(30) binary NOT NULL," + "`configcodebody` varchar(100) binary," + + "`configvalue` varchar(200) binary ," + "`inputdate` datetime NOT NULL," + + "`validstatus` char(1) NOT NULL," + "`remark` varchar(3000)," + "`flag` varchar(10) ," + + "PRIMARY KEY (`Sequence`)" + ") ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8;"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseCreateTable(); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(10, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("CREATE TABLE `t_cpi_driskconfig_bak` (" + "\n\t`Sequence` bigint(20) AUTO_INCREMENT NOT NULL, " + + "\n\t`comcode` binary(20) NOT NULL, " + "\n\t`riskcode` varchar(10) BINARY NOT NULL, " + + "\n\t`configcodehead` varchar(30) BINARY NOT NULL, " + "\n\t`configcodebody` varchar(100) BINARY , " + + "\n\t`configvalue` varchar(200) BINARY , " + "\n\t`inputdate` datetime NOT NULL, " + + "\n\t`validstatus` char(1) NOT NULL, " + "\n\t`remark` varchar(3000), " + "\n\t`flag` varchar(10), " + + "\n\tPRIMARY KEY (`Sequence`)" + "\n) ENGINE = InnoDB AUTO_INCREMENT = 49 CHARSET = utf8",output); + + } +}