fix parse create table bug

This commit is contained in:
kiki
2014-03-03 11:29:38 +08:00
parent ff77d596d1
commit d1c5e2215a
14 changed files with 246 additions and 43 deletions
@@ -15,6 +15,7 @@
*/
package com.alibaba.druid.sql.dialect.mysql.ast;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.statement.SQLTableConstaint;
import com.alibaba.druid.sql.ast.statement.SQLUnique;
import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint;
@@ -23,7 +24,11 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class MySqlKey extends SQLUnique implements SQLUniqueConstraint, SQLTableConstaint {
private String indexType;
private SQLName indexName;
private String indexType;
private boolean hasConstaint;
public MySqlKey(){
@@ -40,6 +45,7 @@ public class MySqlKey extends SQLUnique implements SQLUniqueConstraint, SQLTable
if (visitor.visit(this)) {
acceptChild(visitor, this.getName());
acceptChild(visitor, this.getColumns());
acceptChild(visitor, indexName);
}
visitor.endVisit(this);
}
@@ -52,4 +58,20 @@ public class MySqlKey extends SQLUnique implements SQLUniqueConstraint, SQLTable
this.indexType = indexType;
}
public SQLName getIndexName() {
return indexName;
}
public void setIndexName(SQLName indexName) {
this.indexName = indexName;
}
public boolean isHasConstaint() {
return hasConstaint;
}
public void setHasConstaint(boolean hasConstaint) {
this.hasConstaint = hasConstaint;
}
}
@@ -28,6 +28,7 @@ public class MySqlUnique extends MySqlKey implements SQLPrimaryKey {
if (visitor.visit(this)) {
acceptChild(visitor, this.getName());
acceptChild(visitor, this.getColumns());
acceptChild(visitor, this.getIndexName());
}
visitor.endVisit(this);
}
@@ -0,0 +1,66 @@
/*
* 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.sql.dialect.mysql.ast;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
/**
* @author kiki
*/
public class MysqlForeignKey extends SQLForeignKeyImpl {
private SQLName indexName;
private boolean hasConstaint;
public SQLName getIndexName() {
return indexName;
}
public void setIndexName(SQLName indexName) {
this.indexName = indexName;
}
public boolean isHasConstaint() {
return hasConstaint;
}
public void setHasConstaint(boolean hasConstaint) {
this.hasConstaint = hasConstaint;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor instanceof MySqlASTVisitor) {
accept0((MySqlASTVisitor) visitor);
}
}
protected void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.getName());
acceptChild(visitor, this.getReferencedTableName());
acceptChild(visitor, this.getReferencingColumns());
acceptChild(visitor, this.getReferencedColumns());
acceptChild(visitor, indexName);
}
visitor.endVisit(this);
}
}
@@ -20,11 +20,12 @@ import com.alibaba.druid.sql.ast.statement.SQLCheck;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyConstraint;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
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.MySqlUnique;
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
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;
@@ -592,7 +593,9 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
protected SQLTableConstaint parseConstraint() {
SQLName name = null;
boolean hasConstaint = false;
if (lexer.token() == (Token.CONSTRAINT)) {
hasConstaint = true;
lexer.nextToken();
}
@@ -604,6 +607,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
lexer.nextToken();
MySqlKey key = new MySqlKey();
key.setHasConstaint(hasConstaint);
if (identifierEquals("USING")) {
lexer.nextToken();
@@ -612,7 +616,10 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
}
if (lexer.token() == Token.IDENTIFIER) {
name = this.exprParser.name();
SQLName indexName = this.exprParser.name();
if (indexName != null) {
key.setIndexName(indexName);
}
}
accept(Token.LPAREN);
@@ -640,24 +647,26 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
}
if (lexer.token() == Token.PRIMARY) {
SQLPrimaryKey pk = this.exprParser.parsePrimaryKey();
MySqlPrimaryKey pk = this.getExprParser().parsePrimaryKey();
pk.setName(name);
pk.setHasConstaint(hasConstaint);
return (SQLTableConstaint) pk;
}
if (lexer.token() == Token.UNIQUE) {
MySqlUnique uk = this.getExprParser().parseUnique();
uk.setName(name);
uk.setHasConstaint(hasConstaint);
return (SQLTableConstaint) uk;
}
if (lexer.token() == Token.FOREIGN) {
SQLForeignKeyConstraint fk = this.getExprParser().parseForeignKey();
MysqlForeignKey fk = this.getExprParser().parseForeignKey();
fk.setName(name);
fk.setHasConstaint(hasConstaint);
return (SQLTableConstaint) fk;
}
throw new ParserException("TODO :" + lexer.token());
}
}
@@ -32,9 +32,9 @@ import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
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.MySqlBinaryExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
@@ -689,7 +689,7 @@ public class MySqlExprParser extends SQLExprParser {
}
@Override
public SQLPrimaryKey parsePrimaryKey() {
public MySqlPrimaryKey parsePrimaryKey() {
accept(Token.PRIMARY);
accept(Token.KEY);
@@ -729,8 +729,8 @@ public class MySqlExprParser extends SQLExprParser {
MySqlUnique unique = new MySqlUnique();
if (lexer.token() != Token.LPAREN) {
SQLName name = name();
unique.setName(name);
SQLName indexName = name();
unique.setIndexName(indexName);
}
accept(Token.LPAREN);
@@ -753,6 +753,31 @@ public class MySqlExprParser extends SQLExprParser {
return unique;
}
public MysqlForeignKey parseForeignKey() {
accept(Token.FOREIGN);
accept(Token.KEY);
MysqlForeignKey fk = new MysqlForeignKey();
if (lexer.token() != Token.LPAREN) {
SQLName indexName = name();
fk.setIndexName(indexName);
}
accept(Token.LPAREN);
this.names(fk.getReferencingColumns());
accept(Token.RPAREN);
accept(Token.REFERENCES);
fk.setReferencedTableName(this.name());
accept(Token.LPAREN);
this.names(fk.getReferencedColumns());
accept(Token.RPAREN);
return fk;
}
protected SQLAggregateExpr parseAggregateExprRest(SQLAggregateExpr aggregateExpr) {
if (lexer.token() == Token.ORDER) {
SQLOrderBy orderBy = this.parseOrderBy();
@@ -46,7 +46,6 @@ import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateDatabaseStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyConstraint;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
@@ -57,6 +56,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.CobarShowStatus;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableAddColumn;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableChangeColumn;
@@ -1997,14 +1997,14 @@ public class MySqlStatementParser extends SQLStatementParser {
if (identifierEquals("PASSWORD")) {
lexer.nextToken();
MySqlSetPasswordStatement stmt = new MySqlSetPasswordStatement();
if (lexer.token() == Token.FOR) {
lexer.nextToken();
stmt.setUser(this.exprParser.name());
}
accept(Token.EQ);
stmt.setPassword(this.exprParser.expr());
return stmt;
@@ -2193,8 +2193,9 @@ public class MySqlStatementParser extends SQLStatementParser {
stmt.getItems().add(item);
} else if (lexer.token() == Token.FOREIGN) {
SQLForeignKeyConstraint fk = this.getExprParser().parseForeignKey();
MysqlForeignKey fk = this.getExprParser().parseForeignKey();
fk.setName(constraintName);
fk.setHasConstaint(true);
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(fk);
@@ -21,6 +21,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.MySqlUseIndexHint;
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBinaryExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
@@ -147,6 +148,10 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
void endVisit(MySqlUnique x);
boolean visit(MysqlForeignKey x);
void endVisit(MysqlForeignKey x);
void endVisit(MySqlIntervalExpr x);
boolean visit(MySqlIntervalExpr x);
@@ -558,8 +563,8 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
boolean visit(MySqlOptimizeStatement x);
void endVisit(MySqlOptimizeStatement x);
boolean visit(MySqlSetPasswordStatement x);
void endVisit(MySqlSetPasswordStatement x);
} //
@@ -21,6 +21,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.MySqlUseIndexHint;
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBinaryExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
@@ -1108,6 +1109,16 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq
}
@Override
public boolean visit(MysqlForeignKey x) {
return true;
}
@Override
public void endVisit(MysqlForeignKey x) {
}
@Override
public boolean visit(MySqlAlterTableModifyColumn x) {
return true;
@@ -1237,14 +1248,15 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq
public void endVisit(MySqlOptimizeStatement x) {
}
@Override
public boolean visit(MySqlSetPasswordStatement x) {
return true;
}
@Override
public void endVisit(MySqlSetPasswordStatement x) {
}
} //
@@ -43,6 +43,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.MySqlUseIndexHint;
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBinaryExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
@@ -300,7 +301,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
if (x.getDefaultExpr() instanceof SQLNullExpr) {
print(" NULL");
} else {
print(" DEFAULT");
print(" DEFAULT ");
x.getDefaultExpr().accept(this);
}
}
@@ -324,7 +325,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print(' ');
item.accept(this);
}
if (x.getComment() != null) {
print(" COMMENT ");
x.getComment().accept(this);
@@ -510,16 +511,28 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
@Override
public void endVisit(MysqlForeignKey x) {
}
@Override
public boolean visit(MySqlKey x) {
if (x.getName() != null) {
if (x.isHasConstaint()) {
print("CONSTRAINT ");
x.getName().accept(this);
print(' ');
if (x.getName() != null) {
x.getName().accept(this);
print(' ');
}
}
print("KEY");
if (x.getIndexName() != null) {
print(' ');
x.getIndexName().accept(this);
}
if (x.getIndexType() != null) {
print(" USING ");
print(x.getIndexType());
@@ -2797,14 +2810,21 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
@Override
public boolean visit(MySqlUnique x) {
if (x.getName() != null) {
if (x.isHasConstaint()) {
print("CONSTRAINT ");
x.getName().accept(this);
print(' ');
if (x.getName() != null) {
x.getName().accept(this);
print(' ');
}
}
print("UNIQUE");
if (x.getIndexName() != null) {
print(' ');
x.getIndexName().accept(this);
}
if (x.getIndexType() != null) {
print(" USING ");
print(x.getIndexType());
@@ -2817,6 +2837,36 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
return false;
}
@Override
public boolean visit(MysqlForeignKey x) {
if (x.isHasConstaint()) {
print("CONSTRAINT ");
if (x.getName() != null) {
x.getName().accept(this);
print(' ');
}
}
print("FOREIGN KEY");
if (x.getIndexName() != null) {
print(' ');
x.getIndexName().accept(this);
}
print(" (");
printAndAccept(x.getReferencingColumns(), ", ");
print(")");
print(" REFERENCES ");
x.getReferencedTableName().accept(this);
print(" (");
printAndAccept(x.getReferencedColumns(), ", ");
print(")");
return false;
}
@Override
public void endVisit(MySqlUnique x) {
@@ -3008,15 +3058,15 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
@Override
public boolean visit(MySqlSetPasswordStatement x) {
print("SET PASSWORD ");
if (x.getUser() != null){
if (x.getUser() != null) {
print("FOR ");
x.getUser().accept(this);
print(' ');
}
print("= ");
if (x.getPassword() != null) {
x.getPassword().accept(this);
}
@@ -3025,7 +3075,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
@Override
public void endVisit(MySqlSetPasswordStatement x) {
}
} //
@@ -35,6 +35,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.MySqlUseIndexHint;
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBinaryExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
@@ -1204,6 +1205,16 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
}
@Override
public boolean visit(MysqlForeignKey x) {
return super.visit(x);
}
@Override
public void endVisit(MysqlForeignKey x) {
}
@Override
public boolean visit(MySqlAlterTableDiscardTablespace x) {
return false;
@@ -1323,15 +1334,15 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
public void endVisit(MySqlOptimizeStatement x) {
}
@Override
public boolean visit(MySqlSetPasswordStatement x) {
return false;
}
@Override
public void endVisit(MySqlSetPasswordStatement x) {
}
}
@@ -1681,7 +1681,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
}
print("FOREIGN KEY (");
printAndAccept(x.getReferencedColumns(), ", ");
printAndAccept(x.getReferencingColumns(), ", ");
print(")");
print(" REFERENCES ");
@@ -38,7 +38,7 @@ public class If implements Function {
SQLExpr condition = parameters.get(0);
condition.accept(visitor);
Object itemValue = condition.getAttributes().get(EVAL_VALUE);
if (Boolean.TRUE == itemValue || !SQLEvalVisitorUtils.eq(itemValue, 0)) {
if (Boolean.TRUE == itemValue || (itemValue != null && !SQLEvalVisitorUtils.eq(itemValue, 0))) {
SQLExpr trueExpr = parameters.get(1);
trueExpr.accept(visitor);
return trueExpr.getAttributes().get(EVAL_VALUE);