diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlCharExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlCharExpr.java index 5287c2fb05..5d374b7cba 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlCharExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/expr/MySqlCharExpr.java @@ -53,8 +53,9 @@ public class MySqlCharExpr extends SQLCharExpr implements MySqlExpr { buf.append(charset); buf.append(' '); } - - super.output(buf); + if (super.text!=null){ + super.output(buf); + } if (collate != null) { buf.append(" COLLATE "); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSQLColumnDefinition.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSQLColumnDefinition.java index 5bcd6d6c9e..74b03b0518 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSQLColumnDefinition.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSQLColumnDefinition.java @@ -26,10 +26,21 @@ public class MySqlSQLColumnDefinition extends SQLColumnDefinition { private SQLExpr storage; + private SQLExpr charsetExpr; + + public MySqlSQLColumnDefinition(){ } + public SQLExpr getCharsetExpr() { + return charsetExpr; + } + + public void setCharsetExpr(SQLExpr charsetExpr) { + this.charsetExpr = charsetExpr; + } + public boolean isAutoIncrement() { return autoIncrement; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java index 6075e50bf9..550a2cbbde 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java @@ -531,7 +531,19 @@ public class MySqlExprParser extends SQLExprParser { SQLExpr expr = this.expr(); ((MySqlSQLColumnDefinition) column).setOnUpdate(expr); } - + if (identifierEquals("CHARSET")) { + lexer.nextToken(); + MySqlCharExpr charSetCollateExpr=new MySqlCharExpr(); + charSetCollateExpr.setCharset(lexer.stringVal()); + lexer.nextToken(); + if (identifierEquals("COLLATE")) { + lexer.nextToken(); + charSetCollateExpr.setCollate(lexer.stringVal()); + lexer.nextToken(); + } + ((MySqlSQLColumnDefinition) column).setCharsetExpr(charSetCollateExpr); + return parseColumnRest(column); + } if (identifierEquals("AUTO_INCREMENT")) { lexer.nextToken(); if (column instanceof MySqlSQLColumnDefinition) { 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 c59ed17cd7..db413f1135 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 @@ -309,6 +309,11 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV print(' '); x.getDataType().accept(this); + if (mysqlColumn != null && mysqlColumn.getCharsetExpr() != null) { + print(" CHARSET "); + mysqlColumn.getCharsetExpr().accept(this); + } + for (SQLColumnConstraint item : x.getConstraints()) { print(' '); item.accept(this); diff --git a/src/test/java/com/alibaba/druid/sql/parser/MySQLCharSetTest.java b/src/test/java/com/alibaba/druid/sql/parser/MySQLCharSetTest.java new file mode 100644 index 0000000000..f44462fe9a --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/parser/MySQLCharSetTest.java @@ -0,0 +1,58 @@ +package com.alibaba.druid.sql.parser; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.List; + +/** + * Created by tianzhen.wtz on 2015/10/31. + * 类说明: + */ +public class MySQLCharSetTest extends TestCase{ + + public void testCreateCharset(){ + String targetSql="CREATE TABLE `test_idb`.`acct_certificate` (\n" + + " `id` bigint(20) NOT NULL auto_increment COMMENT '',\n" + + " `nodeid` varchar(5) CHARSET `gbk` COLLATE `gbk_chinese_ci` NULL COMMENT '',\n" + + " `certificatetype` char(1) CHARSET `gbk` COLLATE `gbk_chinese_ci` NULL COMMENT '',\n" + + " `certificateno` varchar(32) CHARSET `gbk` COLLATE `gbk_chinese_ci` NULL COMMENT '',\n" + + " PRIMARY KEY(`id`),\n" + + " INDEX `id_acct_certificate_nodeid`(`nodeid`),\n" + + " INDEX `id_acct_certificate_certificateno`(`certificateno`)\n" + + "\n" + + ") engine= InnoDB DEFAULT CHARSET= `gbk` DEFAULT COLLATE `gbk_chinese_ci` comment= '' ;"; + + String resultSql="CREATE TABLE `test_idb`.`acct_certificate` (\n" + + "\t`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '', \n" + + "\t`nodeid` varchar(5) CHARSET `gbk` COLLATE `gbk_chinese_ci` NULL COMMENT '', \n" + + "\t`certificatetype` char(1) CHARSET `gbk` COLLATE `gbk_chinese_ci` NULL COMMENT '', \n" + + "\t`certificateno` varchar(32) CHARSET `gbk` COLLATE `gbk_chinese_ci` NULL COMMENT '', \n" + + "\tPRIMARY KEY (`id`), \n" + + "\tINDEX `id_acct_certificate_nodeid`(`nodeid`), \n" + + "\tINDEX `id_acct_certificate_certificateno`(`certificateno`)\n" + + ") ENGINE = InnoDB CHARSET = `gbk` COLLATE = `gbk_chinese_ci` COMMENT = ''"; + equal(targetSql, resultSql); + } + + + public void testAlterCharset(){ + String targetSql="ALTER TABLE acct_certificate MODIFY COLUMN `nodeid` varchar(5) CHARSET `gbk` COLLATE `gbk_chinese_ci` NULL COMMENT ''"; + + String resultSql="ALTER TABLE acct_certificate\n" + + "\tMODIFY COLUMN `nodeid` varchar(5) CHARSET `gbk` COLLATE `gbk_chinese_ci` NULL COMMENT ''"; + equal(targetSql, resultSql); + } + + + private void equal(String targetSql,String resultSql){ + MySqlStatementParser parser=new MySqlStatementParser(targetSql); + List sqlStatements = parser.parseStatementList(); + System.out.println(sqlStatements.get(0).toString()); + Assert.assertTrue(sqlStatements.get(0).toString().equals(resultSql)); + + } +}