From 59cc507f4210ccc773aa029c655d3d55c282b51d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AB=98=E9=93=81?= Date: Sat, 25 Jun 2016 12:13:08 +0800 Subject: [PATCH] mysql sql parser support wait_n & no_wat --- .../ast/statement/MySqlSelectQueryBlock.java | 18 +++++ .../mysql/parser/MySqlSelectParser.java | 9 +++ .../mysql/visitor/MySqlOutputVisitor.java | 6 ++ .../bvt/sql/mysql/MySqlSelectTest_30.java | 72 +++++++++++++++++++ .../bvt/sql/mysql/MySqlSelectTest_31.java | 72 +++++++++++++++++++ 5 files changed, 177 insertions(+) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_30.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_31.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java index d51e4805c4..de75421297 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java @@ -47,6 +47,8 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlO private List procedureArgumentList; private boolean forUpdate = false; + private boolean noWait = false; + private SQLExpr waitTime; private boolean lockInShareMode = false; private List hints; @@ -81,6 +83,22 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlO public void setForUpdate(boolean forUpdate) { this.forUpdate = forUpdate; } + + public boolean isNoWait() { + return noWait; + } + + public void setNoWait(boolean noWait) { + this.noWait = noWait; + } + + public SQLExpr getWaitTime() { + return waitTime; + } + + public void setWaitTime(SQLExpr waitTime) { + this.waitTime = waitTime; + } public boolean isLockInShareMode() { return lockInShareMode; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java index a95353cf9d..aea311e3be 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java @@ -179,6 +179,15 @@ public class MySqlSelectParser extends SQLSelectParser { accept(Token.UPDATE); queryBlock.setForUpdate(true); + + if (identifierEquals("NO_WAIT")) { + lexer.nextToken(); + queryBlock.setNoWait(true); + } else if (identifierEquals("WAIT")) { + lexer.nextToken(); + SQLExpr waitTime = this.exprParser.primary(); + queryBlock.setWaitTime(waitTime); + } } if (lexer.token() == Token.LOCK) { 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 829ddcb2d3..dedad6c518 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 @@ -287,6 +287,12 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV if (x.isForUpdate()) { println(); print0(ucase ? "FOR UPDATE" : "for update"); + if (x.isNoWait()) { + print0(ucase ? " NO_WAIT" : " no_wait"); + } else if (x.getWaitTime() != null) { + print0(ucase ? " WAIT " : " wait "); + x.getWaitTime().accept(this); + } } if (x.isLockInShareMode()) { diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_30.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_30.java new file mode 100644 index 0000000000..ccaf4c4752 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_30.java @@ -0,0 +1,72 @@ +/* + * Copyright 1999-2101 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.mysql; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; + +public class MySqlSelectTest_30 extends MysqlTest { + + public void test_0() throws Exception { + String sql = "SELECT name from tab1 for update no_wait"; + + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); +// print(statementList); + + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(1, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + Assert.assertEquals(0, visitor.getOrderByColumns().size()); + + { + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("SELECT name" + + "\nFROM tab1" + + "\nFOR UPDATE NO_WAIT", // + output); + } + { + String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); + Assert.assertEquals("select name" + + "\nfrom tab1" + + "\nfor update no_wait", // + output); + } + } + + + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_31.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_31.java new file mode 100644 index 0000000000..0038e52636 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_31.java @@ -0,0 +1,72 @@ +/* + * Copyright 1999-2101 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.mysql; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; + +public class MySqlSelectTest_31 extends MysqlTest { + + public void test_0() throws Exception { + String sql = "SELECT name from tab1 for update wait 3"; + + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); +// print(statementList); + + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(1, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + Assert.assertEquals(0, visitor.getOrderByColumns().size()); + + { + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("SELECT name" + + "\nFROM tab1" + + "\nFOR UPDATE WAIT 3", // + output); + } + { + String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); + Assert.assertEquals("select name" + + "\nfrom tab1" + + "\nfor update wait 3", // + output); + } + } + + + +}