From d1c5e2215a9688f43e28a7767b00f62531f852d6 Mon Sep 17 00:00:00 2001 From: kiki Date: Mon, 3 Mar 2014 11:29:38 +0800 Subject: [PATCH] fix parse create table bug --- .../druid/sql/dialect/mysql/ast/MySqlKey.java | 24 +++++- .../sql/dialect/mysql/ast/MySqlUnique.java | 1 + .../dialect/mysql/ast/MysqlForeignKey.java | 66 ++++++++++++++++ .../mysql/parser/MySqlCreateTableParser.java | 21 +++-- .../dialect/mysql/parser/MySqlExprParser.java | 33 +++++++- .../mysql/parser/MySqlStatementParser.java | 11 +-- .../mysql/visitor/MySqlASTVisitor.java | 9 ++- .../mysql/visitor/MySqlASTVisitorAdapter.java | 18 ++++- .../mysql/visitor/MySqlOutputVisitor.java | 76 +++++++++++++++---- .../mysql/visitor/MySqlSchemaStatVisitor.java | 17 ++++- .../sql/visitor/SQLASTOutputVisitor.java | 2 +- .../druid/sql/visitor/functions/If.java | 2 +- .../sql/mysql/MySqlAlterTableTest_addFk.java | 5 +- .../bvt/sql/mysql/MySqlCreateTableTest48.java | 4 +- 14 files changed, 246 insertions(+), 43 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/MysqlForeignKey.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/MySqlKey.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/MySqlKey.java index 266e01e3c5..b0dc3d85c4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/MySqlKey.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/MySqlKey.java @@ -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; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/MySqlUnique.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/MySqlUnique.java index 8cc7f7cc58..a7d20e1331 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/MySqlUnique.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/MySqlUnique.java @@ -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); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/MysqlForeignKey.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/MysqlForeignKey.java new file mode 100644 index 0000000000..3335e959f8 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/MysqlForeignKey.java @@ -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); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java index a63df80f61..ed5147a5d8 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java @@ -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()); } - } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java index 2359790499..ec4b3de137 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java @@ -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(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index 8c82816f75..1a914c7485 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -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); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java index b44531064f..f42ae9138d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java @@ -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); } // diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java index e18f3d2ccc..fa166fbd0f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java @@ -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) { - + } + } // diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index 6f11ba6a0a..d4d9d6033f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -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) { - + } } // diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java index 07081d3974..68b9d0265a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java @@ -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) { - + } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 9dcd84ebdf..cae14c8ca4 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -1681,7 +1681,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab } print("FOREIGN KEY ("); - printAndAccept(x.getReferencedColumns(), ", "); + printAndAccept(x.getReferencingColumns(), ", "); print(")"); print(" REFERENCES "); diff --git a/src/main/java/com/alibaba/druid/sql/visitor/functions/If.java b/src/main/java/com/alibaba/druid/sql/visitor/functions/If.java index b01cb90e39..243f7ca1b5 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/functions/If.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/functions/If.java @@ -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); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest_addFk.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest_addFk.java index 9dbbe04c15..e2c5f4b99b 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest_addFk.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlAlterTableTest_addFk.java @@ -44,8 +44,9 @@ public class MySqlAlterTableTest_addFk extends TestCase { String output = SQLUtils.toMySqlString(stmt); Assert.assertEquals("ALTER TABLE Test2" + // - "\n\tADD INDEX FK4CF5DC0F5DD7C31 (test1_name)," + // - "\n\tADD CONSTRAINT FK4CF5DC0F5DD7C31 FOREIGN KEY (name) REFERENCES Test1 (name)", output); + "\n\tADD INDEX FK4CF5DC0F5DD7C31 (test1_name)," + // + "\n\tADD CONSTRAINT FK4CF5DC0F5DD7C31 FOREIGN KEY (test1_name) REFERENCES Test1 (name)", + output); Assert.assertEquals(2, visitor.getTables().size()); Assert.assertEquals(3, visitor.getColumns().size()); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTableTest48.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTableTest48.java index 0a0ec2c7d8..f1e790eea8 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTableTest48.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTableTest48.java @@ -58,8 +58,8 @@ public class MySqlCreateTableTest48 extends MysqlTest { + "\n\tCHANGESET_ID INTEGER, "// + "\n\tID INTEGER AUTO_INCREMENT NOT NULL, "// + "\n\tREPOSITORY_ID INTEGER, "// - + "\n\tCONSTRAINT fk_ao_e8b6cc_repo_to_changeset_repository_id FOREIGN KEY (ID) REFERENCES AO_E8B6CC_REPOSITORY_MAPPING (ID), "// - + "\n\tCONSTRAINT fk_ao_e8b6cc_repo_to_changeset_changeset_id FOREIGN KEY (ID) REFERENCES AO_E8B6CC_CHANGESET_MAPPING (ID), "// + + "\n\tCONSTRAINT fk_ao_e8b6cc_repo_to_changeset_repository_id FOREIGN KEY (REPOSITORY_ID) REFERENCES AO_E8B6CC_REPOSITORY_MAPPING (ID), "// + + "\n\tCONSTRAINT fk_ao_e8b6cc_repo_to_changeset_changeset_id FOREIGN KEY (CHANGESET_ID) REFERENCES AO_E8B6CC_CHANGESET_MAPPING (ID), "// + "\n\tPRIMARY KEY (ID)"// + "\n) ENGINE = InnoDB",// output);