From 01de65e16ea5a2922385d9ad308177bcefb01467 Mon Sep 17 00:00:00 2001 From: zhujunxxxxx <455910092@qq.com> Date: Mon, 14 Sep 2015 13:19:47 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AD=98=E5=82=A8?= =?UTF-8?q?=E8=BF=87=E7=A8=8B=E8=AF=AD=E5=8F=A5=E5=8F=A5=E5=B0=BE=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E5=88=86=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mysql/ast/clause/MySqlCaseStatement.java | 8 +-- .../clause/MySqlCreateProcedureStatement.java | 7 +- .../ast/clause/MySqlDeclareStatement.java | 9 +-- .../mysql/ast/clause/MySqlElseStatement.java | 8 ++- .../mysql/ast/clause/MySqlIfStatement.java | 16 +++-- .../mysql/ast/clause/MySqlParameter.java | 8 ++- .../ast/clause/MySqlSelectIntoStatement.java | 9 +-- .../mysql/ast/clause/MySqlStatementType.java | 8 ++- .../mysql/ast/clause/MySqlWhileStatement.java | 10 +-- .../executor/MySqlProcedureExecutor.java | 8 ++- .../mysql/parser/MySqlSelectIntoParser.java | 13 ++-- .../mysql/parser/MySqlStatementParser.java | 13 ++-- .../mysql/visitor/MySqlOutputVisitor.java | 32 +-------- .../sql/mysql/MySqlCreateProcedureTest1.java | 70 +++++++++++++++++++ 14 files changed, 141 insertions(+), 78 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest1.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCaseStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCaseStatement.java index 41e7106161..74b0d1a856 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCaseStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCaseStatement.java @@ -8,11 +8,11 @@ import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStatementImpl; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; - /** - * MySql procedure case statement - * @author zz - * + * + * @Description: MySql procedure Case statement + * @author zz email:455910092@qq.com + * @version V1.0 */ public class MySqlCaseStatement extends MySqlStatementImpl{ diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCreateProcedureStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCreateProcedureStatement.java index c65126b962..f0c3c4a4f1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCreateProcedureStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCreateProcedureStatement.java @@ -9,9 +9,10 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStatementImpl; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; /** - * MySql create procedure statement - * @author zz - * + * + * @Description: MySql create procedure statement + * @author zz email:455910092@qq.com + * @version V1.0 */ public class MySqlCreateProcedureStatement extends MySqlStatementImpl { private boolean orReplace; 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 3e752f5fe7..7240729209 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 @@ -5,13 +5,14 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLDataType; import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStatementImpl; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; /** - * MySql declare statement - * @author sei.zz - * + * + * @Description: MySql declare statement + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 */ public class MySqlDeclareStatement extends MySqlStatementImpl{ diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlElseStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlElseStatement.java index 341483c293..4109b0e6a1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlElseStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlElseStatement.java @@ -8,9 +8,11 @@ import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; /** - * MySql procedure else statement - * @author zz - * + * + * @Description: MySql procedure else statement + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 */ public class MySqlElseStatement extends MySqlObjectImpl { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlIfStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlIfStatement.java index 8e79c133a2..444f0e8ee5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlIfStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlIfStatement.java @@ -10,9 +10,11 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStatementImpl; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; /** - * MySql procedure if statement - * @author sei.zz - * + * + * @Description: MySql procedure if statement + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 */ public class MySqlIfStatement extends MySqlStatementImpl{ private SQLExpr condition; @@ -55,9 +57,11 @@ public class MySqlIfStatement extends MySqlStatementImpl{ this.elseItem = elseItem; } /** - * comment: else if语句 - * @author sei.zz - * + * + * @Description: MySql procedure else if statement + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 */ public static class MySqlElseIfStatement extends MySqlObjectImpl { 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 544f1f9938..a2e88da6d7 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 @@ -21,9 +21,11 @@ import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; /** - * MySql procedure parameter - * @author sei.zz - * + * + * @Description: MySql procedure parameter + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 */ public class MySqlParameter extends MySqlObjectImpl { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlSelectIntoStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlSelectIntoStatement.java index 9bc58a7444..af1f725052 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlSelectIntoStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlSelectIntoStatement.java @@ -4,14 +4,15 @@ import java.util.ArrayList; import java.util.List; import com.alibaba.druid.sql.ast.statement.SQLSelect; -import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStatementImpl; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; import com.alibaba.druid.sql.ast.SQLExpr; /** - * MySql procedure select into statement - * @author sei.zz - * + * + * @Description: MySql procedure select into statement + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 */ public class MySqlSelectIntoStatement extends MySqlStatementImpl{ diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlStatementType.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlStatementType.java index eeabac07bd..8bc54d0170 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlStatementType.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlStatementType.java @@ -8,9 +8,11 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; /** - * MySql procedure statement type - * @author zz - * + * + * @Description: MySql procedure statement type + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 */ public enum MySqlStatementType { //select statement diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlWhileStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlWhileStatement.java index 338cf19919..5709f0b14b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlWhileStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlWhileStatement.java @@ -9,13 +9,15 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStatementImpl; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; /** - * comment: 存储过程中while循环语句 - * @author 小竹zz - * + * + * @Description: MySql procedure while statement + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 */ public class MySqlWhileStatement extends MySqlStatementImpl { - //while循环的表达式 + //while expr private SQLExpr condition; private List statements = new ArrayList(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/executor/MySqlProcedureExecutor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/executor/MySqlProcedureExecutor.java index 5eae64458d..0ba72f4d6e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/executor/MySqlProcedureExecutor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/executor/MySqlProcedureExecutor.java @@ -5,9 +5,11 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLStatement; /** - * comment: mysql存储过程执行器 - * @author sei.zz - * + * + * @Description: MySql procedure executor + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 */ public class MySqlProcedureExecutor { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectIntoParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectIntoParser.java index 02caf172bd..bbe3d072db 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectIntoParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectIntoParser.java @@ -46,9 +46,11 @@ import com.alibaba.druid.sql.parser.SQLSelectParser; import com.alibaba.druid.sql.parser.Token; /** - * parse select into statement - * @author sei.zz - * + * + * @Description: parse select into statement + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 */ public class MySqlSelectIntoParser extends SQLSelectParser { private List argsList; @@ -187,7 +189,10 @@ public class MySqlSelectIntoParser extends SQLSelectParser { return queryRest(queryBlock); } - + /** + * parser the select into arguments + * @return + */ protected List parseIntoArgs() { List args=new ArrayList(); 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 bcdadb57a9..5e00b26bd0 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 @@ -714,8 +714,6 @@ public class MySqlStatementParser extends SQLStatementParser { MySqlBlockStatement block = new MySqlBlockStatement(); accept(Token.BEGIN); - - //parseStatementList(block.getStatementList()); parseProcedureStatementList(block.getStatementList()); accept(Token.END); @@ -2806,7 +2804,7 @@ public class MySqlStatementParser extends SQLStatementParser { } /** - * parse procedure statement block + * parse procedure statement block,not support begin-end block * @param statementList */ private void parseProcedureStatementList(List statementList) @@ -2948,8 +2946,8 @@ public class MySqlStatementParser extends SQLStatementParser { if (lexer.token() == Token.DECLARE) { statementList.add(this.parseDeclare()); continue; - } - + } + throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); } @@ -2995,6 +2993,7 @@ public class MySqlStatementParser extends SQLStatementParser { accept(Token.END); accept(Token.IF); + accept(Token.SEMI); return stmt; } @@ -3016,6 +3015,8 @@ public class MySqlStatementParser extends SQLStatementParser { accept(Token.END); accept(Token.WHILE); + + accept(Token.SEMI); return stmt; @@ -3082,7 +3083,7 @@ public class MySqlStatementParser extends SQLStatementParser { } accept(Token.END); accept(Token.CASE); - + accept(Token.SEMI); return stmt; } 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 d070428cd2..f9594b7aa0 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 @@ -3212,12 +3212,10 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV /** - * comment: visit procedure node - * author С��zz + * visit procedure create node */ @Override public boolean visit(MySqlCreateProcedureStatement x) { - // TODO Auto-generated method stub if (x.isOrReplace()) { print("CREATE OR REPLACE PROCEDURE "); } else { @@ -3254,13 +3252,11 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public void endVisit(MySqlCreateProcedureStatement x) { - // TODO Auto-generated method stub } @Override public boolean visit(MySqlParameter x) { - // TODO Auto-generated method stub if (x.getDataType().getName().equalsIgnoreCase("CURSOR")) { print("CURSOR "); x.getName().accept(this); @@ -3288,14 +3284,11 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public void endVisit(MySqlParameter x) { - // TODO Auto-generated method stub } @Override public boolean visit(MySqlWhileStatement x) { - // TODO Auto-generated method stub - print("WHILE "); x.getCondition().accept(this); print(" DO"); @@ -3315,13 +3308,11 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public void endVisit(MySqlWhileStatement x) { - // TODO Auto-generated method stub } @Override public boolean visit(MySqlIfStatement x) { - // TODO Auto-generated method stub print("IF "); x.getCondition().accept(this); print(" THEN"); @@ -3348,14 +3339,11 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public void endVisit(MySqlIfStatement x) { - // TODO Auto-generated method stub } @Override public boolean visit(MySqlElseIfStatement x) { - // TODO Auto-generated method stub - print("ELSE IF "); x.getCondition().accept(this); print(" THEN"); @@ -3374,13 +3362,11 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public void endVisit(MySqlElseIfStatement x) { - // TODO Auto-generated method stub } @Override public boolean visit(MySqlElseStatement x) { - // TODO Auto-generated method stub print("ELSE "); println(); for (int i = 0, size = x.getStatements().size(); i < size; ++i) { @@ -3397,22 +3383,17 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public void endVisit(MySqlElseStatement x) { - // TODO Auto-generated method stub } @Override public boolean visit(MySqlCaseStatement x) { - // TODO Auto-generated method stub print("CASE "); x.getCondition().accept(this); println(); for (int i = 0; i < x.getWhenList().size(); i++) { x.getWhenList().get(i).accept(this); -// if (i != x.getWhenList().size() - 1) { -// println(); -// } } if(x.getElseItem()!=null) x.getElseItem().accept(this); @@ -3422,16 +3403,12 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public void endVisit(MySqlCaseStatement x) { - // TODO Auto-generated method stub } @Override public boolean visit(MySqlDeclareStatement x) { - // TODO Auto-generated method stub - print("DECLARE "); - for (int i = 0; i < x.getVarList().size(); i++) { x.getVarList().get(i).accept(this); if(i!=x.getVarList().size()-1) @@ -3439,39 +3416,33 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV } print(" "); x.getType().accept(this); - return false; } @Override public void endVisit(MySqlDeclareStatement x) { - // TODO Auto-generated method stub } @Override public boolean visit(MySqlSelectIntoStatement x) { - // TODO Auto-generated method stub x.getSelect().accept(this); print(" INTO "); for (int i = 0; i < x.getVarList().size(); i++) { x.getVarList().get(i).accept(this); if(i!=x.getVarList().size()-1) print(","); - //println(x.getVarList().get(i).toString()); } return false; } @Override public void endVisit(MySqlSelectIntoStatement x) { - // TODO Auto-generated method stub } @Override public boolean visit(MySqlWhenfStatement x) { - // TODO Auto-generated method stub print("WHEN "); x.getCondition().accept(this); println(" THEN"); @@ -3487,7 +3458,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public void endVisit(MySqlWhenfStatement x) { - // TODO Auto-generated method stub } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest1.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest1.java new file mode 100644 index 0000000000..92ce4b1470 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest1.java @@ -0,0 +1,70 @@ +/* + * 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 zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 + */ +public class MySqlCreateProcedureTest1 extends MysqlTest { + + public void test_0() throws Exception { + String sql="create or replace procedure sp_name(level int,age int)"+ + " begin"+ + " declare x,y,z int;"+ + " begin"+ + " insert into test values(id,age);"+ + " 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(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 44ce8cb8fa759b732ffdbe0ba44f099f234abe8d Mon Sep 17 00:00:00 2001 From: zhujunxxxxx <455910092@qq.com> Date: Mon, 14 Sep 2015 13:32:19 +0800 Subject: [PATCH 2/3] fix procedure statement need SEMI end --- .../sql/dialect/mysql/parser/MySqlStatementParser.java | 2 +- .../druid/bvt/sql/mysql/MySqlCreateProcedureTest.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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 5e00b26bd0..aa59a4a461 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 @@ -2804,7 +2804,7 @@ public class MySqlStatementParser extends SQLStatementParser { } /** - * parse procedure statement block,not support begin-end block + * parse procedure statement block * @param statementList */ private void parseProcedureStatementList(List statementList) diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest.java index 67161d9750..c62f6852be 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest.java @@ -36,7 +36,7 @@ public class MySqlCreateProcedureTest extends MysqlTest { " insert into test values(id,age);"+ " while x do"+ " insert into test values(id,age);"+ - " end while"+ + " end while;"+ " if x then"+ " insert into test values(id,age);"+ " insert into test values(id,age);"+ @@ -44,10 +44,10 @@ public class MySqlCreateProcedureTest extends MysqlTest { " insert into test values(id,age);"+ " while x do"+ " insert into test values(id,age);"+ - " end while"+ + " end while;"+ " else"+ " insert into test values(id,age);"+ - " end if"+ + " end if;"+ " case x"+ " when x>10 then"+ " insert into test values(id,age);"+ @@ -57,7 +57,7 @@ public class MySqlCreateProcedureTest extends MysqlTest { " insert into test values(id,age);"+ " else"+ " insert into test values(id,age);"+ - " end case"+ + " end case;"+ " end"; MySqlStatementParser parser=new MySqlStatementParser(sql); From 02a8376f093811cfb53d78349e0ae59c03f5f8c2 Mon Sep 17 00:00:00 2001 From: zhujunxxxxx <455910092@qq.com> Date: Mon, 14 Sep 2015 18:32:27 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0mysql=E5=AD=98=E5=82=A8?= =?UTF-8?q?=E8=BF=87=E7=A8=8BLOOP,REPAET,LEAVE,ITEARATE=E8=AF=AD=E6=B3=95?= =?UTF-8?q?=E6=94=AF=E6=8C=81,=E4=BB=A5=E5=8F=8A=E6=94=AF=E6=8C=81BEGIN-EN?= =?UTF-8?q?D=E5=92=8CWHILE=E8=AF=AD=E5=8F=A5=E6=A0=87=E7=AD=BE=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mysql/ast/clause/MySqlCaseStatement.java | 25 ++- .../clause/MySqlCreateProcedureStatement.java | 15 ++ .../ast/clause/MySqlDeclareStatement.java | 15 ++ .../mysql/ast/clause/MySqlElseStatement.java | 15 ++ .../mysql/ast/clause/MySqlIfStatement.java | 15 ++ .../ast/clause/MySqlIterateStatement.java | 46 ++++ .../mysql/ast/clause/MySqlLeaveStatement.java | 46 ++++ .../mysql/ast/clause/MySqlLoopStatement.java | 62 ++++++ .../ast/clause/MySqlRepeatStatement.java | 73 ++++++ .../ast/clause/MySqlSelectIntoStatement.java | 15 ++ .../mysql/ast/clause/MySqlStatementType.java | 15 ++ .../mysql/ast/clause/MySqlWhileStatement.java | 25 +++ .../ast/statement/MySqlBlockStatement.java | 16 +- .../mysql/parser/MySqlStatementParser.java | 207 +++++++++++++++++- .../mysql/visitor/MySqlASTVisitor.java | 26 ++- .../mysql/visitor/MySqlASTVisitorAdapter.java | 58 ++++- .../mysql/visitor/MySqlOutputVisitor.java | 100 ++++++++- .../mysql/visitor/MySqlSchemaStatVisitor.java | 71 +++++- .../alibaba/druid/sql/parser/Keywords.java | 7 +- .../com/alibaba/druid/sql/parser/Token.java | 4 + .../sql/mysql/MySqlCreateProcedureTest2.java | 135 ++++++++++++ .../sql/mysql/MySqlCreateProcedureTest3.java | 138 ++++++++++++ .../sql/mysql/MySqlCreateProcedureTest4.java | 105 +++++++++ 23 files changed, 1207 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlIterateStatement.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlLeaveStatement.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlLoopStatement.java create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlRepeatStatement.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest2.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest3.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest4.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCaseStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCaseStatement.java index 74b0d1a856..37ab19f73f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCaseStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCaseStatement.java @@ -1,3 +1,18 @@ +/* + * 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; @@ -19,7 +34,7 @@ public class MySqlCaseStatement extends MySqlStatementImpl{ //case expr private SQLExpr condition; //when statement list - private List whenList=new ArrayList(); + private List whenList=new ArrayList(); //else statement private MySqlElseStatement elseItem; @@ -31,15 +46,15 @@ public class MySqlCaseStatement extends MySqlStatementImpl{ this.condition = condition; } - public List getWhenList() { + public List getWhenList() { return whenList; } - public void setWhenList(List whenList) { + public void setWhenList(List whenList) { this.whenList = whenList; } - public void addWhenStatement(MySqlWhenfStatement stmt) + public void addWhenStatement(MySqlWhenStatement stmt) { this.whenList.add(stmt); } @@ -68,7 +83,7 @@ public class MySqlCaseStatement extends MySqlStatementImpl{ * @author zz * */ - public static class MySqlWhenfStatement extends MySqlObjectImpl { + public static class MySqlWhenStatement extends MySqlObjectImpl { private SQLExpr condition; private List statements = new ArrayList(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCreateProcedureStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCreateProcedureStatement.java index f0c3c4a4f1..43e78f6713 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCreateProcedureStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlCreateProcedureStatement.java @@ -1,3 +1,18 @@ +/* + * 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; 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 7240729209..2c0ceffde6 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 @@ -1,3 +1,18 @@ +/* + * 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; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlElseStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlElseStatement.java index 4109b0e6a1..bd12372ac1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlElseStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlElseStatement.java @@ -1,3 +1,18 @@ +/* + * 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; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlIfStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlIfStatement.java index 444f0e8ee5..5c1050e133 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlIfStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlIfStatement.java @@ -1,3 +1,18 @@ +/* + * 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; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlIterateStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlIterateStatement.java new file mode 100644 index 0000000000..55d2d223df --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlIterateStatement.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.sql.dialect.mysql.ast.clause; + +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStatementImpl; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; + +/** + * + * @Description: MySql procedure iterate statement + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 + */ +public class MySqlIterateStatement extends MySqlStatementImpl { + + private String labelName; + + @Override + public void accept0(MySqlASTVisitor visitor) { + visitor.visit(this); + visitor.endVisit(this); + } + + public String getLabelName() { + return labelName; + } + + public void setLabelName(String labelName) { + this.labelName = labelName; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlLeaveStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlLeaveStatement.java new file mode 100644 index 0000000000..2ead056a38 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlLeaveStatement.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.sql.dialect.mysql.ast.clause; + +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStatementImpl; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; + +/** + * + * @Description: MySql procedure leave statement + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 + */ +public class MySqlLeaveStatement extends MySqlStatementImpl { + + private String labelName; + + @Override + public void accept0(MySqlASTVisitor visitor) { + visitor.visit(this); + visitor.endVisit(this); + } + + public String getLabelName() { + return labelName; + } + + public void setLabelName(String labelName) { + this.labelName = labelName; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlLoopStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlLoopStatement.java new file mode 100644 index 0000000000..aa98e7a607 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlLoopStatement.java @@ -0,0 +1,62 @@ +/* + * 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; + +/** + * + * @Description: MySql procedure loop statement + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 + */ +public class MySqlLoopStatement extends MySqlStatementImpl { + + private String labelName; + + private List statements = new ArrayList(); + + @Override + public void accept0(MySqlASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, statements); + } + visitor.endVisit(this); + } + + public List getStatements() { + return statements; + } + + public void setStatements(List statements) { + this.statements = statements; + } + + public String getLabelName() { + return labelName; + } + + public void setLabelName(String labelName) { + this.labelName = labelName; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlRepeatStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlRepeatStatement.java new file mode 100644 index 0000000000..5052d77292 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlRepeatStatement.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.sql.dialect.mysql.ast.clause; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.SQLExpr; +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; + +/** + * + * @Description: MySql procedure repeat statement + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 + */ +public class MySqlRepeatStatement extends MySqlStatementImpl { + + private String labelName; + + private List statements = new ArrayList(); + + private SQLExpr condition; + + @Override + public void accept0(MySqlASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, statements); + acceptChild(visitor, condition); + } + visitor.endVisit(this); + } + + public List getStatements() { + return statements; + } + + public void setStatements(List statements) { + this.statements = statements; + } + + public String getLabelName() { + return labelName; + } + + public void setLabelName(String labelName) { + this.labelName = labelName; + } + + public SQLExpr getCondition() { + return condition; + } + + public void setCondition(SQLExpr condition) { + this.condition = condition; + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlSelectIntoStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlSelectIntoStatement.java index af1f725052..a0956b5bf4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlSelectIntoStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlSelectIntoStatement.java @@ -1,3 +1,18 @@ +/* + * 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; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlStatementType.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlStatementType.java index 8bc54d0170..2790e2dcb5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlStatementType.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlStatementType.java @@ -1,3 +1,18 @@ +/* + * 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 com.alibaba.druid.sql.ast.SQLStatement; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlWhileStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlWhileStatement.java index 5709f0b14b..854c2814de 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlWhileStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlWhileStatement.java @@ -1,3 +1,18 @@ +/* + * 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; @@ -20,8 +35,18 @@ public class MySqlWhileStatement extends MySqlStatementImpl { //while expr private SQLExpr condition; private List statements = new ArrayList(); + //while label name + private String labelName; + public String getLabelName() { + return labelName; + } + + public void setLabelName(String labelName) { + this.labelName = labelName; + } + @Override public void accept0(MySqlASTVisitor visitor) { if (visitor.visit(this)) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlBlockStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlBlockStatement.java index 2cd26ed9e7..08e4afd4aa 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlBlockStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlBlockStatement.java @@ -23,7 +23,13 @@ import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; public class MySqlBlockStatement extends MySqlStatementImpl { - private List statementList = new ArrayList(); + /** + * begin-end block label name + * @author zz + */ + private String labelName; + + private List statementList = new ArrayList(); public List getStatementList() { return statementList; @@ -33,6 +39,14 @@ public class MySqlBlockStatement extends MySqlStatementImpl { this.statementList = statementList; } + public String getLabelName() { + return labelName; + } + + public void setLabelName(String labelName) { + this.labelName = labelName; + } + @Override public void accept0(MySqlASTVisitor visitor) { if (visitor.visit(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 aa59a4a461..12dfb1d95f 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 @@ -62,13 +62,17 @@ 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.MySqlCaseStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenfStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCreateProcedureStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlElseStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIfStatement; +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.MySqlIfStatement.MySqlElseIfStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlParameter; +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; import com.alibaba.druid.sql.dialect.mysql.ast.statement.CobarShowStatus; @@ -2840,6 +2844,9 @@ public class MySqlStatementParser extends SQLStatementParser { if (lexer.token() == Token.WHEN) { return; } + if (lexer.token() == Token.UNTIL) { + return; + } // select into if (lexer.token() == (Token.SELECT)) { statementList.add(this.parseSelectInto()); @@ -2930,6 +2937,12 @@ public class MySqlStatementParser extends SQLStatementParser { continue; } + // loop statement + if (lexer.token() == Token.LOOP) { + statementList.add(this.parseLoop()); + continue; + } + // if statement if (lexer.token() == Token.IF) { statementList.add(this.parseIf()); @@ -2948,6 +2961,61 @@ public class MySqlStatementParser extends SQLStatementParser { continue; } + // leave statement + if (lexer.token() == Token.LEAVE) { + statementList.add(this.parseLeave()); + continue; + } + + // iterate statement + if (lexer.token() == Token.ITERATE) { + statementList.add(this.parseIterate()); + continue; + } + + // repeat statement + if (lexer.token() == Token.REPEAT) { + statementList.add(this.parseRepeat()); + continue; + } + + if(lexer.token() == Token.IDENTIFIER) + { + String label=lexer.stringVal(); + char ch = lexer.current(); + int bp = lexer.bp(); + lexer.nextToken(); + if(lexer.token()==Token.VARIANT&&lexer.stringVal().equals(":")) + { + lexer.nextToken(); + if(lexer.token()==Token.LOOP) + { + //parse loop statement + statementList.add(this.parseLoop(label)); + } + else if(lexer.token()==Token.WHILE) + { + //parse while statement with label + statementList.add(this.parseWhile(label)); + } + else if(lexer.token()==Token.BEGIN) + { + //parse begin-end statement with label + statementList.add(this.parseBlock(label)); + } + else if(lexer.token()==Token.REPEAT) + { + //parse repeat statement with label + statementList.add(this.parseRepeat(label)); + } + continue; + } + else + { + lexer.reset(bp, ch, Token.IDENTIFIER); + } + + } throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal()); } @@ -3022,6 +3090,35 @@ public class MySqlStatementParser extends SQLStatementParser { } + /** + * parse while statement with label + * @return MySqlWhileStatement + */ + public MySqlWhileStatement parseWhile(String label) { + accept(Token.WHILE); + + MySqlWhileStatement stmt = new MySqlWhileStatement(); + + stmt.setLabelName(label); + + stmt.setCondition(this.exprParser.expr()); + + accept(Token.DO); + + this.parseProcedureStatementList(stmt.getStatements()); + + accept(Token.END); + + accept(Token.WHILE); + + acceptIdentifier(label); + + accept(Token.SEMI); + + return stmt; + + } + /** * parse case statement * @return MySqlCaseStatement @@ -3035,7 +3132,7 @@ public class MySqlStatementParser extends SQLStatementParser { { while (lexer.token() == Token.WHEN) { - MySqlWhenfStatement when=new MySqlWhenfStatement(); + MySqlWhenStatement when=new MySqlWhenStatement(); //when expr when.setCondition(exprParser.expr()); @@ -3061,7 +3158,7 @@ public class MySqlStatementParser extends SQLStatementParser { while (lexer.token() == Token.WHEN) { accept(Token.WHEN); - MySqlWhenfStatement when=new MySqlWhenfStatement(); + MySqlWhenStatement when=new MySqlWhenStatement(); //when expr when.setCondition(exprParser.expr()); @@ -3141,4 +3238,108 @@ public class MySqlStatementParser extends SQLStatementParser { MySqlSelectIntoParser parse=new MySqlSelectIntoParser(this.exprParser); return parse.parseSelectInto(); } + + /** + * parse loop statement + */ + public MySqlLoopStatement parseLoop() + { + MySqlLoopStatement loopStmt=new MySqlLoopStatement(); + accept(Token.LOOP); + parseProcedureStatementList(loopStmt.getStatements()); + accept(Token.END); + accept(Token.LOOP); + accept(Token.SEMI); + return loopStmt; + } + + /** + * parse loop statement with label + */ + public MySqlLoopStatement parseLoop(String label) + { + MySqlLoopStatement loopStmt=new MySqlLoopStatement(); + loopStmt.setLabelName(label); + accept(Token.LOOP); + parseProcedureStatementList(loopStmt.getStatements()); + accept(Token.END); + accept(Token.LOOP); + acceptIdentifier(label); + accept(Token.SEMI); + return loopStmt; + } + + /** + * parse loop statement with label + */ + public MySqlBlockStatement parseBlock(String label) { + MySqlBlockStatement block = new MySqlBlockStatement(); + block.setLabelName(label); + accept(Token.BEGIN); + parseProcedureStatementList(block.getStatementList()); + accept(Token.END); + acceptIdentifier(label); + return block; + } + + /** + * parse leave statement + */ + public MySqlLeaveStatement parseLeave() + { + accept(Token.LEAVE); + MySqlLeaveStatement leaveStmt=new MySqlLeaveStatement(); + leaveStmt.setLabelName(exprParser.name().getSimpleName()); + accept(Token.SEMI); + return leaveStmt; + } + + /** + * parse iterate statement + */ + public MySqlIterateStatement parseIterate() + { + accept(Token.ITERATE); + MySqlIterateStatement iterateStmt=new MySqlIterateStatement(); + iterateStmt.setLabelName(exprParser.name().getSimpleName()); + accept(Token.SEMI); + return iterateStmt; + } + + /** + * parse repeat statement + * @return + */ + public MySqlRepeatStatement parseRepeat() + { + MySqlRepeatStatement repeatStmt=new MySqlRepeatStatement(); + accept(Token.REPEAT); + parseProcedureStatementList(repeatStmt.getStatements()); + accept(Token.UNTIL); + repeatStmt.setCondition(exprParser.expr()); + accept(Token.END); + accept(Token.REPEAT); + accept(Token.SEMI); + return repeatStmt; + } + + /** + * parse repeat statement with label + * @param label + * @return + */ + public MySqlRepeatStatement parseRepeat(String label) + { + MySqlRepeatStatement repeatStmt=new MySqlRepeatStatement(); + repeatStmt.setLabelName(label); + accept(Token.REPEAT); + parseProcedureStatementList(repeatStmt.getStatements()); + accept(Token.UNTIL); + repeatStmt.setCondition(exprParser.expr()); + accept(Token.END); + accept(Token.REPEAT); + acceptIdentifier(label); + accept(Token.SEMI); + return repeatStmt; + } } 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 28346ca040..4e1508a3e5 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 @@ -23,13 +23,17 @@ 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.MySqlCaseStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenfStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCreateProcedureStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlElseStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIfStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIfStatement.MySqlElseIfStatement; +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.MySqlRepeatStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlWhileStatement; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr; @@ -622,7 +626,23 @@ public interface MySqlASTVisitor extends SQLASTVisitor { void endVisit(MySqlSelectIntoStatement x); - boolean visit(MySqlWhenfStatement x); + boolean visit(MySqlWhenStatement x); - void endVisit(MySqlWhenfStatement x); + void endVisit(MySqlWhenStatement x); + + boolean visit(MySqlLoopStatement x); + + void endVisit(MySqlLoopStatement x); + + boolean visit(MySqlLeaveStatement x); + + void endVisit(MySqlLeaveStatement x); + + boolean visit(MySqlIterateStatement x); + + void endVisit(MySqlIterateStatement x); + + boolean visit(MySqlRepeatStatement x); + + void endVisit(MySqlRepeatStatement 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 5036505063..2fa046b353 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 @@ -23,13 +23,17 @@ 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.MySqlCaseStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenfStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCreateProcedureStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlElseStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIfStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIfStatement.MySqlElseIfStatement; +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.MySqlRepeatStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlWhileStatement; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr; @@ -1390,16 +1394,64 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq } @Override - public boolean visit(MySqlWhenfStatement x) { + public boolean visit(MySqlWhenStatement x) { // TODO Auto-generated method stub return true; } @Override - public void endVisit(MySqlWhenfStatement x) { + public void endVisit(MySqlWhenStatement x) { // TODO Auto-generated method stub } //add:end + @Override + public boolean visit(MySqlLoopStatement x) { + // TODO Auto-generated method stub + return true; + } + + @Override + public void endVisit(MySqlLoopStatement x) { + // TODO Auto-generated method stub + + } + + @Override + public boolean visit(MySqlLeaveStatement x) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void endVisit(MySqlLeaveStatement x) { + // TODO Auto-generated method stub + + } + + @Override + public boolean visit(MySqlIterateStatement x) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void endVisit(MySqlIterateStatement x) { + // TODO Auto-generated method stub + + } + + @Override + public boolean visit(MySqlRepeatStatement x) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void endVisit(MySqlRepeatStatement 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 f9594b7aa0..d8b0df99d8 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 @@ -45,13 +45,17 @@ 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.MySqlCaseStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenfStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCreateProcedureStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlElseStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIfStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIfStatement.MySqlElseIfStatement; +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.MySqlRepeatStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlWhileStatement; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr; @@ -3187,6 +3191,8 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public boolean visit(MySqlBlockStatement x) { + if(x.getLabelName()!=null&&!x.getLabelName().equals("")) + print(x.getLabelName()+": "); print("BEGIN"); incrementIndent(); println(); @@ -3202,6 +3208,8 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV decrementIndent(); println(); print("END"); + if(x.getLabelName()!=null&&!x.getLabelName().equals("")) + print(" "+x.getLabelName()); return false; } @@ -3289,6 +3297,8 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public boolean visit(MySqlWhileStatement x) { + if(x.getLabelName()!=null&&!x.getLabelName().equals("")) + print(x.getLabelName()+": "); print("WHILE "); x.getCondition().accept(this); print(" DO"); @@ -3303,6 +3313,8 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV } println(); print("END WHILE"); + if(x.getLabelName()!=null&&!x.getLabelName().equals("")) + print(" "+x.getLabelName()); return false; } @@ -3442,7 +3454,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV } @Override - public boolean visit(MySqlWhenfStatement x) { + public boolean visit(MySqlWhenStatement x) { print("WHEN "); x.getCondition().accept(this); println(" THEN"); @@ -3457,7 +3469,89 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV } @Override - public void endVisit(MySqlWhenfStatement x) { + public void endVisit(MySqlWhenStatement x) { + + } + + @Override + public boolean visit(MySqlLoopStatement x) { + if(x.getLabelName()!=null&&!x.getLabelName().equals("")) + print(x.getLabelName()+": "); + print("LOOP "); + println(); + for (int i = 0, size = x.getStatements().size(); i < size; ++i) { + SQLStatement item = x.getStatements().get(i); + item.setParent(x); + item.accept(this); + if (i != size - 1) { + println(); + } + } + println(); + print("END LOOP"); + if(x.getLabelName()!=null&&!x.getLabelName().equals("")) + print(" "+x.getLabelName()); + return false; + } + + @Override + public void endVisit(MySqlLoopStatement x) { + // TODO Auto-generated method stub + + } + + @Override + public boolean visit(MySqlLeaveStatement x) { + print("LEAVE "+x.getLabelName()); + return false; + } + + @Override + public void endVisit(MySqlLeaveStatement x) { + // TODO Auto-generated method stub + + } + + @Override + public boolean visit(MySqlIterateStatement x) { + print("ITERATE "+x.getLabelName()); + return false; + } + + @Override + public void endVisit(MySqlIterateStatement x) { + // TODO Auto-generated method stub + + } + + @Override + public boolean visit(MySqlRepeatStatement x) { + // TODO Auto-generated method stub + if(x.getLabelName()!=null&&!x.getLabelName().equals("")) + print(x.getLabelName()+": "); + print("REPEAT "); + println(); + for (int i = 0, size = x.getStatements().size(); i < size; ++i) { + SQLStatement item = x.getStatements().get(i); + item.setParent(x); + item.accept(this); + if (i != size - 1) { + println(); + } + } + println(); + print("UNTIL "); + x.getCondition().accept(this); + println(); + print("END REPEAT"); + if(x.getLabelName()!=null&&!x.getLabelName().equals("")) + print(" "+x.getLabelName()); + return false; + } + + @Override + public void endVisit(MySqlRepeatStatement 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 f6a2ce4c01..dcc761ad26 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 @@ -38,13 +38,17 @@ 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.MySqlCaseStatement; -import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenfStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCreateProcedureStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlElseStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIfStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIfStatement.MySqlElseIfStatement; +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.MySqlRepeatStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlWhileStatement; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr; @@ -1409,7 +1413,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public boolean visit(MySqlWhileStatement x) { - // TODO Auto-generated method stub + accept(x.getStatements()); return false; } @@ -1421,7 +1425,9 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public boolean visit(MySqlIfStatement x) { - // TODO Auto-generated method stub + accept(x.getStatements()); + accept(x.getElseIfList()); + accept(x.getElseItem()); return false; } @@ -1433,7 +1439,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public boolean visit(MySqlElseIfStatement x) { - // TODO Auto-generated method stub + accept(x.getStatements()); return false; } @@ -1445,7 +1451,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public boolean visit(MySqlElseStatement x) { - // TODO Auto-generated method stub + accept(x.getStatements()); return false; } @@ -1457,7 +1463,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public boolean visit(MySqlCaseStatement x) { - // TODO Auto-generated method stub + accept(x.getWhenList()); return false; } @@ -1492,13 +1498,62 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS } @Override - public boolean visit(MySqlWhenfStatement x) { + public boolean visit(MySqlWhenStatement x) { + accept(x.getStatements()); + return false; + } + + @Override + public void endVisit(MySqlWhenStatement x) { + // TODO Auto-generated method stub + + } + + @Override + public boolean visit(MySqlLoopStatement x) { + accept(x.getStatements()); + return false; + } + + @Override + public void endVisit(MySqlLoopStatement x) { + // TODO Auto-generated method stub + + } + + @Override + public boolean visit(MySqlLeaveStatement x) { // TODO Auto-generated method stub return false; } @Override - public void endVisit(MySqlWhenfStatement x) { + public void endVisit(MySqlLeaveStatement x) { + // TODO Auto-generated method stub + + } + + @Override + public boolean visit(MySqlIterateStatement x) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void endVisit(MySqlIterateStatement x) { + // TODO Auto-generated method stub + + } + + @Override + public boolean visit(MySqlRepeatStatement x) { + // TODO Auto-generated method stub + accept(x.getStatements()); + return false; + } + + @Override + public void endVisit(MySqlRepeatStatement 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 7234cb247c..ca4b1d9a97 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java @@ -139,7 +139,12 @@ public class Keywords { map.put("WHILE", Token.WHILE); map.put("DO", Token.DO); map.put("DECLARE", Token.DECLARE); - + map.put("LOOP", Token.LOOP); + map.put("LEAVE", Token.LEAVE); + map.put("ITERATE", Token.ITERATE); + map.put("REPEAT", Token.REPEAT); + map.put("UNTIL", Token.UNTIL); + 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 53e1a5ca44..5a6bb8c067 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -131,6 +131,10 @@ public enum Token { // MySql procedure by:zz WHILE("WHILE"), DO("DO"), + LEAVE("LEAVE"), + ITERATE("ITERATE"), + REPEAT("REPEAT"), + UNTIL("UNTIL"), //postgresql WINDOW("WINDOW"), diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest2.java new file mode 100644 index 0000000000..96bd4bd9ef --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest2.java @@ -0,0 +1,135 @@ +/* + * 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: procedure begin-end, loop, while use label + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 + */ +public class MySqlCreateProcedureTest2 extends MysqlTest { + + public void test_0() throws Exception { + String sql="create or replace procedure sp_name(level int,age int)"+ + " begin"+ + " declare x,y,z int;"+ + " lable_1: while x do"+ + " insert into test values(id,age);"+ + " end while lable_1;"+ + " 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(level int,age int)"+ + " begin"+ + " declare x,y,z int;"+ + " lable_1: begin"+ + " insert into test values(id,age);"+ + " end lable_1;"+ + " 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(level int,age int)"+ + " begin"+ + " declare x,y,z int;"+ + " lable_1: loop"+ + " insert into test values(id,age);"+ + " end loop lable_1;"+ + " 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"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest3.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest3.java new file mode 100644 index 0000000000..df524220a5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest3.java @@ -0,0 +1,138 @@ +/* + * 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: procedure begin-end, loop, while use label + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 + */ +public class MySqlCreateProcedureTest3 extends MysqlTest { + + public void test_0() throws Exception { + String sql="create or replace procedure sp_name(level int,age int)"+ + " begin"+ + " declare x,y,z int;"+ + " lable_1: while x do"+ + " insert into test values(id,age);"+ + " leave lable_1;"+ + " end while lable_1;"+ + " 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(level int,age int)"+ + " begin"+ + " declare x,y,z int;"+ + " lable_1: begin"+ + " insert into test values(id,age);"+ + " leave lable_1;"+ + " end lable_1;"+ + " 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(level int,age int)"+ + " begin"+ + " declare x,y,z int;"+ + " lable_1: loop"+ + " insert into test values(id,age);"+ + " leave lable_1;"+ + " end loop lable_1;"+ + " 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"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest4.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest4.java new file mode 100644 index 0000000000..7ab96ea29c --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest4.java @@ -0,0 +1,105 @@ +/* + * 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: procedure begin-end, loop, while use label + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 + */ +public class MySqlCreateProcedureTest4 extends MysqlTest { + + public void test_0() throws Exception { + String sql="create or replace procedure sp_name(level int,age int)"+ + " begin"+ + " declare x,y,z int;"+ + " repeat"+ + " insert into test values(id,age);"+ + " until x>10"+ + " end repeat;"+ + " 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(level int,age int)"+ + " begin"+ + " declare x,y,z int;"+ + " lable_1: repeat"+ + " insert into test values(id,age);"+ + " until x>10"+ + " end repeat lable_1;"+ + " 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"))); + } + +}