From adada50173f58997a5148c9472e73f74b6348828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AB=98=E9=93=81?= Date: Wed, 13 Jan 2016 09:16:25 +0800 Subject: [PATCH] improved mysql parser for 'create procedure statement support' --- .../SQLDeclareItem.java} | 10 +-- .../SQLCreateProcedureStatement.java | 12 +++ .../ast/clause/MySqlDeclareStatement.java | 58 +++++-------- .../mysql/parser/MySqlStatementParser.java | 87 ++++++++++--------- .../mysql/visitor/MySqlOutputVisitor.java | 16 ++-- .../mysql/visitor/MySqlSchemaStatVisitor.java | 9 +- .../ast/stmt/SQLServerDeclareStatement.java | 8 +- .../parser/SQLServerStatementParser.java | 10 +-- .../visitor/SQLServerASTVisitor.java | 5 -- .../visitor/SQLServerASTVisitorAdapter.java | 11 --- .../visitor/SQLServerOutputVisitor.java | 43 --------- .../visitor/SQLServerSchemaStatVisitor.java | 14 +-- .../sql/visitor/SQLASTOutputVisitor.java | 53 ++++++++++- .../druid/sql/visitor/SQLASTVisitor.java | 5 ++ .../sql/visitor/SQLASTVisitorAdapter.java | 10 +++ .../druid/sql/visitor/SchemaStatVisitor.java | 6 ++ .../sql/mysql/MySqlCreateProcedureTest7.java | 73 ++++++++++++++++ .../bvt/sql/mysql/MySqlCreateTableTest60.java | 46 ++++++++++ 18 files changed, 300 insertions(+), 176 deletions(-) rename src/main/java/com/alibaba/druid/sql/{dialect/sqlserver/ast/SQLServerDeclareItem.java => ast/SQLDeclareItem.java} (86%) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest7.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTableTest60.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/SQLServerDeclareItem.java b/src/main/java/com/alibaba/druid/sql/ast/SQLDeclareItem.java similarity index 86% rename from src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/SQLServerDeclareItem.java rename to src/main/java/com/alibaba/druid/sql/ast/SQLDeclareItem.java index bd3a2e78c9..4d1bb60cdd 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/SQLServerDeclareItem.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLDeclareItem.java @@ -13,17 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.druid.sql.dialect.sqlserver.ast; +package com.alibaba.druid.sql.ast; import java.util.ArrayList; import java.util.List; -import com.alibaba.druid.sql.ast.SQLDataType; -import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.statement.SQLTableElement; -import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; -public class SQLServerDeclareItem extends SQLServerObjectImpl { +public class SQLDeclareItem extends SQLObjectImpl { protected Type type; @@ -36,7 +34,7 @@ public class SQLServerDeclareItem extends SQLServerObjectImpl { protected List tableElementList = new ArrayList(); @Override - public void accept0(SQLServerASTVisitor visitor) { + protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, this.name); acceptChild(visitor, this.dataType); diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateProcedureStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateProcedureStatement.java index 63519fa99b..0437d5bef7 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateProcedureStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateProcedureStatement.java @@ -26,6 +26,8 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLCreateProcedureStatement extends SQLStatementImpl { + private SQLName definer; + private boolean orReplace; private SQLName name; private SQLStatement block; @@ -34,6 +36,7 @@ public class SQLCreateProcedureStatement extends SQLStatementImpl { @Override public void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { + acceptChild(visitor, definer); acceptChild(visitor, name); acceptChild(visitor, parameters); acceptChild(visitor, block); @@ -73,4 +76,13 @@ public class SQLCreateProcedureStatement extends SQLStatementImpl { this.orReplace = orReplace; } + public SQLName getDefiner() { + return definer; + } + + + public void setDefiner(SQLName definer) { + this.definer = definer; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlDeclareStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlDeclareStatement.java index 2c0ceffde6..c63e6b2e22 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlDeclareStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlDeclareStatement.java @@ -18,54 +18,40 @@ package com.alibaba.druid.sql.dialect.mysql.ast.clause; import java.util.ArrayList; import java.util.List; -import com.alibaba.druid.sql.ast.SQLDataType; -import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLDeclareItem; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStatementImpl; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; + /** - * * @Description: MySql declare statement * @author zz email:455910092@qq.com * @date 2015-9-14 * @version V1.0 */ -public class MySqlDeclareStatement extends MySqlStatementImpl{ - - //var type - private SQLDataType type; - //var list - private List varList=new ArrayList(); - +public class MySqlDeclareStatement extends MySqlStatementImpl { - public List getVarList() { - return varList; - } - public void addVar(SQLExpr expr) - { - varList.add(expr); - } + private List varList = new ArrayList(); - public void setVarList(List varList) { - this.varList = varList; - } + public List getVarList() { + return varList; + } - public SQLDataType getType() { - return type; - } + public void addVar(SQLDeclareItem expr) { + varList.add(expr); + } - public void setType(SQLDataType type) { - this.type = type; - } + public void setVarList(List varList) { + this.varList = varList; + } - @Override - public void accept0(MySqlASTVisitor visitor) { - // TODO Auto-generated method stub - if (visitor.visit(this)) { - acceptChild(visitor, type); - acceptChild(visitor, varList); - } - visitor.endVisit(this); - - } + @Override + public void accept0(MySqlASTVisitor visitor) { + // TODO Auto-generated method stub + if (visitor.visit(this)) { + acceptChild(visitor, varList); + } + visitor.endVisit(this); + + } } 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 3e7ae247d9..278c428fc9 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 @@ -20,6 +20,7 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLCommentHint; import com.alibaba.druid.sql.ast.SQLDataTypeImpl; +import com.alibaba.druid.sql.ast.SQLDeclareItem; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLOrderBy; @@ -29,7 +30,6 @@ import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; import com.alibaba.druid.sql.ast.expr.SQLCharExpr; -import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLNCharExpr; @@ -378,7 +378,7 @@ public class MySqlStatementParser extends SQLStatementParser { return parseCreateTrigger(); } //parse create procedure - if (lexer.token() == Token.PROCEDURE) { + if (lexer.token() == Token.PROCEDURE || identifierEquals("DEFINER")) { if (replace) { lexer.reset(markBp, markChar, Token.CREATE); } @@ -2765,12 +2765,19 @@ public class MySqlStatementParser extends SQLStatementParser { */ SQLCreateProcedureStatement stmt = new SQLCreateProcedureStatement(); - accept(Token.CREATE); - if (lexer.token() == Token.OR) { - lexer.nextToken(); - accept(Token.REPLACE); - stmt.setOrReplace(true); - } + if(identifierEquals("DEFINER")) { + lexer.nextToken(); + accept(Token.EQ); + SQLName definer = this.exprParser.name(); + stmt.setDefiner(definer); + } else { + accept(Token.CREATE); + if (lexer.token() == Token.OR) { + lexer.nextToken(); + accept(Token.REPLACE); + stmt.setOrReplace(true); + } + } accept(Token.PROCEDURE); @@ -2793,6 +2800,10 @@ public class MySqlStatementParser extends SQLStatementParser { * @param parameters */ private void parserParameters(List parameters) { + if (lexer.token() == Token.RPAREN) { + return; + } + for (;;) { SQLParameter parameter = new SQLParameter(); @@ -3264,37 +3275,35 @@ public class MySqlStatementParser extends SQLStatementParser { /** * parse declare statement */ - public MySqlDeclareStatement parseDeclare() - { - MySqlDeclareStatement stmt=new MySqlDeclareStatement(); - accept(Token.DECLARE); - //lexer.nextToken(); - for(;;) - { - SQLExpr var = exprParser.primary(); - if (var instanceof SQLIdentifierExpr) { - var = new SQLVariantRefExpr(((SQLIdentifierExpr) var).getName()); - } - stmt.addVar(var); - if(lexer.token()==Token.COMMA) - { - accept(Token.COMMA); - continue; - } - else if(lexer.token()!=Token.EOF) - { - //var type - stmt.setType(exprParser.parseDataType()); - break; - } - else - { - setErrorEndPos(lexer.pos()); - printError(lexer.token()); - } - } - return stmt; - } + public MySqlDeclareStatement parseDeclare() { + MySqlDeclareStatement stmt = new MySqlDeclareStatement(); + accept(Token.DECLARE); + // lexer.nextToken(); + for (;;) { + SQLDeclareItem item = new SQLDeclareItem(); + item.setName(exprParser.name()); + + stmt.addVar(item); + if (lexer.token() == Token.COMMA) { + accept(Token.COMMA); + continue; + } else if (lexer.token() != Token.EOF) { + // var type + item.setDataType(exprParser.parseDataType()); + + if (lexer.token() == Token.DEFAULT) { + lexer.nextToken(); + SQLExpr defaultValue = this.exprParser.primary(); + item.setValue(defaultValue); + } + + break; + } else { + throw new ParserException("TODO"); + } + } + return stmt; + } /** * parse assign statement 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 36d908850a..04865229c3 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 @@ -164,8 +164,12 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatem import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateTableSource; import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; +import com.alibaba.druid.util.JdbcConstants; public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTVisitor { + { + this.dbType = JdbcConstants.MYSQL; + } public MySqlOutputVisitor(Appendable appender){ super(appender); @@ -3179,8 +3183,8 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV int paramSize = x.getParameters().size(); + print0(" ("); if (paramSize > 0) { - print0(" ("); incrementIndent(); println(); @@ -3195,8 +3199,8 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV decrementIndent(); println(); - print(')'); } + print(')'); println(); x.getBlock().setParent(x); @@ -3317,13 +3321,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public boolean visit(MySqlDeclareStatement x) { print0(ucase ? "DECLARE " : "declare "); - for (int i = 0; i < x.getVarList().size(); i++) { - x.getVarList().get(i).accept(this); - if(i!=x.getVarList().size()-1) - print0(", "); - } - print(' '); - x.getType().accept(this); + printAndAccept(x.getVarList(), ", "); return false; } 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 5381ab39e5..e5875a105a 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 @@ -17,11 +17,10 @@ package com.alibaba.druid.sql.dialect.mysql.visitor; import java.util.Map; -import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLDeclareItem; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; -import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; @@ -1359,11 +1358,11 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public boolean visit(MySqlDeclareStatement x) { - for (SQLExpr item : x.getVarList()) { + for (SQLDeclareItem item : x.getVarList()) { item.setParent(x); - SQLVariantRefExpr var = (SQLVariantRefExpr)item; - this.variants.put(var.getName(), var); + SQLName var = (SQLName)item.getName(); + this.variants.put(var.toString(), var); } return false; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerDeclareStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerDeclareStatement.java index f35aa8824b..d979b82481 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerDeclareStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerDeclareStatement.java @@ -18,14 +18,14 @@ package com.alibaba.druid.sql.dialect.sqlserver.ast.stmt; import java.util.ArrayList; import java.util.List; -import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem; +import com.alibaba.druid.sql.ast.SQLDeclareItem; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerObjectImpl; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerStatement; import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor; public class SQLServerDeclareStatement extends SQLServerObjectImpl implements SQLServerStatement { - protected List items = new ArrayList(); + protected List items = new ArrayList(); private String dbType; @@ -37,11 +37,11 @@ public class SQLServerDeclareStatement extends SQLServerObjectImpl implements SQ visitor.endVisit(this); } - public List getItems() { + public List getItems() { return items; } - public void setItems(List items) { + public void setItems(List items) { this.items = items; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java index b0e7d06158..7438b256eb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java @@ -21,6 +21,7 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.ast.SQLDeclareItem; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; @@ -34,7 +35,6 @@ import com.alibaba.druid.sql.ast.statement.SQLSetStatement; import com.alibaba.druid.sql.ast.statement.SQLTableElement; import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; -import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; @@ -171,7 +171,7 @@ public class SQLServerStatementParser extends SQLStatementParser { SQLServerDeclareStatement declareStatement = new SQLServerDeclareStatement(); for (;;) { - SQLServerDeclareItem item = new SQLServerDeclareItem(); + SQLDeclareItem item = new SQLDeclareItem(); declareStatement.getItems().add(item); item.setName(this.exprParser.name()); @@ -182,7 +182,7 @@ public class SQLServerStatementParser extends SQLStatementParser { if (lexer.token() == Token.TABLE) { lexer.nextToken(); - item.setType(SQLServerDeclareItem.Type.TABLE); + item.setType(SQLDeclareItem.Type.TABLE); if (lexer.token() == Token.LPAREN) { lexer.nextToken(); @@ -221,10 +221,10 @@ public class SQLServerStatementParser extends SQLStatementParser { } break; } else if (lexer.token() == Token.CURSOR) { - item.setType(SQLServerDeclareItem.Type.CURSOR); + item.setType(SQLDeclareItem.Type.CURSOR); lexer.nextToken(); } else { - item.setType(SQLServerDeclareItem.Type.LOCAL); + item.setType(SQLDeclareItem.Type.LOCAL); item.setDataType(this.exprParser.parseDataType()); if (lexer.token() == Token.EQ) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java index 33313ebc5b..eca77bd87a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java @@ -16,7 +16,6 @@ package com.alibaba.druid.sql.dialect.sqlserver.visitor; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition; -import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; @@ -79,10 +78,6 @@ public interface SQLServerASTVisitor extends SQLASTVisitor { boolean visit(SQLServerOutput x); void endVisit(SQLServerOutput x); - - boolean visit(SQLServerDeclareItem x); - - void endVisit(SQLServerDeclareItem x); boolean visit(SQLServerDeclareStatement x); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java index 1bfb3350cc..4d24ffe090 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java @@ -16,7 +16,6 @@ package com.alibaba.druid.sql.dialect.sqlserver.visitor; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition; -import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; @@ -146,16 +145,6 @@ public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements } - @Override - public boolean visit(SQLServerDeclareItem x) { - return true; - } - - @Override - public void endVisit(SQLServerDeclareItem x) { - - } - @Override public boolean visit(SQLServerDeclareStatement x) { return true; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java index e27f57b7d2..5a08027a6d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java @@ -26,7 +26,6 @@ import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLGrantStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition.Identity; -import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; @@ -429,48 +428,6 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe } - @Override - public boolean visit(SQLServerDeclareItem x) { - x.getName().accept(this); - - if(x.getType() == SQLServerDeclareItem.Type.TABLE) { - print0(ucase ? " TABLE" : " table"); - int size = x.getTableElementList().size(); - - if (size > 0) { - print0(" ("); - incrementIndent(); - println(); - for (int i = 0; i < size; ++i) { - if (i != 0) { - print(','); - println(); - } - x.getTableElementList().get(i).accept(this); - } - decrementIndent(); - println(); - print(')'); - } - } else if (x.getType() == SQLServerDeclareItem.Type.CURSOR) { - print0(ucase ? " CURSOR" : " cursor"); - } else { - print(' '); - x.getDataType().accept(this); - if (x.getValue() != null) { - print0(" = "); - x.getValue().accept(this); - } - } - - return false; - } - - @Override - public void endVisit(SQLServerDeclareItem x) { - - } - @Override public boolean visit(SQLServerDeclareStatement x) { print0(ucase ? "DECLARE " : "declare "); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java index 7b3444425f..e51b0a010e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java @@ -17,13 +17,13 @@ package com.alibaba.druid.sql.dialect.sqlserver.visitor; import java.util.Map; +import com.alibaba.druid.sql.ast.SQLDeclareItem; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerColumnDefinition.Identity; -import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerDeclareItem; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerOutput; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelect; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; @@ -176,19 +176,9 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL } - @Override - public boolean visit(SQLServerDeclareItem x) { - return false; - } - - @Override - public void endVisit(SQLServerDeclareItem x) { - - } - @Override public boolean visit(SQLServerDeclareStatement x) { - for (SQLServerDeclareItem item : x.getItems()) { + for (SQLDeclareItem item : x.getItems()) { item.setParent(x); SQLExpr name = item.getName(); 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 f4224ef1e2..97636c8251 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -28,6 +28,7 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLCommentHint; import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.ast.SQLDeclareItem; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.SQLOrderBy; @@ -166,6 +167,7 @@ import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.ast.statement.SQLUseStatement; import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause; +import com.alibaba.druid.util.JdbcConstants; public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements PrintableVisitor { @@ -178,7 +180,9 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab protected boolean groupItemSingleLine = false; - private List parameters; + private List parameters; + + protected String dbType; public SQLASTOutputVisitor(Appendable appender){ this.appender = appender; @@ -2614,6 +2618,53 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab return false; } + + @Override + public boolean visit(SQLDeclareItem x) { + x.getName().accept(this); + + if(x.getType() == SQLDeclareItem.Type.TABLE) { + print0(ucase ? " TABLE" : " table"); + int size = x.getTableElementList().size(); + + if (size > 0) { + print0(" ("); + incrementIndent(); + println(); + for (int i = 0; i < size; ++i) { + if (i != 0) { + print(','); + println(); + } + x.getTableElementList().get(i).accept(this); + } + decrementIndent(); + println(); + print(')'); + } + } else if (x.getType() == SQLDeclareItem.Type.CURSOR) { + print0(ucase ? " CURSOR" : " cursor"); + } else { + if (x.getDataType() != null) { + print(' '); + x.getDataType().accept(this); + } + if (x.getValue() != null) { + if (JdbcConstants.MYSQL.equals(getDbType())) { + print0(ucase ? " DEFAULT " : " default "); + } else { + print0(" = "); + } + x.getValue().accept(this); + } + } + + return false; + } + + public String getDbType() { + return dbType; + } public boolean isUppCase() { return ucase; diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java index c399b9169f..6bdbbfa98b 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java @@ -17,6 +17,7 @@ package com.alibaba.druid.sql.visitor; import com.alibaba.druid.sql.ast.SQLCommentHint; import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.ast.SQLDeclareItem; import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.SQLOrderBy; import com.alibaba.druid.sql.ast.SQLOver; @@ -681,4 +682,8 @@ public interface SQLASTVisitor { boolean visit(SQLAlterTableDropKey x); void endVisit(SQLAlterTableDropKey x); + + boolean visit(SQLDeclareItem x); + + void endVisit(SQLDeclareItem x); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java index 042f394c1d..7f81012b68 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java @@ -17,6 +17,7 @@ package com.alibaba.druid.sql.visitor; import com.alibaba.druid.sql.ast.SQLCommentHint; import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.ast.SQLDeclareItem; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.SQLOrderBy; @@ -1365,5 +1366,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { public void endVisit(SQLAlterTableDropKey x) { } + + @Override + public boolean visit(SQLDeclareItem x) { + return true; + } + + @Override + public void endVisit(SQLDeclareItem x) { + } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index 6d79f59543..b5e79a14f4 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import com.alibaba.druid.sql.ast.SQLDeclareItem; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObject; @@ -1445,4 +1446,9 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { public boolean visit(SQLShowTablesStatement x) { return false; } + + @Override + public boolean visit(SQLDeclareItem x) { + return false; + } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest7.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest7.java new file mode 100644 index 0000000000..e9068490f8 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest7.java @@ -0,0 +1,73 @@ +/* + * Copyright 1999-2101 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; +import com.alibaba.druid.stat.TableStat.Column; + +/** + * + * @Description: create procedure parameter type support + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 + */ +public class MySqlCreateProcedureTest7 extends MysqlTest { + + public void test_0() throws Exception { + String sql="CREATE DEFINER=test@% PROCEDURE test11111()" + + "\nBEGIN" + + "\ndeclare v_a date default '2007-4-10';" + + "\ndeclare v_b date default '2007-4-11';" + + "\ndeclare v_c datetime default '2004-4-9 0:0:0';" + + "\nEND"; + + MySqlStatementParser parser=new MySqlStatementParser(sql); + List 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()); + + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("CREATE PROCEDURE test11111 ()" + + "\nBEGIN" + + "\n\tDECLARE v_a date DEFAULT '2007-4-10';" + + "\n\tDECLARE v_b date DEFAULT '2007-4-11';" + + "\n\tDECLARE v_c datetime DEFAULT '2004-4-9 0:0:0';" + + "\nEND", output); + + Assert.assertEquals(0, visitor.getTables().size()); + Assert.assertEquals(0, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTableTest60.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTableTest60.java new file mode 100644 index 0000000000..cb9e57b070 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateTableTest60.java @@ -0,0 +1,46 @@ +/* + * Copyright 1999-2101 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 org.junit.Assert; +import org.junit.Test; + +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; + +public class MySqlCreateTableTest60 extends MysqlTest { + + @Test + public void test_one() throws Exception { + String sql = "create table t10 (pk int auto_increment primary key,f1 varchar(65500) charset latin1);"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseCreateTable(); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("CREATE TABLE t10 (" + + "\n\tpk int PRIMARY KEY AUTO_INCREMENT, " + + "\n\tf1 varchar(65500) CHARSET latin1 " + + "\n)", output); + + } +}