From dc45cd0a9227b6faee0ccfba7d8037a34c2ab628 Mon Sep 17 00:00:00 2001 From: zhujunxxxxx <455910092@qq.com> Date: Sun, 20 Sep 2015 19:37:17 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0mysql=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E8=BF=87=E7=A8=8B=E6=97=B6=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E5=8F=AF=E9=80=89=E7=B1=BB=E5=9E=8BIN|OUT|INOUT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mysql/ast/clause/MySqlParameter.java | 21 ++- .../mysql/parser/MySqlStatementParser.java | 22 +++ .../mysql/visitor/MySqlOutputVisitor.java | 14 ++ .../alibaba/druid/sql/parser/Keywords.java | 4 +- .../com/alibaba/druid/sql/parser/Token.java | 4 +- .../sql/mysql/MySqlCreateProcedureTest6.java | 155 ++++++++++++++++++ 6 files changed, 217 insertions(+), 3 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest6.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlParameter.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlParameter.java index a2e88da6d7..df9f3e1621 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlParameter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlParameter.java @@ -32,8 +32,17 @@ public class MySqlParameter extends MySqlObjectImpl { private SQLExpr name; private SQLDataType dataType; private SQLExpr defaultValue; + private ParameterType paramType; - public SQLExpr getDefaultValue() { + public ParameterType getParamType() { + return paramType; + } + + public void setParamType(ParameterType paramType) { + this.paramType = paramType; + } + + public SQLExpr getDefaultValue() { return defaultValue; } @@ -66,5 +75,15 @@ public class MySqlParameter extends MySqlObjectImpl { } visitor.endVisit(this); } + /** + * mysql procedure parameter type + */ + public static enum ParameterType + { + DEFAULT, + IN,//in + OUT,//out + INOUT//inout + } } 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 05d54819e6..c096f330b5 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 @@ -73,6 +73,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIterateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLeaveStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLoopStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlParameter; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlParameter.ParameterType; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlRepeatStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlWhileStatement; @@ -2785,7 +2786,28 @@ public class MySqlStatementParser extends SQLStatementParser { parameter.setDataType(dataType); parameter.setDefaultValue(new SQLQueryExpr(select)); + + } else if (lexer.token() == Token.IN || lexer.token() == Token.OUT || lexer.token() == Token.INOUT) { + + if(lexer.token()==Token.IN) + { + parameter.setParamType(ParameterType.IN); + } + else if(lexer.token()==Token.OUT) + { + parameter.setParamType(ParameterType.OUT); + } + else if(lexer.token()==Token.INOUT) + { + parameter.setParamType(ParameterType.INOUT); + } + lexer.nextToken(); + + parameter.setName(this.exprParser.name()); + + parameter.setDataType(this.exprParser.parseDataType()); } else { + parameter.setParamType(ParameterType.DEFAULT);//default parameter type is in parameter.setName(this.exprParser.name()); parameter.setDataType(this.exprParser.parseDataType()); 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 5ef99443f0..12e0b106ab 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 @@ -59,6 +59,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIterateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLeaveStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLoopStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlParameter; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlParameter.ParameterType; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlRepeatStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlWhileStatement; @@ -3277,6 +3278,19 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV decrementIndent(); } else { + + if(x.getParamType()==ParameterType.IN) + { + print("IN "); + } + else if(x.getParamType()==ParameterType.OUT) + { + print("OUT "); + } + else if(x.getParamType()==ParameterType.INOUT) + { + print("INOUT "); + } x.getName().accept(this); print(" "); diff --git a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java index 5b0eb2f6cd..5bcc6f3dab 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java @@ -135,7 +135,7 @@ public class Keywords { map.put("GRANT", Token.GRANT); map.put("REVOKE", Token.REVOKE); - // MySql procedure by:zz + // MySql procedure: add by zz map.put("WHILE", Token.WHILE); map.put("DO", Token.DO); map.put("DECLARE", Token.DECLARE); @@ -148,6 +148,8 @@ public class Keywords { map.put("CLOSE", Token.CLOSE); map.put("CURSOR", Token.CURSOR); map.put("FETCH", Token.FETCH); + map.put("OUT", Token.OUT); + map.put("INOUT", Token.INOUT); DEFAULT_KEYWORDS = new Keywords(map); } diff --git a/src/main/java/com/alibaba/druid/sql/parser/Token.java b/src/main/java/com/alibaba/druid/sql/parser/Token.java index 8e0d0e3b80..c3e97136bb 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -128,7 +128,7 @@ public enum Token { SHOW("SHOW"), REPLACE("REPLACE"), - // MySql procedure by:zz + // MySql procedure add by zz WHILE("WHILE"), DO("DO"), LEAVE("LEAVE"), @@ -137,6 +137,8 @@ public enum Token { UNTIL("UNTIL"), OPEN("OPEN"), CLOSE("CLOSE"), + OUT("OUT"), + INOUT("INOUT"), //postgresql WINDOW("WINDOW"), diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest6.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest6.java new file mode 100644 index 0000000000..026eea9d66 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest6.java @@ -0,0 +1,155 @@ +/* + * 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.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 MySqlCreateProcedureTest6 extends MysqlTest { + + public void test_0() throws Exception { + String sql="create or replace procedure sp_name(level int,age int)"+ + " begin"+ + " insert into test values(id,age);"+ + " end"; + + MySqlStatementParser parser=new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + statemen.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()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(2, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("test"))); + + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "id"))); + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "age"))); + } + public void test_1() throws Exception { + String sql="create or replace procedure sp_name(in level int,in age int)"+ + " begin"+ + " insert into test values(id,age);"+ + " end"; + + MySqlStatementParser parser=new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + statemen.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()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(2, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("test"))); + + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "id"))); + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "age"))); + } + public void test_2() throws Exception { + String sql="create or replace procedure sp_name(out level int,out age int)"+ + " begin"+ + " insert into test values(id,age);"+ + " end"; + + MySqlStatementParser parser=new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + statemen.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()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(2, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("test"))); + + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "id"))); + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "age"))); + } + public void test_3() throws Exception { + String sql="create or replace procedure sp_name(inout level int,inout age int)"+ + " begin"+ + " insert into test values(id,age);"+ + " end"; + + MySqlStatementParser parser=new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + statemen.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()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(2, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("test"))); + + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "id"))); + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "age"))); + } + +} From 1150f45f396a99839fc877c958a74fb05e0d7ded Mon Sep 17 00:00:00 2001 From: zhujunxxxxx <455910092@qq.com> Date: Mon, 21 Sep 2015 21:24:22 +0800 Subject: [PATCH 2/2] fixed issue#949 --- .../ast/stmt/SQLServerExecStatement.java | 47 +++++++++++++++--- .../parser/SQLServerStatementParser.java | 48 +++++++++++++++++-- .../visitor/SQLServerASTVisitor.java | 5 ++ .../visitor/SQLServerASTVisitorAdapter.java | 13 +++++ .../visitor/SQLServerOutputVisitor.java | 18 +++++++ .../visitor/SQLServerSchemaStatVisitor.java | 13 +++++ .../bvt/sql/sqlserver/SQLServerExec_Test.java | 24 ++++++++++ 7 files changed, 158 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerExecStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerExecStatement.java index 43faa2d97d..1395ca92b4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerExecStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerExecStatement.java @@ -1,8 +1,3 @@ -package com.alibaba.druid.sql.dialect.sqlserver.ast.stmt; - -import java.util.ArrayList; -import java.util.List; - /* * Copyright 1999-2101 Alibaba Group Holding Ltd. * @@ -18,6 +13,11 @@ import java.util.List; * See the License for the specific language governing permissions and * limitations under the License. */ +package com.alibaba.druid.sql.dialect.sqlserver.ast.stmt; + +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.dialect.sqlserver.ast.SQLServerObjectImpl; @@ -28,7 +28,7 @@ public class SQLServerExecStatement extends SQLServerObjectImpl implements SQLSe private SQLName returnStatus; private SQLName moduleName; - private List parameters = new ArrayList(); + private List parameters = new ArrayList(); private String dbType; public SQLName getModuleName() { @@ -39,7 +39,7 @@ public class SQLServerExecStatement extends SQLServerObjectImpl implements SQLSe this.moduleName = moduleName; } - public List getParameters() { + public List getParameters() { return parameters; } @@ -67,4 +67,37 @@ public class SQLServerExecStatement extends SQLServerObjectImpl implements SQLSe public void setDbType(String dbType) { this.dbType = dbType; } + + /** + * + * @Description: SQLServer execute Parameter statement + * @author zz email:455910092@qq.com + * @date 2015-9-20 + * @version V1.0 + */ + public static class SQLServerParameter extends SQLServerObjectImpl + { + private SQLExpr expr; + private boolean type;//sql server 支持参数只有input 和 output 两种 + public SQLExpr getExpr() { + return expr; + } + public void setExpr(SQLExpr expr) { + this.expr = expr; + } + public boolean getType() { + return type; + } + public void setType(boolean type) { + this.type = type; + } + @Override + public void accept0(SQLServerASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, expr); + } + visitor.endVisit(this); + + } + } } 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 f49257a66d..42e2281879 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 @@ -15,9 +15,12 @@ */ package com.alibaba.druid.sql.dialect.sqlserver.parser; +import java.util.Collection; 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.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; @@ -43,6 +46,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionIsolationLevelStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter; import com.alibaba.druid.sql.parser.Lexer; import com.alibaba.druid.sql.parser.ParserException; import com.alibaba.druid.sql.parser.SQLSelectParser; @@ -76,7 +80,7 @@ public class SQLServerStatementParser extends SQLStatementParser { SQLServerExecStatement execStmt = new SQLServerExecStatement(); if (lexer.token() == Token.LPAREN) { lexer.nextToken(); - this.exprParser.exprList(execStmt.getParameters(), execStmt); + this.parseExecParameter(execStmt.getParameters(), execStmt); accept(Token.RPAREN); } else { SQLName sqlNameName = this.exprParser.name(); @@ -88,8 +92,8 @@ public class SQLServerStatementParser extends SQLStatementParser { } else { execStmt.setModuleName(sqlNameName); } - - this.exprParser.exprList(execStmt.getParameters(), execStmt); + + this.parseExecParameter(execStmt.getParameters(), execStmt); } statementList.add(execStmt); return true; @@ -122,6 +126,44 @@ public class SQLServerStatementParser extends SQLStatementParser { return false; } + /** + * SQLServer parse Parameter statement support out type + * @author zz email:455910092@qq.com + * @date 2015-9-20 + */ + public void parseExecParameter(Collection exprCol, SQLObject parent) + { + if (lexer.token() == Token.RPAREN || lexer.token() == Token.RBRACKET) { + return; + } + + if (lexer.token() == Token.EOF) { + return; + } + SQLServerParameter param=new SQLServerParameter(); + SQLExpr expr=this.exprParser.expr(); + expr.setParent(parent); + param.setExpr(expr); + if(lexer.token()==Token.OUT) + { + param.setType(true); + accept(Token.OUT); + } + exprCol.add(param); + while (lexer.token() == Token.COMMA) { + lexer.nextToken(); + param=new SQLServerParameter(); + expr=this.exprParser.expr(); + expr.setParent(parent); + param.setExpr(expr); + if(lexer.token()==Token.OUT) + { + param.setType(true); + accept(Token.OUT); + } + exprCol.add(param); + } + } public SQLStatement parseDeclare() { this.accept(Token.DECLARE); 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 a4f2493898..829d1ca73e 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 @@ -26,6 +26,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement.Else; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; @@ -117,5 +118,9 @@ public interface SQLServerASTVisitor extends SQLASTVisitor { boolean visit(SQLServerWaitForStatement x); void endVisit(SQLServerWaitForStatement x); + + boolean visit(SQLServerParameter x); + + void endVisit(SQLServerParameter 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 ba4d4a6e5c..cabb471ae3 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 @@ -26,6 +26,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement.Else; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; @@ -238,4 +239,16 @@ public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements } + @Override + public boolean visit(SQLServerParameter x) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void endVisit(SQLServerParameter x) { + // TODO Auto-generated method stub + + } + } 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 d7c748a0a2..c2c94ac19c 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 @@ -35,6 +35,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement.Else; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; @@ -690,4 +691,21 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe public void endVisit(SQLServerWaitForStatement x) { } + + @Override + public boolean visit(SQLServerParameter x) { + // TODO Auto-generated method stub + x.getExpr().accept(this); + if(x.getType()) + { + print(" OUT"); + } + return false; + } + + @Override + public void endVisit(SQLServerParameter x) { + // TODO Auto-generated method stub + + } } 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 cf44d95f8e..c01db613b0 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 @@ -33,6 +33,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement.Else; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; @@ -274,4 +275,16 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL } + @Override + public boolean visit(SQLServerParameter x) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void endVisit(SQLServerParameter x) { + // TODO Auto-generated method stub + + } + } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerExec_Test.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerExec_Test.java index 6c61e6c004..eb6f716c0a 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerExec_Test.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerExec_Test.java @@ -71,4 +71,28 @@ public class SQLServerExec_Test extends TestCase { Assert.assertEquals(0, visitor.getColumns().size()); } + /** + * add by zz to test execute sp with out type + * @throws Exception + */ + public void test_3() throws Exception { + String sql = "EXEC sp_rename @P0 OUT"; + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + + SQLServerSchemaStatVisitor visitor = new SQLServerSchemaStatVisitor(); + 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.toSQLString(stmt, JdbcConstants.SQL_SERVER); + Assert.assertEquals("EXEC sp_rename @P0 OUT", output); + + Assert.assertEquals(0, visitor.getTables().size()); + Assert.assertEquals(0, visitor.getColumns().size()); + } }