improved mysql parser. bug fixed for issue #2263

This commit is contained in:
wenshao
2018-01-22 23:28:58 +08:00
parent b7214015a2
commit 5ed3a3e5a7
7 changed files with 177 additions and 2 deletions
@@ -0,0 +1,73 @@
/*
* Copyright 1999-2017 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.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLAlterTableExchangePartition extends SQLObjectImpl implements SQLAlterTableItem {
private SQLName partition;
private SQLExprTableSource table;
private Boolean validation;
public SQLAlterTableExchangePartition() {
}
@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, partition);
acceptChild(visitor, table);
}
visitor.endVisit(this);
}
public SQLName getPartition() {
return partition;
}
public void setPartition(SQLName x) {
if (x != null) {
x.setParent(this);
}
this.partition = x;
}
public SQLExprTableSource getTable() {
return table;
}
public void setTable(SQLName x) {
setTable(new SQLExprTableSource(x));
}
public void setTable(SQLExprTableSource x) {
if (x != null) {
x.setParent(this);
}
this.table = x;
}
public void setValidation(boolean validation) {
this.validation = validation;
}
public Boolean getValidation() {
return validation;
}
}
@@ -3806,7 +3806,31 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.RPAREN);
stmt.addItem(item);
} else if (lexer.identifierEquals("EXCHANGE")) {
throw new ParserException("TODO " + lexer.info());
lexer.nextToken();
accept(Token.PARTITION);
SQLAlterTableExchangePartition item = new SQLAlterTableExchangePartition();
SQLName partition = this.exprParser.name();
item.setPartition(partition);
accept(Token.WITH);
accept(Token.TABLE);
SQLName table = this.exprParser.name();
item.setTable(table);
if (lexer.token() == Token.WITH) {
lexer.nextToken();
acceptIdentifier("VALIDATION");
item.setValidation(true);
} else if (lexer.identifierEquals(FnvHash.Constants.WITHOUT)) {
lexer.nextToken();
acceptIdentifier("VALIDATION");
item.setValidation(false);
}
stmt.addItem(item);
} else if (lexer.token() == Token.OPTIMIZE) {
lexer.nextToken();
@@ -5192,7 +5192,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
if (x.isTablespace()) {
print0(ucase ? " TABLESPACE" : " tablespace");
}
return false;
}
@@ -6225,4 +6225,23 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
x.getTo().accept(this);
return false;
}
@Override
public boolean visit(SQLAlterTableExchangePartition x) {
print0(ucase ? "EXCHANGE PARTITION " : "exchange partition ");
x.getPartition().accept(this);
print0(ucase ? " WITH TABLE " : " with table ");
x.getTable().accept(this);
Boolean validation = x.getValidation();
if (validation != null) {
if (validation) {
print0(ucase ? " WITH VALIDATION" : " with validation");
} else {
print0(ucase ? " WITHOUT VALIDATION" : " without validation");
}
}
return false;
}
}
@@ -823,4 +823,7 @@ public interface SQLASTVisitor {
boolean visit(SQLAlterSequenceStatement x);
void endVisit(SQLAlterSequenceStatement x);
boolean visit(SQLAlterTableExchangePartition x);
void endVisit(SQLAlterTableExchangePartition x);
}
@@ -1944,6 +1944,16 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
}
@Override
public boolean visit(SQLAlterTableExchangePartition x) {
return true;
}
@Override
public void endVisit(SQLAlterTableExchangePartition x) {
}
public final boolean isEnabled(VisitorFeature feature) {
return VisitorFeature.isEnabled(this.features, feature);
}
@@ -2441,4 +2441,13 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLCreateDatabaseStatement x) {
return false;
}
@Override
public boolean visit(SQLAlterTableExchangePartition x) {
SQLExprTableSource table = x.getTable();
if (table != null) {
table.accept(this);
}
return false;
}
}
@@ -0,0 +1,37 @@
/*
* Copyright 1999-2017 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.alter;
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;
import junit.framework.TestCase;
import org.junit.Assert;
public class MySqlAlterTableTest33 extends TestCase {
public void test_alter_add_key() throws Exception {
String sql = "ALTER TABLE src.`part_tab` EXCHANGE PARTITION p9 WITH TABLE test_create_table without validation";
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement stmt = parser.parseStatementList().get(0);
parser.match(Token.EOF);
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("ALTER TABLE src.`part_tab`\n" +
"\tEXCHANGE PARTITION p9 WITH TABLE test_create_table WITHOUT VALIDATION", output);
}
}