diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLVariantRefExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLVariantRefExpr.java index 1e6928b022..8f4e67161a 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLVariantRefExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLVariantRefExpr.java @@ -30,7 +30,7 @@ public class SQLVariantRefExpr extends SQLExprImpl { private boolean global = false; - private boolean hasSessionBefore = false; + private boolean session = false; private int index = -1; @@ -43,10 +43,10 @@ public class SQLVariantRefExpr extends SQLExprImpl { this.global = global; } - public SQLVariantRefExpr(String name, boolean global,boolean hasSessionBefore){ + public SQLVariantRefExpr(String name, boolean global,boolean session){ this.name = name; this.global = global; - this.hasSessionBefore = hasSessionBefore; + this.session = session; } public SQLVariantRefExpr(){ @@ -74,12 +74,12 @@ public class SQLVariantRefExpr extends SQLExprImpl { } - public boolean isHasSessionBefore() { - return hasSessionBefore; + public boolean isSession() { + return session; } - public void setHasSessionBefore(boolean hasSessionBefore) { - this.hasSessionBefore = hasSessionBefore; + public void setSession(boolean session) { + this.session = session; } @Override diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlFlushStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlFlushStatement.java index 634e3cb67f..f10683eb42 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlFlushStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlFlushStatement.java @@ -50,6 +50,7 @@ public class MySqlFlushStatement extends MySqlStatementImpl { private boolean slowLogs; private boolean status; private boolean userResources; + private boolean tableOption; public boolean isNoWriteToBinlog() { return noWriteToBinlog; @@ -207,6 +208,14 @@ public class MySqlFlushStatement extends MySqlStatementImpl { this.errorLogs = errorLogs; } + public boolean isTableOption() { + return tableOption; + } + + public void setTableOption(boolean tableOption) { + this.tableOption = tableOption; + } + public void accept0(MySqlASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, tables); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionStatement.java index e731b84c73..5897d6a23f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSetTransactionStatement.java @@ -29,15 +29,15 @@ public class MySqlSetTransactionStatement extends MySqlStatementImpl { private String accessModel; - private Boolean hasSessionBefore; + private Boolean session; - public Boolean getHasSessionBefore() { - return hasSessionBefore; + public Boolean getSession() { + return session; } - public void setHasSessionBefore(Boolean hasSessionBefore) { - this.hasSessionBefore = hasSessionBefore; + public void setSession(Boolean session) { + this.session = session; } public void accept0(MySqlASTVisitor visitor) { 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 024c4e2949..4aa8901a60 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 @@ -935,16 +935,7 @@ public class MySqlStatementParser extends SQLStatementParser { } for (;;) { - if (lexer.token() == Token.WITH) { - lexer.nextToken(); - acceptIdentifier("READ"); - accept(Token.LOCK); - stmt.setWithReadLock(true); - } else if (lexer.token() == Token.FOR) { - lexer.nextToken(); - acceptIdentifier("EXPORT"); - stmt.setForExport(true); - } else if (lexer.identifierEquals("BINARY") || lexer.token() == Token.BINARY) { + if (lexer.token() == Token.BINARY || lexer.identifierEquals("BINARY")) { lexer.nextToken(); acceptIdentifier("LOGS"); stmt.setBinaryLogs(true); @@ -992,28 +983,61 @@ public class MySqlStatementParser extends SQLStatementParser { lexer.nextToken(); acceptIdentifier("LOGS"); stmt.setSlowLogs(true); - } else if (lexer.identifierEquals("STATUS")) { + } else if (lexer.identifierEquals(STATUS)) { lexer.nextToken(); stmt.setStatus(true); - } else if (lexer.identifierEquals("USER_RESOURCES")) { + } else if (lexer.identifierEquals("USER_RESOURCES")) { lexer.nextToken(); stmt.setUserResources(true); - } else if (lexer.identifierEquals(FnvHash.Constants.TABLES)) { + } else if (lexer.token() == Token.COMMA) { lexer.nextToken(); - for (;;) { - SQLName name = this.exprParser.name(); - stmt.addTable(name); + continue; + } else { + break; + } + } - if (lexer.token() == Token.COMMA) { - lexer.nextToken(); - continue; + if (lexer.identifierEquals("TABLES")) { + lexer.nextToken(); + + stmt.setTableOption(true); + + if (lexer.token() == Token.WITH) { + lexer.nextToken(); + acceptIdentifier("READ"); + accept(Token.LOCK); + stmt.setWithReadLock(true); + } + for(;;) { + if (lexer.token() == Token.IDENTIFIER) { + for (; ; ) { + SQLName name = this.exprParser.name(); + stmt.addTable(name); + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; } break; } break; - } else { - break; } + + if (stmt.getTables().size() != 0) { + if (lexer.token() == Token.FOR) { + lexer.nextToken(); + acceptIdentifier("EXPORT"); + stmt.setForExport(true); + } else if (lexer.token() == Token.WITH) { + lexer.nextToken(); + acceptIdentifier("READ"); + accept(Token.LOCK); + stmt.setWithReadLock(true); + } + } + } return stmt; @@ -2609,20 +2633,20 @@ public class MySqlStatementParser extends SQLStatementParser { } Boolean global = null; - Boolean sessionBefore = null; + Boolean session = null; if (lexer.identifierEquals(GLOBAL)) { global = Boolean.TRUE; lexer.nextToken(); } else if (lexer.identifierEquals(SESSION)) { global = Boolean.FALSE; - sessionBefore = Boolean.TRUE; + session = Boolean.TRUE; lexer.nextToken(); } if (lexer.identifierEquals("TRANSACTION")) { MySqlSetTransactionStatement stmt = new MySqlSetTransactionStatement(); stmt.setGlobal(global); - stmt.setHasSessionBefore(sessionBefore); + stmt.setSession(session); lexer.nextToken(); if (lexer.identifierEquals("ISOLATION")) { @@ -2722,14 +2746,14 @@ public class MySqlStatementParser extends SQLStatementParser { parseAssignItems(stmt.getItems(), stmt); - if (global != null && global.booleanValue()) { + if (global != null && global) { SQLVariantRefExpr varRef = (SQLVariantRefExpr) stmt.getItems().get(0).getTarget(); varRef.setGlobal(true); } - if(sessionBefore != null && sessionBefore.booleanValue()){ + if(session != null && session){ SQLVariantRefExpr varRef = (SQLVariantRefExpr) stmt.getItems().get(0).getTarget(); - varRef.setHasSessionBefore(true); + varRef.setSession(true); } if (lexer.token() == Token.HINT) { 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 cfc156045f..9a6b8d4575 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 @@ -655,7 +655,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV if (x.isGlobal()) { print0("@@global."); - }else if(x.isHasSessionBefore()){ + }else if(x.isSession()){ print0("@@session."); } @@ -3586,83 +3586,76 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV public boolean visit(MySqlFlushStatement x) { print0(ucase ? "FLUSH" : "flush"); - if (x.isBinaryLogs()) { + if (x.isNoWriteToBinlog()) { + print0(ucase ? " NO_WRITE_TO_BINLOG" : " no_write_to_binlog"); + } else if (x.isLocal()) { + print0(ucase ? " LOCAL" : " local"); + } + + if(x.isBinaryLogs()) { print0(ucase ? " BINARY LOGS" : " binary logs"); } - - if (x.isPrivileges()) { - print0(ucase ? " PRIVILEGES" : " privileges"); - } - if (x.isDesKeyFile()) { print0(ucase ? " DES_KEY_FILE" : " des_key_file"); } - if (x.isEngineLogs()) { print0(ucase ? " ENGINE LOGS" : " engine logs"); } - if (x.isErrorLogs()) { print0(ucase ? " ERROR LOGS" : " error logs"); } - if (x.isGeneralLogs()) { print0(ucase ? " GENERAL LOGS" : " general logs"); } - if (x.isHots()) { print0(ucase ? " HOSTS" : " hosts"); } - if (x.isLogs()) { print0(ucase ? " LOGS" : " logs"); } - + if (x.isPrivileges()) { + print0(ucase ? " PRIVILEGES" : " privileges"); + } if (x.isOptimizerCosts()) { print0(ucase ? " OPTIMIZER_COSTS" : " optimizer_costs"); } - if (x.isQueryCache()) { print0(ucase ? " QUERY CACHE" : " query cache"); } - - if (x.isSlowLogs()) { - print0(ucase ? " SLOW LOGS" : " slow logs"); - } - - if (x.isStatus()) { - print0(ucase ? " STATUS" : " status"); - } - - if (x.isUserResources()) { - print0(ucase ? " USER_RESOURCES" : " user_resources"); - } - if (x.isRelayLogs()) { print0(ucase ? " RELAY LOGS" : " relay logs"); - SQLExpr channel = x.getRelayLogsForChannel(); if (channel != null) { print(' '); channel.accept(this); } } + if (x.isSlowLogs()) { + print0(ucase ? " SLOW LOGS" : " slow logs"); + } + if (x.isStatus()) { + print0(ucase ? " STATUS" : " status"); + } + if (x.isUserResources()) { + print0(ucase ? " USER_RESOURCES" : " user_resources"); + } - List tables = x.getTables(); - if (tables != null && tables.size() > 0) { + if(x.isTableOption()){ print0(ucase ? " TABLES" : " tables"); - if (tables.size() > 0) { + + List tables = x.getTables(); + if (tables != null && tables.size() > 0) { print(' '); printAndAccept(tables, ", "); } - } - if (x.isWithReadLock()) { - print0(ucase ? " WITH READ LOCK" : " with read lock"); - } + if (x.isWithReadLock()) { + print0(ucase ? " WITH READ LOCK" : " with read lock"); + } - if (x.isForExport()) { - print0(ucase ? " FOR EXPORT" : " for export"); + if (x.isForExport()) { + print0(ucase ? " FOR EXPORT" : " for export"); + } } return false; } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 2832aaaa85..b604f461dc 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -1327,6 +1327,7 @@ public class SQLExprParser extends SQLParser { case SCHEMA: case INTERVAL: case EXPLAIN: + case SET: identName = lexer.stringVal(); lexer.nextToken(); break; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/createTable/MySqlCreateTableTest92.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/createTable/MySqlCreateTableTest92.java new file mode 100644 index 0000000000..1a28870d56 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/createTable/MySqlCreateTableTest92.java @@ -0,0 +1,29 @@ +package com.alibaba.druid.bvt.sql.mysql.createTable; + +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.ast.statement.MySqlCreateTableStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import org.junit.Assert; + +import java.util.List; + +public class MySqlCreateTableTest92 extends MysqlTest { + + public void test_0() throws Exception { + String sql = "CREATE TABLE `test` (\n" + + " `id` bigint(20) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT 'id',\n" + + " `c_set` set('a','b','c') COMMENT 'set',\n" + " PRIMARY KEY (`id`)\n" + + ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='10000000';"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + MySqlCreateTableStatement statemen = (MySqlCreateTableStatement)statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + Assert.assertEquals(3, statemen.getTableElementList().size()); + Assert.assertEquals("`c_set` set('a', 'b', 'c') COMMENT 'set'", SQLUtils.toMySqlString(statemen.getTableElementList().get(1))); + + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/druid/mysql/MysqlCreateTableTest.java b/src/test/java/com/alibaba/druid/mysql/MysqlVarantRefTest.java similarity index 82% rename from src/test/java/com/alibaba/druid/mysql/MysqlCreateTableTest.java rename to src/test/java/com/alibaba/druid/mysql/MysqlVarantRefTest.java index 452d3f8fe0..c4afc0401c 100644 --- a/src/test/java/com/alibaba/druid/mysql/MysqlCreateTableTest.java +++ b/src/test/java/com/alibaba/druid/mysql/MysqlVarantRefTest.java @@ -16,7 +16,7 @@ import java.util.List; /** * Created by szf on 2017/11/16. */ -public class MysqlCreateTableTest { +public class MysqlVarantRefTest { @Test public void test(){ @@ -28,8 +28,8 @@ public class MysqlCreateTableTest { SQLVariantRefExpr resultExpr = (SQLVariantRefExpr)result.getItems().get(0).getTarget(); SQLVariantRefExpr resultExpr2 = (SQLVariantRefExpr)result.getItems().get(1).getTarget(); - Assert.assertTrue(resultExpr.isHasSessionBefore()); - Assert.assertTrue(resultExpr2.isHasSessionBefore()); + Assert.assertTrue(resultExpr.isSession()); + Assert.assertTrue(resultExpr2.isSession()); } @Test @@ -54,7 +54,7 @@ public class MysqlCreateTableTest { MySqlSetTransactionStatement x = (MySqlSetTransactionStatement)stmtList.get(0); - Assert.assertTrue(x.getHasSessionBefore()); + Assert.assertTrue(x.getSession()); } @Test @@ -65,7 +65,7 @@ public class MysqlCreateTableTest { MySqlSetTransactionStatement x = (MySqlSetTransactionStatement)stmtList.get(0); - Assert.assertTrue(x.getHasSessionBefore()==null); + Assert.assertTrue(x.getSession() == null); } @Test @@ -78,8 +78,8 @@ public class MysqlCreateTableTest { SQLVariantRefExpr resultExpr = (SQLVariantRefExpr)result.getItems().get(0).getTarget(); SQLVariantRefExpr resultExpr2 = (SQLVariantRefExpr)result.getItems().get(1).getTarget(); - Assert.assertTrue(resultExpr.isHasSessionBefore()); - Assert.assertTrue(!resultExpr2.isHasSessionBefore()); + Assert.assertTrue(resultExpr.isSession()); + Assert.assertTrue(!resultExpr2.isSession()); } @@ -93,8 +93,8 @@ public class MysqlCreateTableTest { SQLVariantRefExpr resultExpr = (SQLVariantRefExpr)result.getItems().get(0).getTarget(); SQLVariantRefExpr resultExpr2 = (SQLVariantRefExpr)result.getItems().get(1).getTarget(); - Assert.assertTrue(!resultExpr.isHasSessionBefore()); - Assert.assertTrue(!resultExpr2.isHasSessionBefore()); + Assert.assertTrue(!resultExpr.isSession()); + Assert.assertTrue(!resultExpr2.isSession()); } @@ -108,8 +108,8 @@ public class MysqlCreateTableTest { SQLVariantRefExpr resultExpr = (SQLVariantRefExpr)result.getItems().get(0).getTarget(); SQLVariantRefExpr resultExpr2 = (SQLVariantRefExpr)result.getItems().get(1).getTarget(); - Assert.assertTrue(!resultExpr.isHasSessionBefore()); - Assert.assertTrue(resultExpr2.isHasSessionBefore()); + Assert.assertTrue(!resultExpr.isSession()); + Assert.assertTrue(resultExpr2.isSession()); } @@ -124,9 +124,9 @@ public class MysqlCreateTableTest { SQLVariantRefExpr resultExpr = (SQLVariantRefExpr)result.getItems().get(0).getTarget(); SQLVariantRefExpr resultExpr2 = (SQLVariantRefExpr)result.getItems().get(1).getTarget(); SQLVariantRefExpr resultExpr3 = (SQLVariantRefExpr)result.getItems().get(2).getTarget(); - Assert.assertTrue(!resultExpr.isHasSessionBefore()); - Assert.assertTrue(resultExpr2.isHasSessionBefore()); - Assert.assertTrue(resultExpr3.isHasSessionBefore()); + Assert.assertTrue(!resultExpr.isSession()); + Assert.assertTrue(resultExpr2.isSession()); + Assert.assertTrue(resultExpr3.isSession()); } @@ -143,11 +143,11 @@ public class MysqlCreateTableTest { SQLVariantRefExpr resultExpr3 = (SQLVariantRefExpr)result.getItems().get(2).getTarget(); SQLVariantRefExpr resultExpr4 = (SQLVariantRefExpr)result.getItems().get(3).getTarget(); SQLVariantRefExpr resultExpr5 = (SQLVariantRefExpr)result.getItems().get(4).getTarget(); - Assert.assertTrue(!resultExpr.isHasSessionBefore()); - Assert.assertTrue(resultExpr2.isHasSessionBefore()); - Assert.assertTrue(resultExpr3.isHasSessionBefore()); - Assert.assertTrue(!resultExpr4.isHasSessionBefore()); - Assert.assertTrue(resultExpr5.isHasSessionBefore()); + Assert.assertTrue(!resultExpr.isSession()); + Assert.assertTrue(resultExpr2.isSession()); + Assert.assertTrue(resultExpr3.isSession()); + Assert.assertTrue(!resultExpr4.isSession()); + Assert.assertTrue(resultExpr5.isSession()); } }