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 6bba3f5f04..e5bce2cc74 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 @@ -2442,23 +2442,43 @@ public class MySqlStatementParser extends SQLStatementParser { stmt.addItem(item); } else if (identifierEquals("MODIFY")) { lexer.nextToken(); + if (lexer.token() == Token.COLUMN) { lexer.nextToken(); } - MySqlAlterTableModifyColumn item = new MySqlAlterTableModifyColumn(); - item.setNewColumnDefinition(this.exprParser.parseColumn()); - if (identifierEquals("AFTER")) { - lexer.nextToken(); - item.setAfterColumn(this.exprParser.name()); - } else if (identifierEquals("FIRST")) { - lexer.nextToken(); - if (lexer.token() == Token.IDENTIFIER) { - item.setFirstColumn(this.exprParser.name()); - } else { - item.setFirst(true); - } + + boolean paren = false; + if (lexer.token() == Token.LPAREN) { + paren = true; + lexer.nextToken(); + } + + for (;;) { + MySqlAlterTableModifyColumn item = new MySqlAlterTableModifyColumn(); + item.setNewColumnDefinition(this.exprParser.parseColumn()); + if (identifierEquals("AFTER")) { + lexer.nextToken(); + item.setAfterColumn(this.exprParser.name()); + } else if (identifierEquals("FIRST")) { + lexer.nextToken(); + if (lexer.token() == Token.IDENTIFIER) { + item.setFirstColumn(this.exprParser.name()); + } else { + item.setFirst(true); + } + } + stmt.addItem(item); + + if (paren && lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + + if (paren) { + accept(Token.RPAREN); } - stmt.addItem(item); } else if (lexer.token() == Token.DISABLE) { lexer.nextToken(); 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 0cce4a8d54..829ddcb2d3 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 @@ -299,8 +299,12 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV public boolean visit(SQLColumnDefinition x) { x.getName().accept(this); - print(' '); - x.getDataType().accept(this); + + SQLDataType dataType = x.getDataType(); + if (dataType != null) { + print(' '); + dataType.accept(this); + } if (x.getCharsetExpr() != null) { print0(ucase ? " CHARSET " : " charset "); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest23.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest23.java new file mode 100644 index 0000000000..7f4fe01622 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest23.java @@ -0,0 +1,38 @@ +/* + * Copyright 1999-2101 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 MySqlAlterTableTest23 extends TestCase { + + public void test_alter_add_key() throws Exception { + String sql = "alter table xxxxx modify (xxx default '0');"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("ALTER TABLE xxxxx" + + "\n\tMODIFY COLUMN xxx DEFAULT '0'", output); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest24.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest24.java new file mode 100644 index 0000000000..8c79518831 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest24.java @@ -0,0 +1,39 @@ +/* + * Copyright 1999-2101 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 MySqlAlterTableTest24 extends TestCase { + + public void test_alter_add_key() throws Exception { + String sql = "alter table xxxxx modify (f0 default '0',f1 default '0');"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("ALTER TABLE xxxxx" + + "\n\tMODIFY COLUMN f0 DEFAULT '0'," + + "\n\tMODIFY COLUMN f1 DEFAULT '0'", output); + } +}