mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
bug fixed for sql parser
This commit is contained in:
@@ -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 {
|
||||
|
||||
}
|
||||
|
||||
+14
-3
@@ -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;
|
||||
}
|
||||
|
||||
+45
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+42
-13
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -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")));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user