improved mysql parser

This commit is contained in:
高铁
2016-01-14 17:57:32 +08:00
parent 5668eed214
commit 262e0b4da1
12 changed files with 176 additions and 25 deletions
@@ -21,16 +21,16 @@ import com.alibaba.druid.sql.ast.SQLOrderingSpecification;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class MySqlGroupByItemExpr extends SQLExprImpl implements MySqlExpr {
public class MySqlOrderingExpr extends SQLExprImpl implements MySqlExpr {
protected SQLExpr expr;
protected SQLOrderingSpecification type;
public MySqlGroupByItemExpr() {
public MySqlOrderingExpr() {
}
public MySqlGroupByItemExpr(SQLExpr expr, SQLOrderingSpecification type){
public MySqlOrderingExpr(SQLExpr expr, SQLOrderingSpecification type){
super();
this.expr = expr;
this.type = type;
@@ -74,7 +74,7 @@ public class MySqlGroupByItemExpr extends SQLExprImpl implements MySqlExpr {
if (getClass() != obj.getClass()) {
return false;
}
MySqlGroupByItemExpr other = (MySqlGroupByItemExpr) obj;
MySqlOrderingExpr other = (MySqlOrderingExpr) obj;
if (expr != other.expr) {
return false;
}
@@ -15,7 +15,9 @@
*/
package com.alibaba.druid.sql.dialect.mysql.parser;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLOrderingSpecification;
import com.alibaba.druid.sql.ast.statement.SQLCheck;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
@@ -27,6 +29,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.MySqlKey;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlPrimaryKey;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlUnique;
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement.TableSpaceOption;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPartitionByHash;
@@ -662,7 +665,16 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
accept(Token.LPAREN);
for (;;) {
key.getColumns().add(this.exprParser.expr());
SQLExpr expr = this.exprParser.expr();
if (lexer.token() == Token.ASC) {
lexer.nextToken();
expr = new MySqlOrderingExpr(expr, SQLOrderingSpecification.ASC);
} else if (lexer.token() == Token.DESC) {
lexer.nextToken();
expr = new MySqlOrderingExpr(expr, SQLOrderingSpecification.DESC);
}
key.getColumns().add(expr);
if (!(lexer.token() == (Token.COMMA))) {
break;
} else {
@@ -45,7 +45,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExtractExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalUnit;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlGroupByItemExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr.SearchModifier;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlUserName;
@@ -859,8 +859,8 @@ public class MySqlExprParser extends SQLExprParser {
return aggregateExpr;
}
public MySqlGroupByItemExpr parseSelectGroupByItem() {
MySqlGroupByItemExpr item = new MySqlGroupByItemExpr();
public MySqlOrderingExpr parseSelectGroupByItem() {
MySqlOrderingExpr item = new MySqlOrderingExpr();
item.setExpr(expr());
@@ -33,7 +33,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlWhileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExtractExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlGroupByItemExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
@@ -554,9 +554,9 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
void endVisit(MySqlHintStatement x);
boolean visit(MySqlGroupByItemExpr x);
boolean visit(MySqlOrderingExpr x);
void endVisit(MySqlGroupByItemExpr x);
void endVisit(MySqlOrderingExpr x);
/**
* support procedure
@@ -33,7 +33,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlWhileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExtractExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlGroupByItemExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
@@ -1213,12 +1213,12 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq
}
@Override
public boolean visit(MySqlGroupByItemExpr x) {
public boolean visit(MySqlOrderingExpr x) {
return true;
}
@Override
public void endVisit(MySqlGroupByItemExpr x) {
public void endVisit(MySqlOrderingExpr x) {
}
@@ -63,7 +63,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlWhileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExtractExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlGroupByItemExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
@@ -3125,7 +3125,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
@Override
public boolean visit(MySqlGroupByItemExpr x) {
public boolean visit(MySqlOrderingExpr x) {
x.getExpr().accept(this);
if (x.getType() != null) {
print(' ');
@@ -3136,7 +3136,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
@Override
public void endVisit(MySqlGroupByItemExpr x) {
public void endVisit(MySqlOrderingExpr x) {
}
@@ -47,7 +47,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlWhileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExtractExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlGroupByItemExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
@@ -1312,12 +1312,12 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
}
@Override
public boolean visit(MySqlGroupByItemExpr x) {
public boolean visit(MySqlOrderingExpr x) {
return true;
}
@Override
public void endVisit(MySqlGroupByItemExpr x) {
public void endVisit(MySqlOrderingExpr x) {
}
@@ -35,7 +35,7 @@ import com.alibaba.druid.sql.ast.statement.SQLUnionOperator;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUnionQueryTableSource;
import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlGroupByItemExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
import com.alibaba.druid.util.JdbcConstants;
public class SQLSelectParser extends SQLParser {
@@ -339,10 +339,10 @@ public class SQLSelectParser extends SQLParser {
if(JdbcConstants.MYSQL.equals(getDbType())) {
if (lexer.token() == Token.DESC) {
lexer.nextToken(); // skip
item =new MySqlGroupByItemExpr(item, SQLOrderingSpecification.DESC);
item =new MySqlOrderingExpr(item, SQLOrderingSpecification.DESC);
} else if (lexer.token() == Token.ASC) {
lexer.nextToken(); // skip
item =new MySqlGroupByItemExpr(item, SQLOrderingSpecification.ASC);
item =new MySqlOrderingExpr(item, SQLOrderingSpecification.ASC);
}
}
return item;
@@ -95,7 +95,7 @@ import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUseStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlGroupByItemExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement;
@@ -1206,7 +1206,7 @@ public class WallVisitorUtils {
return true;
} else if (parent instanceof Limit) {
return true;
} else if (parent instanceof MySqlGroupByItemExpr) {
} else if (parent instanceof MySqlOrderingExpr) {
return true;
}
@@ -0,0 +1,47 @@
/*
* 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 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 MySqlCreateTableTest61 extends MysqlTest {
@Test
public void test_one() throws Exception {
String sql = "create table t (pk int auto_increment primary key,a timestamp null default current_timestamp on update current_timestamp, b timestamp null)";
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement stmt = parser.parseCreateTable();
MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
stmt.accept(visitor);
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("CREATE TABLE t ("
+ "\n\tpk int PRIMARY KEY AUTO_INCREMENT, "
+ "\n\ta timestamp DEFAULT current_timestamp ON UPDATE current_timestamp, "
+ "\n\tb timestamp NULL"
+ "\n)", output);
}
}
@@ -0,0 +1,45 @@
/*
* 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 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 MySqlCreateTableTest62 extends MysqlTest {
@Test
public void test_one() throws Exception {
String sql = "create table a ( b varchar(15) CHARACTER SET latin1 DEFAULT NULL)";
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement stmt = parser.parseCreateTable();
MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
stmt.accept(visitor);
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("CREATE TABLE a ("
+ "\n\tb varchar(15) CHARACTER SET latin1 NULL"
+ "\n)", output);
}
}
@@ -0,0 +1,47 @@
/*
* 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 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 MySqlCreateTableTest63 extends MysqlTest {
@Test
public void test_one() throws Exception {
String sql = "CREATE TABLE t (pk int auto_increment primary key, a TIMESTAMP, KEY ( a DESC ) );";
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement stmt = parser.parseCreateTable();
MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
stmt.accept(visitor);
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("CREATE TABLE t ("
+ "\n\tpk int PRIMARY KEY AUTO_INCREMENT, "
+ "\n\ta TIMESTAMP, "
+ "\n\tKEY (a DESC)"
+ "\n)", output);
}
}