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 64ce2ad047..7b2dbc246f 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 @@ -675,8 +675,16 @@ public class MySqlStatementParser extends SQLStatementParser { if (lexer.token() == Token.LOCK) { lexer.nextToken(); - acceptIdentifier(TABLES); - + String val = lexer.stringVal(); + boolean isLockTables = TABLES.equalsIgnoreCase(val) && lexer.token() == Token.IDENTIFIER; + boolean isLockTable = "TABLE".equalsIgnoreCase(val) && lexer.token() == Token.TABLE; + if (isLockTables || isLockTable) { + lexer.nextToken(); + } else { + setErrorEndPos(lexer.pos()); + throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token()); + } + MySqlLockTableStatement stmt = new MySqlLockTableStatement(); stmt.setTableSource(this.exprParser.name()); @@ -694,6 +702,8 @@ public class MySqlStatementParser extends SQLStatementParser { lexer.nextToken(); acceptIdentifier(WRITE); stmt.setLockType(LockType.LOW_PRIORITY_WRITE); + } else { + throw new ParserException("syntax error, expect READ or WRITE, actual " + lexer.token()); } if (lexer.token() == Token.HINT) { @@ -705,8 +715,16 @@ public class MySqlStatementParser extends SQLStatementParser { if (identifierEquals("UNLOCK")) { lexer.nextToken(); - acceptIdentifier(TABLES); + String val = lexer.stringVal(); + boolean isUnLockTables = TABLES.equalsIgnoreCase(val) && lexer.token() == Token.IDENTIFIER; + boolean isUnLockTable = "TABLE".equalsIgnoreCase(val) && lexer.token() == Token.TABLE; statementList.add(new MySqlUnlockTablesStatement()); + if (isUnLockTables || isUnLockTable) { + lexer.nextToken(); + } else { + setErrorEndPos(lexer.pos()); + throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token()); + } return true; } diff --git a/src/test/java/com/alibaba/druid/sql/parser/MySQLLockTableTest.java b/src/test/java/com/alibaba/druid/sql/parser/MySQLLockTableTest.java new file mode 100644 index 0000000000..c48a60b325 --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/parser/MySQLLockTableTest.java @@ -0,0 +1,50 @@ +package com.alibaba.druid.sql.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement.LockType; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; + +public class MySQLLockTableTest extends TestCase { + + public void testLockTables() { + String stmt1 = "lock tables tt_table read"; + MySqlStatementParser parser1 = new MySqlStatementParser(stmt1); + MySqlLockTableStatement statment1 = (MySqlLockTableStatement) parser1.parseStatement(); + Assert.assertTrue("tt_table".equalsIgnoreCase(statment1.getTableSource().toString())); + Assert.assertTrue(LockType.READ == statment1.getLockType()); + + String stmt2 = "lock tables tt_table write"; + MySqlStatementParser parser2 = new MySqlStatementParser(stmt2); + MySqlLockTableStatement statment2 = (MySqlLockTableStatement) parser2.parseStatement(); + Assert.assertTrue("tt_table".equalsIgnoreCase(statment2.getTableSource().toString())); + Assert.assertTrue(LockType.WRITE == statment2.getLockType()); + + String stmt3 = "lock table tt_table read"; + MySqlStatementParser parser3 = new MySqlStatementParser(stmt3); + MySqlLockTableStatement statment3 = (MySqlLockTableStatement) parser3.parseStatement(); + Assert.assertTrue("tt_table".equalsIgnoreCase(statment3.getTableSource().toString())); + Assert.assertTrue(LockType.READ == statment3.getLockType()); + + String stmt4 = "lock table tt_table write"; + MySqlStatementParser parser4 = new MySqlStatementParser(stmt4); + MySqlLockTableStatement statment4 = (MySqlLockTableStatement) parser4.parseStatement(); + Assert.assertTrue("tt_table".equalsIgnoreCase(statment4.getTableSource().toString())); + Assert.assertTrue(LockType.WRITE == statment4.getLockType()); + } + + public void testUnlockTables() { + String stmt1 = "unlock tables"; + String stmt2 = "unlock table"; + MySqlStatementParser parser1 = new MySqlStatementParser(stmt1); + MySqlStatementParser parser2 = new MySqlStatementParser(stmt2); + MySqlUnlockTablesStatement statment1 = (MySqlUnlockTablesStatement)parser1.parseStatement(); + MySqlUnlockTablesStatement statment2 = (MySqlUnlockTablesStatement)parser2.parseStatement(); + Assert.assertTrue(true); + } + +}