From 4b3ed4c71485cf99290347652ad7473dd4aa4fa9 Mon Sep 17 00:00:00 2001 From: fanglei <793514387@qq.com> Date: Tue, 3 Nov 2020 13:26:17 +0800 Subject: [PATCH] =?UTF-8?q?bug:=20mysql=E6=94=AF=E6=8C=81=E8=A7=A3?= =?UTF-8?q?=E6=9E=90if...elseif...elseif...end?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sql/dialect/mysql/parser/MySqlLexer.java | 1 + .../mysql/parser/MySqlStatementParser.java | 38 +++++++++---------- .../mysql/visitor/MySqlOutputVisitor.java | 2 +- .../druid/sql/parser/SQLStatementParser.java | 7 +++- .../com/alibaba/druid/sql/parser/Token.java | 2 +- .../sql/parser/MySQL_IF_ELSEIF_Test.java | 32 ++++++++++++++++ 6 files changed, 58 insertions(+), 24 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/sql/parser/MySQL_IF_ELSEIF_Test.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java index f1b8b0fb83..f9fc40f61b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java @@ -39,6 +39,7 @@ public class MySqlLexer extends Lexer { map.put("DUAL", Token.DUAL); map.put("FALSE", Token.FALSE); map.put("IF", Token.IF); + map.put("ELSEIF", Token.ELSEIF); map.put("KILL", Token.KILL); map.put("LIMIT", Token.LIMIT); 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 7c8f9ee353..f2571c00aa 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 @@ -8818,28 +8818,24 @@ public class MySqlStatementParser extends SQLStatementParser { this.parseStatementList(stmt.getStatements(), -1, stmt); - while (lexer.token() == Token.ELSE) { + while (lexer.token() == Token.ELSEIF) { lexer.nextToken(); - - if (lexer.token() == Token.IF) { - lexer.nextToken(); - - SQLIfStatement.ElseIf elseIf = new SQLIfStatement.ElseIf(); - - elseIf.setCondition(this.exprParser.expr()); - elseIf.setParent(stmt); - - accept(Token.THEN); - this.parseStatementList(elseIf.getStatements(), -1, elseIf); - - - stmt.getElseIfList().add(elseIf); - } else { - SQLIfStatement.Else elseItem = new SQLIfStatement.Else(); - this.parseStatementList(elseItem.getStatements(), -1, elseItem); - stmt.setElseItem(elseItem); - break; - } + SQLIfStatement.ElseIf elseIf = new SQLIfStatement.ElseIf(); + + elseIf.setCondition(this.exprParser.expr()); + elseIf.setParent(stmt); + + accept(Token.THEN); + this.parseStatementList(elseIf.getStatements(), -1, stmt); + + stmt.getElseIfList().add(elseIf); + } + + if(lexer.token() == Token.ELSE) { + lexer.nextToken(); + SQLIfStatement.Else elseItem = new SQLIfStatement.Else(); + this.parseStatementList(elseItem.getStatements(), -1, elseItem); + stmt.setElseItem(elseItem); } accept(Token.END); 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 fba5a274f6..b95d4ba101 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 @@ -4261,7 +4261,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public boolean visit(SQLIfStatement.ElseIf x) { - print0(ucase ? "ELSE IF " : "else if "); + print0(ucase ? "ELSEIF " : "elseif "); x.getCondition().accept(this); print0(ucase ? " THEN" : " then"); this.indentCount++; diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index 951642723c..4273d63077 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -582,7 +582,12 @@ public class SQLStatementParser extends SQLParser { stmt.setParent(parent); continue; } - + + if (lexer.token() == Token.ELSEIF + && parent instanceof SQLIfStatement) { + break; + } + int size = statementList.size(); if (parseStatementListDialect(statementList)) { if (parent != null) { 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 e728c7ba14..e44914e303 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -132,7 +132,7 @@ public enum Token { SHOW("SHOW"), REPLACE("REPLACE"), PERIOD("PERIOD"), - + ELSEIF("ELSEIF"), BITS, // MySql procedure add by zz diff --git a/src/test/java/com/alibaba/druid/sql/parser/MySQL_IF_ELSEIF_Test.java b/src/test/java/com/alibaba/druid/sql/parser/MySQL_IF_ELSEIF_Test.java new file mode 100644 index 0000000000..66998f2874 --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/parser/MySQL_IF_ELSEIF_Test.java @@ -0,0 +1,32 @@ +package com.alibaba.druid.sql.parser; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class MySQL_IF_ELSEIF_Test extends TestCase { + + public void test_IF_ELSEIF(){ + String sql = "CREATE TRIGGER trg_test1 BEFORE INSERT ON test_table_name FOR EACH ROW\n" + + "begin\n" + + "\tIF new.BSRQ IS NOT NULL THEN\n" + + "\t\tset new.SJRQ1 = new.BSRQ;\n" + + "\tELSEIF new.SJRQ1 IS NOT NULL THEN\n" + + "\t\tset new.BSRQ = new.SJRQ1;\n" + + "\t\tset new.SJRQ2 =new.SJRQ1;\n" + + " ELSEIF new.SJRQ2 IS NOT NULL THEN\n" + + "\t\tset new.SJRQ1 =new.SJRQ2;\n" + + "\tEND IF;\n" + + "end;"; + List stmtList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL); + StringBuilder out = new StringBuilder(); + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmtList.get(0).accept(visitor); + System.out.println(stmtList.get(0).toString()); + } +}