bug fixed for sql parser

This commit is contained in:
温少
2012-03-09 09:51:10 +08:00
parent 74316fba51
commit 786859fc71
13 changed files with 164 additions and 26 deletions
@@ -1,8 +1,7 @@
package com.alibaba.druid.sql.ast;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
public interface SQLPartitioningClause extends OracleSQLObject {
public interface SQLPartitioningClause extends SQLObject {
}
@@ -18,22 +18,33 @@ package com.alibaba.druid.sql.dialect.mysql.ast.statement;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.druid.sql.ast.SQLPartitioningClause;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
@SuppressWarnings("serial")
public class MySqlCreateTableStatement extends SQLCreateTableStatement {
private boolean ifNotExiists = false;
private boolean ifNotExiists = false;
private Map<String, String> tableOptions = new HashMap<String, String>();
private Map<String, String> tableOptions = new HashMap<String, String>();
protected SQLSelect query;
protected SQLSelect query;
private SQLPartitioningClause partitioning;
public MySqlCreateTableStatement(){
}
public SQLPartitioningClause getPartitioning() {
return partitioning;
}
public void setPartitioning(SQLPartitioningClause partitioning) {
this.partitioning = partitioning;
}
public Map<String, String> getTableOptions() {
return tableOptions;
}
@@ -0,0 +1,45 @@
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLPartitioningClause;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
public class MySqlPartitionByKey extends MySqlObjectImpl implements SQLPartitioningClause {
private static final long serialVersionUID = 1L;
private List<SQLName> columns = new ArrayList<SQLName>();
private SQLExpr partitionCount;
@Override
public void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, columns);
acceptChild(visitor, partitionCount);
}
visitor.endVisit(this);
}
public SQLExpr getPartitionCount() {
return partitionCount;
}
public void setPartitionCount(SQLExpr partitionCount) {
this.partitionCount = partitionCount;
}
public List<SQLName> getColumns() {
return columns;
}
public void setColumns(List<SQLName> columns) {
this.columns = columns;
}
}
@@ -23,6 +23,7 @@ import com.alibaba.druid.sql.ast.statement.SQLTableConstaint;
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.statement.MySqlCreateTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPartitionByKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
@@ -49,11 +50,11 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
if (acceptCreate) {
accept(Token.CREATE);
}
MySqlCreateTableStatement createTable = new MySqlCreateTableStatement();
MySqlCreateTableStatement stmt = new MySqlCreateTableStatement();
if (identifierEquals("TEMPORARY")) {
lexer.nextToken();
createTable.setType(SQLCreateTableStatement.Type.GLOBAL_TEMPORARY);
stmt.setType(SQLCreateTableStatement.Type.GLOBAL_TEMPORARY);
}
accept(Token.TABLE);
@@ -63,10 +64,10 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
accept(Token.NOT);
accept(Token.EXISTS);
createTable.setIfNotExiists(true);
stmt.setIfNotExiists(true);
}
createTable.setName(this.exprParser.name());
stmt.setName(this.exprParser.name());
if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
@@ -74,9 +75,9 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
for (;;) {
if (lexer.token() == Token.IDENTIFIER) {
SQLColumnDefinition column = this.exprParser.parseColumn();
createTable.getTableElementList().add(column);
stmt.getTableElementList().add(column);
} else if (lexer.token() == (Token.CONSTRAINT)) {
createTable.getTableElementList().add(parseConstraint());
stmt.getTableElementList().add(parseConstraint());
} else if (lexer.token() == (Token.INDEX)) {
lexer.nextToken();
@@ -105,11 +106,11 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
}
accept(Token.RPAREN);
createTable.getTableElementList().add(idx);
stmt.getTableElementList().add(idx);
} else if (lexer.token() == (Token.KEY)) {
createTable.getTableElementList().add(parseConstraint());
stmt.getTableElementList().add(parseConstraint());
} else if (lexer.token() == (Token.PRIMARY)) {
createTable.getTableElementList().add(parseConstraint());
stmt.getTableElementList().add(parseConstraint());
}
if (!(lexer.token() == (Token.COMMA))) {
@@ -126,7 +127,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
if (identifierEquals("ENGINE")) {
lexer.nextToken();
accept(Token.EQ);
createTable.getTableOptions().put("ENGINE", lexer.stringVal());
stmt.getTableOptions().put("ENGINE", lexer.stringVal());
lexer.nextToken();
continue;
}
@@ -134,11 +135,39 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
if (identifierEquals("TYPE")) {
lexer.nextToken();
accept(Token.EQ);
createTable.getTableOptions().put("TYPE", lexer.stringVal());
stmt.getTableOptions().put("TYPE", lexer.stringVal());
lexer.nextToken();
continue;
}
if (identifierEquals("PARTITION")) {
lexer.nextToken();
accept(Token.BY);
if (lexer.token() == Token.KEY) {
MySqlPartitionByKey clause = new MySqlPartitionByKey();
lexer.nextToken();
accept(Token.LPAREN);
for (;;) {
clause.getColumns().add(this.exprParser.name());
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
accept(Token.RPAREN);
stmt.setPartitioning(clause);
if (identifierEquals("PARTITIONS")) {
lexer.nextToken();
clause.setPartitionCount(this.exprParser.expr());
}
} else {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
}
break;
}
@@ -148,10 +177,10 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
if (lexer.token() == (Token.SELECT)) {
SQLSelect query = new MySqlSelectParser(this.lexer).select();
createTable.setQuery(query);
stmt.setQuery(query);
}
return createTable;
return stmt;
}
@SuppressWarnings("unused")
@@ -439,7 +439,10 @@ public class MySqlExprParser extends SQLExprParser {
}
return parseColumnRest(column);
}
if (identifierEquals("PARTITION")) {
throw new ParserException("syntax error " + lexer.token() + " " + lexer.stringVal());
}
super.parseColumnRest(column);
return column;
@@ -34,6 +34,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPartitionByKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplicateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement;
@@ -182,4 +183,8 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
void endVisit(MySqlDropTableStatement x);
boolean visit(MySqlDropTableStatement x);
void endVisit(MySqlPartitionByKey x);
boolean visit(MySqlPartitionByKey x);
}
@@ -20,6 +20,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPartitionByKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplicateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement;
@@ -389,4 +390,14 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements
return true;
}
@Override
public void endVisit(MySqlPartitionByKey x) {
}
@Override
public boolean visit(MySqlPartitionByKey x) {
return true;
}
}
@@ -49,6 +49,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPartitionByKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplicateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement;
@@ -1324,4 +1325,22 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
printAndAccept(x.getTableNames(), ", ");
return false;
}
@Override
public void endVisit(MySqlPartitionByKey x) {
}
@Override
public boolean visit(MySqlPartitionByKey x) {
print("PARTITION BY KEY (");
printAndAccept(x.getColumns(), ", ");
print(")");
if (x.getPartitionCount() != null) {
print(" PARTITIONS ");
x.getPartitionCount().accept(this);
}
return false;
}
}
@@ -26,6 +26,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPartitionByKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplicateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement;
@@ -443,4 +444,13 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
public boolean visit(MySqlDropTableStatement x) {
return visit((SQLDropTableStatement) x);
}
@Override
public void endVisit(MySqlPartitionByKey x) {
}
@Override
public boolean visit(MySqlPartitionByKey x) {
accept(x.getColumns());
return false;
}
}
@@ -149,6 +149,8 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
public OracleSchemaStatVisitor(){
this.variants.put("DUAL", null);
this.variants.put("NOTFOUND", null);
this.variants.put("TRUE", null);
this.variants.put("FALSE", null);
}
protected Column getColumn(SQLExpr expr) {
@@ -217,6 +217,7 @@ public class SQLExprParser extends SQLParser {
case SCHEMA:
case AT:
case COLUMN:
case IF:
sqlExpr = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextToken();
break;
@@ -1090,10 +1091,6 @@ public class SQLExprParser extends SQLParser {
SQLCharactorDataType charType = new SQLCharactorDataType(dataType.getName());
charType.getArguments().addAll(dataType.getArguments());
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException("syntax error " + lexer.token() + " " + lexer.stringVal());
}
if (identifierEquals("CHARACTER")) {
lexer.nextToken();
@@ -14,6 +14,7 @@ import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLCurrentOfCursorExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.druid.sql.ast.expr.SQLInSubQueryExpr;
@@ -867,4 +868,8 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLCommentStatement x) {
return false;
}
public boolean visit(SQLCurrentOfCursorExpr x) {
return false;
}
}
@@ -32,11 +32,13 @@ public class MySqlCreateTableTest3 extends MysqlTest {
System.out.println("orderBy : " + visitor.getOrderByColumns());
Assert.assertEquals(1, visitor.getTables().size());
Assert.assertEquals(1, visitor.getColumns().size());
Assert.assertEquals(3, visitor.getColumns().size());
Assert.assertEquals(0, visitor.getConditions().size());
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("test")));
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("tk")));
Assert.assertTrue(visitor.getColumns().contains(new Column("test", "blob_col")));
Assert.assertTrue(visitor.getColumns().contains(new Column("tk", "col1")));
Assert.assertTrue(visitor.getColumns().contains(new Column("tk", "col2")));
Assert.assertTrue(visitor.getColumns().contains(new Column("tk", "col3")));
}
}