diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/ConditionValue.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/ConditionValue.java new file mode 100644 index 0000000000..8df7b465c1 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/ConditionValue.java @@ -0,0 +1,50 @@ +/* + * 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.sql.dialect.mysql.ast.clause; + + +/** + * + * @author zhujun [455910092@qq.com] + * 2016-04-16 + */ +public class ConditionValue { + // type for condition SQLSTATE | SELF | SYSTEM | mysql_error_code + private ConditionType type; + + //value for condition condition_name | sqlstate | SQLWARNING | NOT FOUND | SQLEXCEPTION | mysql_error_code + private String value; + public ConditionType getType() { + return type; + } + public void setType(ConditionType type) { + this.type = type; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + public enum ConditionType{ + SQLSTATE, + SELF, + SYSTEM, + MYSQL_ERROR_CODE + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlDeclareHandlerStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlDeclareHandlerStatement.java new file mode 100644 index 0000000000..b1e60067c4 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlDeclareHandlerStatement.java @@ -0,0 +1,80 @@ +/* + * 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.sql.dialect.mysql.ast.clause; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStatementImpl; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; +/** + * + * @author zhujun [455910092@qq.com] + * @date 2016-04-14 + */ +public class MySqlDeclareHandlerStatement extends MySqlStatementImpl{ + + //DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement + + //handler type + private MySqlHandlerType handleType; + //sp statement + private SQLStatement spStatement; + + private List conditionValues; + + + public MySqlDeclareHandlerStatement() { + conditionValues = new ArrayList(); + } + + public List getConditionValues() { + return conditionValues; + } + + public void setConditionValues(List conditionValues) { + this.conditionValues = conditionValues; + } + + public MySqlHandlerType getHandleType() { + return handleType; + } + + public void setHandleType(MySqlHandlerType handleType) { + this.handleType = handleType; + } + + public SQLStatement getSpStatement() { + return spStatement; + } + + public void setSpStatement(SQLStatement spStatement) { + this.spStatement = spStatement; + } + + @Override + public void accept0(MySqlASTVisitor visitor) { + // TODO Auto-generated method stub + if (visitor.visit(this)) { + acceptChild(visitor, spStatement); + } + visitor.endVisit(this); + + } + +} + diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlHandlerType.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlHandlerType.java new file mode 100644 index 0000000000..9343df6bfa --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlHandlerType.java @@ -0,0 +1,29 @@ +/* + * 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.sql.dialect.mysql.ast.clause; + +/** + * + * @author zhujun [zhujunxxxxx@163.com] + * @date 2016-04-14 + */ +public enum MySqlHandlerType { + //DECLARE处理程序handler_type + + CONTINUE, + EXIT, + UNDO +} 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 6ecd0351a1..afc12a2f82 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 @@ -18,6 +18,8 @@ package com.alibaba.druid.sql.dialect.mysql.parser; import java.util.ArrayList; import java.util.List; +import javax.swing.text.AbstractDocument.LeafElement; + import com.alibaba.druid.sql.ast.SQLCommentHint; import com.alibaba.druid.sql.ast.SQLDataTypeImpl; import com.alibaba.druid.sql.ast.SQLDeclareItem; @@ -86,10 +88,14 @@ 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.clause.ConditionValue; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.ConditionValue.ConditionType; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCursorDeclareStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareHandlerStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlHandlerType; 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.MySqlRepeatStatement; @@ -3243,10 +3249,15 @@ public class MySqlStatementParser extends SQLStatementParser { int markBp = lexer.bp(); lexer.nextToken(); lexer.nextToken(); + System.out.println(lexer.token()); if (lexer.token() == Token.CURSOR)// cursor declare statement { lexer.reset(markBp, markChar, Token.DECLARE); statementList.add(this.parseCursorDeclare()); + } else if (lexer.token() == Token.HANDLER) { + //DECLARE处理程序 [add by zhujun 2016-04-16] + lexer.reset(markBp, markChar, Token.DECLARE); + statementList.add(this.parseDeclareHandler()); } else { lexer.reset(markBp, markChar, Token.DECLARE); statementList.add(this.parseDeclare()); @@ -3657,4 +3668,94 @@ public class MySqlStatementParser extends SQLStatementParser { return stmt; } + /** + * 定义异常处理程序 + * @author zhujun [455910092@qq.com] + * 2016-04-16 + * @return + */ + public MySqlDeclareHandlerStatement parseDeclareHandler() { + //DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement + //handler_type 取值为 CONTINUE | EXIT | UNDO + //condition_value 取值为 SQLWARNING | NOT FOUND | SQLEXCEPTION | SQLSTATE value(异常码 e.g 1062) + + MySqlDeclareHandlerStatement stmt = new MySqlDeclareHandlerStatement(); + accept(Token.DECLARE); + + //String handlerType = exprParser.name().getSimpleName(); + if(lexer.token() == Token.CONTINUE) { + stmt.setHandleType(MySqlHandlerType.CONTINUE); + } else if(lexer.token() == Token.EXIT) { + stmt.setHandleType(MySqlHandlerType.CONTINUE); + } else if(lexer.token() == Token.UNDO) { + stmt.setHandleType(MySqlHandlerType.CONTINUE); + } else { + throw new ParserException("unkown handle type"); + } + lexer.nextToken(); + + accept(Token.HANDLER); + + accept(Token.FOR); + + for (;;) { + String tokenName = lexer.stringVal(); + ConditionValue condition = new ConditionValue(); + + if (tokenName.equalsIgnoreCase("NOT")) {//for 'NOT FOUND' + lexer.nextToken(); + accept(Token.FOUND); + condition.setType(ConditionType.SYSTEM); + condition.setValue("NOT FOUND"); + + } else if(tokenName.equalsIgnoreCase("SQLSTATE")) { //for SQLSTATE (SQLSTATE '10001') + condition.setType(ConditionType.SQLSTATE); + condition.setValue(lexer.stringVal()); + lexer.nextToken(); + } else if(lexer.token() == Token.SQLEXCEPTION) { //for SQLEXCEPTION + condition.setType(ConditionType.SYSTEM); + condition.setValue(lexer.stringVal()); + lexer.nextToken(); + } else if(lexer.token() == Token.SQLWARNING) { //for SQLWARNING + condition.setType(ConditionType.SYSTEM); + condition.setValue(lexer.stringVal()); + lexer.nextToken(); + } else { //for condition_name or mysql_error_code + if (lexer.token() == Token.LITERAL_INT) { + condition.setType(ConditionType.MYSQL_ERROR_CODE); + condition.setValue(lexer.integerValue().toString()); + } else { + condition.setType(ConditionType.SELF); + condition.setValue(tokenName); + } + lexer.nextToken(); + } + stmt.getConditionValues().add(condition); + if (lexer.token() == Token.COMMA) { + accept(Token.COMMA); + continue; + } else if (lexer.token() != Token.EOF) { + //TODO + break; + } else { + throw new ParserException("declare handle not eof"); + } + } + + stmt.setSpStatement(parseBlock()); + + accept(Token.SEMI); + + return stmt; + } + /** + * 定义异常 + * @author zhujun [455910092@qq.com] + * 2016-04-16 + * @return + */ + public MySqlDeclareHandlerStatement parseDeclareCondition() { + //TODO + return null; + } } 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 21949ddef0..6b4edd3e1d 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 @@ -25,6 +25,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCursorDeclareStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareHandlerStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIterateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLeaveStatement; @@ -581,5 +582,9 @@ public interface MySqlASTVisitor extends SQLASTVisitor { boolean visit(MySqlSubPartitionByList x); void endVisit(MySqlSubPartitionByList x); + + boolean visit(MySqlDeclareHandlerStatement x); + + void endVisit(MySqlDeclareHandlerStatement 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 7304092830..3876360f3f 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 @@ -22,9 +22,11 @@ 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.clause.ConditionValue; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCursorDeclareStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareHandlerStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIterateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLeaveStatement; @@ -1278,4 +1280,16 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq public void endVisit(MySqlSubPartitionByList x) { } + @Override + public boolean visit(MySqlDeclareHandlerStatement x) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void endVisit(MySqlDeclareHandlerStatement x) { + // TODO Auto-generated method stub + + } + } // 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 accd4e391e..df2efdd7d3 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 @@ -54,9 +54,12 @@ 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.clause.ConditionValue; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.ConditionValue.ConditionType; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCursorDeclareStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareHandlerStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIterateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLeaveStatement; @@ -3422,4 +3425,40 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV public void endVisit(MySqlSubPartitionByList x) { } + + + @Override + public boolean visit(MySqlDeclareHandlerStatement x) { + // TODO Auto-generated method stub + + print0(ucase ? "DECLARE " : "declare "); + print0(ucase ? x.getHandleType().toString().toUpperCase() : x.getHandleType().toString().toLowerCase()); + print0(ucase ? " HANDLER FOR " : " handler for "); + for (int i = 0; i < x.getConditionValues().size(); i++) { + ConditionValue cv = x.getConditionValues().get(i); + if (cv.getType() == ConditionType.SQLSTATE) { + print0(ucase ? " SQLSTATE " : " sqlstate "); + print0(cv.getValue()); + } else if (cv.getType() == ConditionType.MYSQL_ERROR_CODE) { + print0(cv.getValue()); + } else if (cv.getType() == ConditionType.SELF) { + print0(cv.getValue()); + } else if (cv.getType() == ConditionType.SYSTEM){ + print0(ucase ? cv.getValue().toUpperCase() : cv.getValue().toLowerCase()); + } + + if (i != x.getConditionValues().size() - 1) { + print0(", "); + } + + } + println(); + return true; + } + + @Override + public void endVisit(MySqlDeclareHandlerStatement x) { + // TODO Auto-generated method stub + + } } // 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 a583fa876b..3c2e15e170 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 @@ -39,6 +39,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCursorDeclareStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareHandlerStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIterateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLeaveStatement; @@ -1388,4 +1389,16 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS public void endVisit(MySqlSubPartitionByList x) { } + + @Override + public boolean visit(MySqlDeclareHandlerStatement x) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void endVisit(MySqlDeclareHandlerStatement x) { + // TODO Auto-generated method stub + + } } 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 f125b4a3d7..2835265ba2 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java @@ -150,6 +150,13 @@ public class Keywords { map.put("FETCH", Token.FETCH); map.put("OUT", Token.OUT); map.put("INOUT", Token.INOUT); + map.put("HANDLER", Token.HANDLER); + map.put("CONTINUE", Token.CONTINUE); + map.put("UNDO", Token.UNDO); + map.put("SQLSTATE", Token.SQLSTATE); + map.put("SQLWARNING", Token.SQLWARNING); + map.put("SQLEXCEPTION", Token.SQLEXCEPTION); + map.put("FOUND", Token.FOUND); 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 a623d8a7ca..3e8dd49da7 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -138,6 +138,13 @@ public enum Token { CLOSE("CLOSE"), OUT("OUT"), INOUT("INOUT"), + HANDLER("HANDLER"), + EXIT("EXIT"), + UNDO("UNDO"), + SQLSTATE("SQLSTATE"), + SQLWARNING("SQLWARNING"), + SQLEXCEPTION("SQLEXCEPTION"), + FOUND("FOUND"), //postgresql WINDOW("WINDOW"), 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 cf1376459a..95e6820425 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java @@ -695,4 +695,5 @@ public interface SQLASTVisitor { boolean visit(SQLAlterTableRepairPartition x); void endVisit(SQLAlterTableRepairPartition x); + } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest8.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest8.java new file mode 100644 index 0000000000..f19040cc45 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest8.java @@ -0,0 +1,85 @@ +/* + * 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: begin-end within begin-end + * @author zhujun [455910092@qq.com] + * @date 2016-4-14 + * @version V1.0 + */ +public class MySqlCreateProcedureTest8 extends MysqlTest { + + /** + * DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement handler_type: CONTINUE | EXIT condition_value: SQLSTATE [VALUE] sqlstate_value | condition_name | SQLWARNING | NOT FOUND | SQLEXCEPTION | mysql_error_code + * @throws Exception + */ + public void test_0() throws Exception { + String sql="create or replace procedure test_cursor (in param int(10),out result varchar(90)) " + +" begin" + +" declare name varchar(20);" + +" declare pass varchar(20);" + +" declare done int;" + +" declare cur_test CURSOR for select user_name,user_pass from test;" +// +" declare continue handler FOR SQLSTATE '02000' SET done = 1;" + +" if param then" + +" select concat_ws(',',user_name,user_pass) into result from test.users where id=param;" + +" else" + +" open cur_test;" + +" repeat" + +" fetch cur_test into name, pass;" + +" select concat_ws(',',result,name,pass) into result;" + +" until done end repeat;" + +" close cur_test;" + +" end if;" + +" end;"; + + sql="create or replace procedure sp_name(level int,age int)"+ + " begin"+ + " declare continue handler FOR SQLEXCEPTION,SQLWARNING begin SET done = 1; end;"+ + " 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(0, visitor.getTables().size()); + Assert.assertEquals(0, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + } +}