improve mysql parser

This commit is contained in:
wenshao
2013-04-28 00:28:18 +08:00
parent 7024507519
commit 524527dae9
7 changed files with 194 additions and 20 deletions
@@ -43,7 +43,7 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement implement
private List<SQLCommentHint> hints = new ArrayList<SQLCommentHint>();
private SQLExprTableSource like;
public MySqlCreateTableStatement(){
}
@@ -26,6 +26,8 @@ public class MySqlSQLColumnDefinition extends SQLColumnDefinition {
private SQLExpr onUpdate;
private SQLExpr storage;
public MySqlSQLColumnDefinition(){
}
@@ -38,12 +40,21 @@ public class MySqlSQLColumnDefinition extends SQLColumnDefinition {
this.autoIncrement = autoIncrement;
}
public SQLExpr getOnUpdate() {
return onUpdate;
}
public void setOnUpdate(SQLExpr onUpdate) {
this.onUpdate = onUpdate;
}
public SQLExpr getStorage() {
return storage;
}
public void setStorage(SQLExpr storage) {
this.storage = storage;
}
}
@@ -186,7 +186,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
parseTableOptionCharsetOrCollate(stmt);
continue;
}
if (parseTableOptionCharsetOrCollate(stmt)) {
continue;
}
@@ -200,7 +200,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
continue;
}
if (identifierEquals("COMMENT")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
@@ -210,7 +210,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
continue;
}
if (identifierEquals("CONNECTION")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
@@ -220,7 +220,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
continue;
}
if (identifierEquals("DATA")) {
lexer.nextToken();
acceptIdentifier("DIRECTORY");
@@ -231,7 +231,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
continue;
}
if (identifierEquals("DELAY_KEY_WRITE")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
@@ -241,7 +241,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
continue;
}
if (identifierEquals("INDEX")) {
lexer.nextToken();
acceptIdentifier("DIRECTORY");
@@ -252,7 +252,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
continue;
}
if (identifierEquals("INSERT_METHOD")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
@@ -262,7 +262,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
continue;
}
if (identifierEquals("KEY_BLOCK_SIZE")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
@@ -272,7 +272,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
continue;
}
if (identifierEquals("MAX_ROWS")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
@@ -282,7 +282,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
continue;
}
if (identifierEquals("MIN_ROWS")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
@@ -292,7 +292,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
continue;
}
if (identifierEquals("PACK_KEYS")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
@@ -302,7 +302,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
continue;
}
if (identifierEquals("PASSWORD")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
@@ -312,7 +312,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
continue;
}
if (identifierEquals("ROW_FORMAT")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
@@ -323,6 +323,20 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
continue;
}
if (identifierEquals("TABLESPACE")) {
lexer.nextToken();
String tablespace_name = lexer.stringVal();
accept(Token.IDENTIFIER);
if (identifierEquals("STORAGE")) {
throw new ParserException("TODO STORAGE");
}
stmt.getTableOptions().put("TABLESPACE", tablespace_name);
continue;
}
if (identifierEquals("TYPE")) {
lexer.nextToken();
accept(Token.EQ);
@@ -373,7 +387,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
return stmt;
}
private boolean parseTableOptionCharsetOrCollate(MySqlCreateTableStatement stmt) {
if (identifierEquals("CHARACTER")) {
lexer.nextToken();
@@ -395,7 +409,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
return true;
}
if (identifierEquals("COLLATE")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
@@ -405,7 +419,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
return true;
}
return false;
}
@@ -559,6 +559,14 @@ public class MySqlExprParser extends SQLExprParser {
accept(Token.LITERAL_CHARS);
}
if (identifierEquals("STORAGE")) {
lexer.nextToken();
SQLExpr expr = expr();
if (column instanceof MySqlSQLColumnDefinition) {
((MySqlSQLColumnDefinition) column).setStorage(expr);
}
}
super.parseColumnRest(column);
return column;
@@ -295,6 +295,11 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
x.getDefaultExpr().accept(this);
}
}
if (mysqlColumn != null && mysqlColumn.getStorage() != null) {
print(" STORAGE ");
mysqlColumn.getStorage().accept(this);
}
if (mysqlColumn != null && mysqlColumn.getOnUpdate() != null) {
print(" ON UPDATE ");
@@ -452,8 +457,15 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
for (Map.Entry<String, String> option : x.getTableOptions().entrySet()) {
String key = option.getKey();
print(" ");
print(' ');
print(key);
if ("TABLESPACE".equals(key)) {
print(' ');
print(option.getValue());
continue;
}
print(" = ");
if ("COMMENT".equals(key)) {
@@ -0,0 +1,65 @@
/*
* 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 java.util.List;
import org.junit.Assert;
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;
import com.alibaba.druid.stat.TableStat;
public class MySqlCreateTableTest22 extends MysqlTest {
public void test_0() throws Exception {
String sql = "CREATE TABLE t1 (" + //
"c1 INT STORAGE DISK," + //
"c2 INT STORAGE MEMORY " + //
") TABLESPACE ts_1 ENGINE NDB;";
MySqlStatementParser parser = new MySqlStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement stmt = statementList.get(0);
print(statementList);
Assert.assertEquals(1, statementList.size());
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());
System.out.println("orderBy : " + visitor.getOrderByColumns());
Assert.assertEquals(1, visitor.getTables().size());
Assert.assertEquals(2, visitor.getColumns().size());
Assert.assertEquals(0, visitor.getConditions().size());
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("t1")));
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("CREATE TABLE t1 (" + //
"\n\tc1 INT STORAGE DISK, " + //
"\n\tc2 INT STORAGE MEMORY" + //
"\n) TABLESPACE ts_1 ENGINE = NDB", output);
}
}
@@ -0,0 +1,64 @@
/*
* 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 java.util.List;
import org.junit.Assert;
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;
import com.alibaba.druid.stat.TableStat;
public class MySqlCreateTableTest23 extends MysqlTest {
public void test_0() throws Exception {
String sql = "CREATE TABLE lookup" + //
" (id INT, INDEX USING BTREE (id))" + //
" ENGINE = MEMORY;"; //
MySqlStatementParser parser = new MySqlStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement stmt = statementList.get(0);
print(statementList);
Assert.assertEquals(1, statementList.size());
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());
System.out.println("orderBy : " + visitor.getOrderByColumns());
Assert.assertEquals(1, visitor.getTables().size());
Assert.assertEquals(1, visitor.getColumns().size());
Assert.assertEquals(0, visitor.getConditions().size());
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("lookup")));
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("CREATE TABLE lookup (" + //
"\n\tid INT, " + //
"\n\tINDEX USING BTREE(id)" + //
"\n) ENGINE = MEMORY", output);
}
}