#1645 - Added full support for MySQL EXPLAIN / DESCRIBE.

This commit is contained in:
Bob Tiernay
2017-03-21 20:58:51 -04:00
parent a861aeab24
commit 6c147a5667
13 changed files with 1081 additions and 433 deletions
@@ -0,0 +1,23 @@
/*
* Copyright 1999-2017 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;
public enum MySqlExplainType {
EXTENDED,
PARTITIONS,
FORMAT
}
@@ -0,0 +1,22 @@
/*
* Copyright 1999-2017 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;
public enum MySqlFormatName {
TRADITIONAL,
JSON
}
@@ -1,52 +0,0 @@
/*
* Copyright 1999-2017 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.statement;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.statement.SQLDescribeStatement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class MySqlDescribeStatement extends SQLDescribeStatement implements MySqlStatement {
private SQLName colName;
public void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, object);
acceptChild(visitor, colName);
}
visitor.endVisit(this);
}
@Override
public void accept0(SQLASTVisitor visitor) {
if (visitor instanceof MySqlASTVisitor) {
accept0((MySqlASTVisitor) visitor);
} else {
throw new IllegalArgumentException("not support visitor type : " + visitor.getClass().getName());
}
}
public SQLName getColName() {
return colName;
}
public void setColName(SQLName colName) {
this.colName = colName;
}
}
@@ -0,0 +1,133 @@
/*
* Copyright 1999-2017 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.statement;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.statement.SQLExplainStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlExplainType;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlFormatName;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class MySqlExplainStatement extends SQLExplainStatement implements MySqlStatement {
private boolean describe;
private SQLName tableName;
private SQLName columnName;
private SQLExpr wild;
private MySqlExplainType type;
private MySqlFormatName formatName;
private SQLExpr connectionId;
public MySqlExplainStatement() {
super (JdbcConstants.MYSQL);
}
@Override
public void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
// tbl_name [col_name | wild]
if (tableName != null) {
acceptChild(visitor, tableName);
if (columnName != null) {
acceptChild(visitor, columnName);
} else if (wild != null) {
acceptChild(visitor, wild);
}
} else {
// {explainable_stmt | FOR CONNECTION connection_id}
if (connectionId != null) {
acceptChild(visitor, connectionId);
} else {
acceptChild(visitor, statement);
}
}
}
visitor.endVisit(this);
}
protected void accept0(SQLASTVisitor visitor) {
accept0((MySqlASTVisitor) visitor);
}
public String toString() {
return SQLUtils.toMySqlString(this);
}
public boolean isDescribe() {
return describe;
}
public void setDescribe(boolean describe) {
this.describe = describe;
}
public SQLName getTableName() {
return tableName;
}
public void setTableName(SQLName tableName) {
this.tableName = tableName;
}
public SQLName getColumnName() {
return columnName;
}
public void setColumnName(SQLName columnName) {
this.columnName = columnName;
}
public SQLExpr getWild() {
return wild;
}
public void setWild(SQLExpr wild) {
this.wild = wild;
}
public MySqlExplainType getType() {
return type;
}
public void setType(MySqlExplainType type) {
this.type = type;
}
public MySqlFormatName getFormatName() {
return formatName;
}
public void setFormatName(MySqlFormatName formatName) {
this.formatName = formatName;
}
public SQLExpr getConnectionId() {
return connectionId;
}
public void setConnectionId(SQLExpr connectionId) {
this.connectionId = connectionId;
}
}
@@ -15,9 +15,6 @@
*/
package com.alibaba.druid.sql.dialect.mysql.parser;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
import com.alibaba.druid.sql.ast.SQLDeclareItem;
@@ -37,8 +34,56 @@ import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.ast.statement.SQLAlterDatabaseStatement;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddColumn;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddConstraint;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddIndex;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddPartition;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAnalyzePartition;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableCheckPartition;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableCoalescePartition;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableConvertCharSet;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDisableConstraint;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDisableKeys;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDiscardPartition;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropColumnItem;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropConstraint;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropForeignKey;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropIndex;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropKey;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropPartition;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropPrimaryKey;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableEnableConstraint;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableEnableKeys;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableImportPartition;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableOptimizePartition;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableReOrganizePartition;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableRebuildPartition;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableRepairPartition;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableTruncatePartition;
import com.alibaba.druid.sql.ast.statement.SQLBlockStatement;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateDatabaseStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateProcedureStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLIfStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
import com.alibaba.druid.sql.ast.statement.SQLLoopStatement;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLShowTablesStatement;
import com.alibaba.druid.sql.ast.statement.SQLStartTransactionStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUnique;
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.ConditionValue;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.ConditionValue.ConditionType;
@@ -48,6 +93,8 @@ import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCursorDeclareStatemen
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareConditionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareHandlerStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlExplainType;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlFormatName;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlHandlerType;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIterateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLeaveStatement;
@@ -69,8 +116,8 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExplainStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHelpStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHintStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
@@ -85,7 +132,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStateme
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement;
import com.alibaba.druid.sql.ast.SQLLimit;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetPasswordStatement;
@@ -142,41 +188,50 @@ import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.parser.Token;
import com.alibaba.druid.util.JdbcConstants;
import java.util.ArrayList;
import java.util.List;
public class MySqlStatementParser extends SQLStatementParser {
private static final String AUTO_INCREMENT = "AUTO_INCREMENT";
private static final String COLLATE2 = "COLLATE";
private static final String CHAIN = "CHAIN";
private static final String ENGINES = "ENGINES";
private static final String ENGINE = "ENGINE";
private static final String BINLOG = "BINLOG";
private static final String EVENTS = "EVENTS";
private static final String CHARACTER = "CHARACTER";
private static final String SESSION = "SESSION";
private static final String GLOBAL = "GLOBAL";
private static final String VARIABLES = "VARIABLES";
private static final String ERRORS = "ERRORS";
private static final String STATUS = "STATUS";
private static final String IGNORE = "IGNORE";
private static final String RESET = "RESET";
private static final String DESCRIBE = "DESCRIBE";
private static final String WRITE = "WRITE";
private static final String READ = "READ";
private static final String LOCAL = "LOCAL";
private static final String TABLES = "TABLES";
private static final String TEMPORARY = "TEMPORARY";
private static final String SPATIAL = "SPATIAL";
private static final String FULLTEXT = "FULLTEXT";
private static final String DELAYED = "DELAYED";
private static final String LOW_PRIORITY = "LOW_PRIORITY";
private static final String COLLATE2 = "COLLATE";
private static final String CHAIN = "CHAIN";
private static final String ENGINES = "ENGINES";
private static final String ENGINE = "ENGINE";
private static final String BINLOG = "BINLOG";
private static final String EVENTS = "EVENTS";
private static final String CHARACTER = "CHARACTER";
private static final String SESSION = "SESSION";
private static final String GLOBAL = "GLOBAL";
private static final String VARIABLES = "VARIABLES";
private static final String ERRORS = "ERRORS";
private static final String STATUS = "STATUS";
private static final String IGNORE = "IGNORE";
private static final String RESET = "RESET";
private static final String DESCRIBE = "DESCRIBE";
private static final String WRITE = "WRITE";
private static final String READ = "READ";
private static final String LOCAL = "LOCAL";
private static final String TABLES = "TABLES";
private static final String TEMPORARY = "TEMPORARY";
private static final String SPATIAL = "SPATIAL";
private static final String FULLTEXT = "FULLTEXT";
private static final String DELAYED = "DELAYED";
private static final String LOW_PRIORITY = "LOW_PRIORITY";
private static final String CONNECTION = "CONNECTION";
private static final String EXTENDED = "EXTENDED";
private static final String PARTITIONS = "PARTITIONS";
private static final String FORMAT = "FORMAT";
private static final String TRADITIONAL = "TRADITIONAL";
private static final String JSON = "JSON";
private int maxIntoClause = -1;
public MySqlStatementParser(String sql){
public MySqlStatementParser(String sql) {
super(new MySqlExprParser(sql));
}
public MySqlStatementParser(Lexer lexer){
public MySqlStatementParser(Lexer lexer) {
super(new MySqlExprParser(lexer));
}
@@ -195,13 +250,13 @@ public class MySqlStatementParser extends SQLStatementParser {
public SQLStatement parseSelect() {
MySqlSelectParser selectParser = new MySqlSelectParser(this.exprParser);
SQLSelect select = selectParser.select();
if (selectParser.returningFlag) {
return selectParser.updateStmt;
}
return new SQLSelectStatement(select, JdbcConstants.MYSQL);
}
@@ -314,7 +369,7 @@ public class MySqlStatementParser extends SQLStatementParser {
}
if (lexer.token() == Token.UNIQUE || lexer.token() == Token.INDEX || identifierEquals(FULLTEXT)
|| identifierEquals(SPATIAL)) {
|| identifierEquals(SPATIAL)) {
if (replace) {
lexer.reset(markBp, markChar, Token.CREATE);
}
@@ -384,7 +439,7 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.LPAREN);
for (;;) {
for (; ; ) {
SQLSelectOrderByItem item = this.exprParser.parseSelectOrderByItem();
stmt.addItem(item);
if (lexer.token() == Token.COMMA) {
@@ -425,7 +480,7 @@ public class MySqlStatementParser extends SQLStatementParser {
MySqlCreateUserStatement stmt = new MySqlCreateUserStatement();
for (;;) {
for (; ; ) {
MySqlCreateUserStatement.UserSpecification userSpec = new MySqlCreateUserStatement.UserSpecification();
SQLExpr expr = exprParser.primary();
@@ -527,7 +582,7 @@ public class MySqlStatementParser extends SQLStatementParser {
MySqlResetStatement stmt = new MySqlResetStatement();
for (;;) {
for (; ; ) {
if (lexer.token() == Token.IDENTIFIER) {
if (identifierEquals("QUERY")) {
lexer.nextToken();
@@ -567,11 +622,11 @@ public class MySqlStatementParser extends SQLStatementParser {
statementList.add(stmt);
return true;
}
if(identifierEquals("DEALLOCATE")) {
MysqlDeallocatePrepareStatement stmt = parseDeallocatePrepare();
statementList.add(stmt);
return true;
if (identifierEquals("DEALLOCATE")) {
MysqlDeallocatePrepareStatement stmt = parseDeallocatePrepare();
statementList.add(stmt);
return true;
}
if (identifierEquals("LOAD")) {
@@ -598,6 +653,13 @@ public class MySqlStatementParser extends SQLStatementParser {
return true;
}
if (lexer.token() == Token.EXPLAIN) {
MySqlExplainStatement stmt = this.parseExplain();
statementList.add(stmt);
return true;
}
if (identifierEquals(BINLOG)) {
SQLStatement stmt = parseBinlog();
statementList.add(stmt);
@@ -642,12 +704,12 @@ public class MySqlStatementParser extends SQLStatementParser {
boolean isLockTables = TABLES.equalsIgnoreCase(val) && lexer.token() == Token.IDENTIFIER;
boolean isLockTable = "TABLE".equalsIgnoreCase(val) && lexer.token() == Token.TABLE;
if (isLockTables || isLockTable) {
lexer.nextToken();
lexer.nextToken();
} else {
setErrorEndPos(lexer.pos());
setErrorEndPos(lexer.pos());
throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token());
}
MySqlLockTableStatement stmt = new MySqlLockTableStatement();
stmt.setTableSource(this.exprParser.name());
@@ -666,7 +728,7 @@ public class MySqlStatementParser extends SQLStatementParser {
acceptIdentifier(WRITE);
stmt.setLockType(LockType.LOW_PRIORITY_WRITE);
} else {
throw new ParserException("syntax error, expect READ or WRITE, actual " + lexer.token());
throw new ParserException("syntax error, expect READ or WRITE, actual " + lexer.token());
}
if (lexer.token() == Token.HINT) {
@@ -683,9 +745,9 @@ public class MySqlStatementParser extends SQLStatementParser {
boolean isUnLockTable = "TABLE".equalsIgnoreCase(val) && lexer.token() == Token.TABLE;
statementList.add(new MySqlUnlockTablesStatement());
if (isUnLockTables || isUnLockTable) {
lexer.nextToken();
lexer.nextToken();
} else {
setErrorEndPos(lexer.pos());
setErrorEndPos(lexer.pos());
throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token());
}
return true;
@@ -736,19 +798,84 @@ public class MySqlStatementParser extends SQLStatementParser {
return block;
}
public MySqlDescribeStatement parseDescribe() {
public MySqlExplainStatement parseDescribe() {
// see https://dev.mysql.com/doc/refman/5.7/en/explain.html
MySqlExplainStatement describe = new MySqlExplainStatement();
// {DESCRIBE | DESC}
if (lexer.token() == Token.DESC || identifierEquals(DESCRIBE)) {
lexer.nextToken();
describe.setDescribe(true);
} else {
throw new ParserException("expect DESC, actual " + lexer.token());
throw new ParserException("expect one of {DESCRIBE | DESC} , actual " + lexer.token());
}
MySqlDescribeStatement stmt = new MySqlDescribeStatement();
stmt.setObject(this.exprParser.name());
if (lexer.token() == Token.IDENTIFIER) {
stmt.setColName(this.exprParser.name());
return parseExplain(describe);
}
public MySqlExplainStatement parseExplain() {
// see https://dev.mysql.com/doc/refman/5.7/en/explain.html
MySqlExplainStatement explain = new MySqlExplainStatement();
// {EXPLAIN}
if (lexer.token() == Token.EXPLAIN) {
lexer.nextToken();
} else {
throw new ParserException("expect EXPLAIN , actual " + lexer.token());
}
return stmt;
return parseExplain(explain);
}
private MySqlExplainStatement parseExplain(MySqlExplainStatement explain) {
// see https://dev.mysql.com/doc/refman/5.7/en/explain.html
boolean extended = lexer.token() == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase(EXTENDED);
boolean partitions = lexer.token() == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase(PARTITIONS);
boolean format = lexer.token() == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase(FORMAT);
boolean type = extended || partitions || format;
boolean forConnection = lexer.token() == Token.FOR;
boolean table = lexer.token() == Token.IDENTIFIER && !type && !forConnection;
// tbl_name [col_name | wild]
if (table) {
explain.setTableName(exprParser.name());
if (lexer.token() == Token.IDENTIFIER) {
explain.setColumnName(exprParser.name());
} else if (lexer.token() == Token.LITERAL_CHARS) {
explain.setWild(exprParser.expr());
}
} else if (type) {
// [explain_type]
if (extended) {
explain.setType(MySqlExplainType.EXTENDED);
} else if (partitions) {
explain.setType(MySqlExplainType.PARTITIONS);
} else if (format) {
explain.setType(MySqlExplainType.FORMAT);
lexer.nextToken();
accept(Token.EQ);
if (lexer.token() == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase(TRADITIONAL)) {
explain.setFormatName(MySqlFormatName.TRADITIONAL);
} else if (lexer.token() == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase(JSON)) {
explain.setFormatName(MySqlFormatName.JSON);
}
}
lexer.nextToken();
}
// {explainable_stmt | FOR CONNECTION connection_id}
if (lexer.token() == Token.FOR) {
lexer.nextToken();
acceptIdentifier(CONNECTION);
explain.setConnectionId(exprParser.expr());
} else if (!table) {
explain.setStatement(this.parseStatement());
}
return explain;
}
public SQLStatement parseShow() {
@@ -1269,7 +1396,7 @@ public class MySqlStatementParser extends SQLStatementParser {
lexer.nextToken();
MySqlShowProfileStatement stmt = new MySqlShowProfileStatement();
for (;;) {
for (; ; ) {
if (lexer.token() == Token.ALL) {
stmt.getTypes().add(MySqlShowProfileStatement.Type.ALL);
lexer.nextToken();
@@ -1679,7 +1806,7 @@ public class MySqlStatementParser extends SQLStatementParser {
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
stmt.getValuesList().add(values);
for (;;) {
for (; ; ) {
stmt.addColumn(this.exprParser.name());
if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
@@ -1943,14 +2070,14 @@ public class MySqlStatementParser extends SQLStatementParser {
}
public MysqlDeallocatePrepareStatement parseDeallocatePrepare() {
acceptIdentifier("DEALLOCATE");
acceptIdentifier("PREPARE");
MysqlDeallocatePrepareStatement stmt = new MysqlDeallocatePrepareStatement();
SQLName statementName = exprParser.name();
stmt.setStatementName(statementName);
return stmt;
acceptIdentifier("DEALLOCATE");
acceptIdentifier("PREPARE");
MysqlDeallocatePrepareStatement stmt = new MysqlDeallocatePrepareStatement();
SQLName statementName = exprParser.name();
stmt.setStatementName(statementName);
return stmt;
}
public SQLInsertStatement parseInsert() {
@@ -1959,7 +2086,7 @@ public class MySqlStatementParser extends SQLStatementParser {
if (lexer.token() == Token.INSERT) {
lexer.nextToken();
for (;;) {
for (; ; ) {
if (identifierEquals(LOW_PRIORITY)) {
insertStatement.setLowPriority(true);
lexer.nextToken();
@@ -1989,7 +2116,7 @@ public class MySqlStatementParser extends SQLStatementParser {
lexer.nextToken();
continue;
}
break;
}
@@ -2030,7 +2157,7 @@ public class MySqlStatementParser extends SQLStatementParser {
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
insertStatement.getValuesList().add(values);
for (;;) {
for (; ; ) {
SQLName name = this.exprParser.name();
insertStatement.addColumn(name);
if (lexer.token() == Token.EQ) {
@@ -2073,7 +2200,7 @@ public class MySqlStatementParser extends SQLStatementParser {
}
private void parseValueClause(List<ValuesClause> valueClauseList, int columnSize) {
for (int i = 0;;++i) {
for (int i = 0; ; ++i) {
if (lexer.token() != Token.LPAREN) {
throw new ParserException("syntax error, expect ')'");
}
@@ -2087,7 +2214,7 @@ public class MySqlStatementParser extends SQLStatementParser {
valueExprList = new ArrayList<SQLExpr>();
}
for (;;) {
for (; ; ) {
SQLExpr expr;
if (lexer.token() == Token.LITERAL_INT) {
expr = new SQLIntegerExpr(lexer.integerValue());
@@ -2330,7 +2457,7 @@ public class MySqlStatementParser extends SQLStatementParser {
stmt.setIgnore(ignore);
stmt.setName(this.exprParser.name());
for (;;) {
for (; ; ) {
if (lexer.token() == Token.DROP) {
parseAlterDrop(stmt);
} else if (lexer.token() == Token.TRUNCATE) {
@@ -2465,42 +2592,42 @@ public class MySqlStatementParser extends SQLStatementParser {
stmt.addItem(item);
} else if (identifierEquals("MODIFY")) {
lexer.nextToken();
if (lexer.token() == Token.COLUMN) {
lexer.nextToken();
}
boolean paren = false;
if (lexer.token() == Token.LPAREN) {
paren = true;
lexer.nextToken();
paren = true;
lexer.nextToken();
}
for (;;) {
MySqlAlterTableModifyColumn item = new MySqlAlterTableModifyColumn();
item.setNewColumnDefinition(this.exprParser.parseColumn());
if (identifierEquals("AFTER")) {
lexer.nextToken();
item.setAfterColumn(this.exprParser.name());
} else if (identifierEquals("FIRST")) {
lexer.nextToken();
if (lexer.token() == Token.IDENTIFIER) {
item.setFirstColumn(this.exprParser.name());
} else {
item.setFirst(true);
}
}
stmt.addItem(item);
if (paren && lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
for (; ; ) {
MySqlAlterTableModifyColumn item = new MySqlAlterTableModifyColumn();
item.setNewColumnDefinition(this.exprParser.parseColumn());
if (identifierEquals("AFTER")) {
lexer.nextToken();
item.setAfterColumn(this.exprParser.name());
} else if (identifierEquals("FIRST")) {
lexer.nextToken();
if (lexer.token() == Token.IDENTIFIER) {
item.setFirstColumn(this.exprParser.name());
} else {
item.setFirst(true);
}
}
stmt.addItem(item);
if (paren && lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
if (paren) {
accept(Token.RPAREN);
accept(Token.RPAREN);
}
} else if (lexer.token() == Token.DISABLE) {
lexer.nextToken();
@@ -2648,7 +2775,7 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.INTO);
accept(Token.LPAREN);
for (;;) {
for (; ; ) {
SQLPartition partition = this.getExprParser().parsePartition();
item.addPartition(partition);
@@ -2677,7 +2804,7 @@ public class MySqlStatementParser extends SQLStatementParser {
} else {
this.exprParser.names(item.getPartitions(), item);
}
stmt.addItem(item);
} else if (identifierEquals("REBUILD")) {
lexer.nextToken();
@@ -2692,7 +2819,7 @@ public class MySqlStatementParser extends SQLStatementParser {
} else {
this.exprParser.names(item.getPartitions(), item);
}
stmt.addItem(item);
} else if (identifierEquals("REPAIR")) {
lexer.nextToken();
@@ -2707,7 +2834,7 @@ public class MySqlStatementParser extends SQLStatementParser {
} else {
this.exprParser.names(item.getPartitions(), item);
}
stmt.addItem(item);
} else if (identifierEquals("REMOVE")) {
lexer.nextToken();
@@ -2815,7 +2942,7 @@ public class MySqlStatementParser extends SQLStatementParser {
}
SQLAlterTableAddColumn item = new SQLAlterTableAddColumn();
for (;;) {
for (; ; ) {
SQLColumnDefinition columnDef = this.exprParser.parseColumn();
item.addColumn(columnDef);
@@ -2922,7 +3049,7 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.TABLE);
for (;;) {
for (; ; ) {
MySqlRenameTableStatement.Item item = new MySqlRenameTableStatement.Item();
item.setName(this.exprParser.name());
accept(Token.TO);
@@ -2970,7 +3097,7 @@ public class MySqlStatementParser extends SQLStatementParser {
if (lexer.token() == Token.DEFAULT) {
lexer.nextToken();
}
if (identifierEquals("CHARACTER")) {
lexer.nextToken();
accept(Token.SET);
@@ -2986,7 +3113,7 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.IDENTIFIER);
stmt.setCharacterSet(charset);
}
if (lexer.token() == Token.DEFAULT) {
lexer.nextToken();
}
@@ -3007,7 +3134,7 @@ public class MySqlStatementParser extends SQLStatementParser {
protected void parseUpdateSet(SQLUpdateStatement update) {
accept(Token.SET);
for (;;) {
for (; ; ) {
SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem();
update.addItem(item);
@@ -3042,7 +3169,7 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.USER);
MySqlAlterUserStatement stmt = new MySqlAlterUserStatement();
for (;;) {
for (; ; ) {
SQLExpr user = this.exprParser.expr();
acceptIdentifier("PASSWORD");
acceptIdentifier("EXPIRE");
@@ -3104,7 +3231,7 @@ public class MySqlStatementParser extends SQLStatementParser {
/**
* parse create procedure parameters
*
*
* @param parameters
*/
private void parserParameters(List<SQLParameter> parameters) {
@@ -3112,7 +3239,7 @@ public class MySqlStatementParser extends SQLStatementParser {
return;
}
for (;;) {
for (; ; ) {
SQLParameter parameter = new SQLParameter();
if (lexer.token() == Token.CURSOR) {
@@ -3169,7 +3296,7 @@ public class MySqlStatementParser extends SQLStatementParser {
/**
* parse procedure statement block
*
*
* @param statementList
*/
private void parseProcedureStatementList(List<SQLStatement> statementList) {
@@ -3181,7 +3308,7 @@ public class MySqlStatementParser extends SQLStatementParser {
*/
private void parseProcedureStatementList(List<SQLStatement> statementList, int max) {
for (;;) {
for (; ; ) {
if (max != -1) {
if (statementList.size() >= max) {
return;
@@ -3255,7 +3382,7 @@ public class MySqlStatementParser extends SQLStatementParser {
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) variant;
if (binaryOpExpr.getOperator() == SQLBinaryOperator.Assignment) {
SQLSetStatement stmt = new SQLSetStatement(binaryOpExpr.getLeft(), binaryOpExpr.getRight(),
getDbType());
getDbType());
statementList.add(stmt);
continue;
}
@@ -3323,13 +3450,13 @@ public class MySqlStatementParser extends SQLStatementParser {
lexer.reset(markBp, markChar, Token.DECLARE);
statementList.add(this.parseCursorDeclare());
} else if (identifierEquals("HANDLER")) {
//DECLARE异常处理程序 [add by zhujun 2016-04-16]
lexer.reset(markBp, markChar, Token.DECLARE);
statementList.add(this.parseDeclareHandler());
//DECLARE异常处理程序 [add by zhujun 2016-04-16]
lexer.reset(markBp, markChar, Token.DECLARE);
statementList.add(this.parseDeclareHandler());
} else if (lexer.token() == Token.CONDITION) {
//DECLARE异常 [add by zhujun 2016-04-17]
lexer.reset(markBp, markChar, Token.DECLARE);
statementList.add(this.parseDeclareCondition());
//DECLARE异常 [add by zhujun 2016-04-17]
lexer.reset(markBp, markChar, Token.DECLARE);
statementList.add(this.parseDeclareCondition());
} else {
lexer.reset(markBp, markChar, Token.DECLARE);
statementList.add(this.parseDeclare());
@@ -3406,7 +3533,7 @@ public class MySqlStatementParser extends SQLStatementParser {
/**
* parse if statement
*
*
* @return MySqlIfStatement
*/
public SQLIfStatement parseIf() {
@@ -3451,7 +3578,7 @@ public class MySqlStatementParser extends SQLStatementParser {
/**
* parse while statement
*
*
* @return MySqlWhileStatement
*/
public MySqlWhileStatement parseWhile() {
@@ -3476,7 +3603,7 @@ public class MySqlStatementParser extends SQLStatementParser {
/**
* parse while statement with label
*
*
* @return MySqlWhileStatement
*/
public MySqlWhileStatement parseWhile(String label) {
@@ -3506,7 +3633,7 @@ public class MySqlStatementParser extends SQLStatementParser {
/**
* parse case statement
*
*
* @return MySqlCaseStatement
*/
public MySqlCaseStatement parseCase() {
@@ -3574,7 +3701,7 @@ public class MySqlStatementParser extends SQLStatementParser {
MySqlDeclareStatement stmt = new MySqlDeclareStatement();
accept(Token.DECLARE);
// lexer.nextToken();
for (;;) {
for (; ; ) {
SQLDeclareItem item = new SQLDeclareItem();
item.setName(exprParser.name());
@@ -3683,7 +3810,7 @@ public class MySqlStatementParser extends SQLStatementParser {
/**
* parse repeat statement
*
*
* @return
*/
public MySqlRepeatStatement parseRepeat() {
@@ -3700,7 +3827,7 @@ public class MySqlStatementParser extends SQLStatementParser {
/**
* parse repeat statement with label
*
*
* @param label
* @return
*/
@@ -3720,7 +3847,7 @@ public class MySqlStatementParser extends SQLStatementParser {
/**
* parse cursor declare statement
*
*
* @return
*/
public MySqlCursorDeclareStatement parseCursorDeclare() {
@@ -3733,7 +3860,7 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.FOR);
SQLSelectStatement selelctStmt = (SQLSelectStatement)parseSelect();
SQLSelectStatement selelctStmt = (SQLSelectStatement) parseSelect();
stmt.setSelect(selelctStmt);
accept(Token.SEMI);
@@ -3744,10 +3871,11 @@ public class MySqlStatementParser extends SQLStatementParser {
/**
* zhujun [455910092@qq.com]
* parse spstatement
*
* @return
*/
public SQLStatement parseSpStatement() {
// update
if (lexer.token() == (Token.UPDATE)) {
return parseUpdateStatement();
@@ -3793,71 +3921,72 @@ public class MySqlStatementParser extends SQLStatementParser {
throw new ParserException("error sp_statement");
}
/**
* 定义异常处理程序
*
* @return
* @author zhujun [455910092@qq.com]
* 2016-04-16
* @return
*/
public MySqlDeclareHandlerStatement parseDeclareHandler() {
//DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement
//handler_type 取值为 CONTINUE | EXIT | UNDO
//condition_value 取值为 SQLWARNING | NOT FOUND | SQLEXCEPTION | SQLSTATE value(异常码 e.g 1062)
MySqlDeclareHandlerStatement stmt = new MySqlDeclareHandlerStatement();
//DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement
//handler_type 取值为 CONTINUE | EXIT | UNDO
//condition_value 取值为 SQLWARNING | NOT FOUND | SQLEXCEPTION | SQLSTATE value(异常码 e.g 1062)
MySqlDeclareHandlerStatement stmt = new MySqlDeclareHandlerStatement();
accept(Token.DECLARE);
//String handlerType = exprParser.name().getSimpleName();
if(lexer.token() == Token.CONTINUE) {
stmt.setHandleType(MySqlHandlerType.CONTINUE);
} else if(lexer.token() == Token.EXIT) {
stmt.setHandleType(MySqlHandlerType.CONTINUE);
} else if(lexer.token() == Token.UNDO) {
stmt.setHandleType(MySqlHandlerType.CONTINUE);
if (lexer.token() == Token.CONTINUE) {
stmt.setHandleType(MySqlHandlerType.CONTINUE);
} else if (lexer.token() == Token.EXIT) {
stmt.setHandleType(MySqlHandlerType.CONTINUE);
} else if (lexer.token() == Token.UNDO) {
stmt.setHandleType(MySqlHandlerType.CONTINUE);
} else {
throw new ParserException("unkown handle type");
throw new ParserException("unkown handle type");
}
lexer.nextToken();
acceptIdentifier("HANDLER");
accept(Token.FOR);
for (;;) {
String tokenName = lexer.stringVal();
ConditionValue condition = new ConditionValue();
if (tokenName.equalsIgnoreCase("NOT")) {//for 'NOT FOUND'
lexer.nextToken();
acceptIdentifier("HANDLE");
condition.setType(ConditionType.SYSTEM);
condition.setValue("NOT FOUND");
} else if(tokenName.equalsIgnoreCase("SQLSTATE")) { //for SQLSTATE (SQLSTATE '10001')
condition.setType(ConditionType.SQLSTATE);
lexer.nextToken();
//condition.setValue(lexer.stringVal());
//lexer.nextToken();
condition.setValue(exprParser.name().toString());
} else if(identifierEquals("SQLEXCEPTION")) { //for SQLEXCEPTION
condition.setType(ConditionType.SYSTEM);
condition.setValue(lexer.stringVal());
lexer.nextToken();
} else if(identifierEquals("SQLWARNING")) { //for SQLWARNING
condition.setType(ConditionType.SYSTEM);
condition.setValue(lexer.stringVal());
lexer.nextToken();
} else { //for condition_name or mysql_error_code
if (lexer.token() == Token.LITERAL_INT) {
condition.setType(ConditionType.MYSQL_ERROR_CODE);
condition.setValue(lexer.integerValue().toString());
} else {
condition.setType(ConditionType.SELF);
condition.setValue(tokenName);
}
lexer.nextToken();
}
stmt.getConditionValues().add(condition);
for (; ; ) {
String tokenName = lexer.stringVal();
ConditionValue condition = new ConditionValue();
if (tokenName.equalsIgnoreCase("NOT")) {//for 'NOT FOUND'
lexer.nextToken();
acceptIdentifier("HANDLE");
condition.setType(ConditionType.SYSTEM);
condition.setValue("NOT FOUND");
} else if (tokenName.equalsIgnoreCase("SQLSTATE")) { //for SQLSTATE (SQLSTATE '10001')
condition.setType(ConditionType.SQLSTATE);
lexer.nextToken();
//condition.setValue(lexer.stringVal());
//lexer.nextToken();
condition.setValue(exprParser.name().toString());
} else if (identifierEquals("SQLEXCEPTION")) { //for SQLEXCEPTION
condition.setType(ConditionType.SYSTEM);
condition.setValue(lexer.stringVal());
lexer.nextToken();
} else if (identifierEquals("SQLWARNING")) { //for SQLWARNING
condition.setType(ConditionType.SYSTEM);
condition.setValue(lexer.stringVal());
lexer.nextToken();
} else { //for condition_name or mysql_error_code
if (lexer.token() == Token.LITERAL_INT) {
condition.setType(ConditionType.MYSQL_ERROR_CODE);
condition.setValue(lexer.integerValue().toString());
} else {
condition.setType(ConditionType.SELF);
condition.setValue(tokenName);
}
lexer.nextToken();
}
stmt.getConditionValues().add(condition);
if (lexer.token() == Token.COMMA) {
accept(Token.COMMA);
continue;
@@ -3867,58 +3996,59 @@ public class MySqlStatementParser extends SQLStatementParser {
throw new ParserException("declare handle not eof");
}
}
stmt.setSpStatement(parseSpStatement());
if (!(stmt.getSpStatement() instanceof SQLBlockStatement)) {
accept(Token.SEMI);
}
accept(Token.SEMI);
}
return stmt;
}
/**
* zhujun [455910092@qq.com]
* 2016-04-17
* 定义条件
*
* @return
*/
public MySqlDeclareConditionStatement parseDeclareCondition() {
/*
DECLARE condition_name CONDITION FOR condition_value
/*
DECLARE condition_name CONDITION FOR condition_value
condition_value:
SQLSTATE [VALUE] sqlstate_value
| mysql_error_code
*/
MySqlDeclareConditionStatement stmt = new MySqlDeclareConditionStatement();
MySqlDeclareConditionStatement stmt = new MySqlDeclareConditionStatement();
accept(Token.DECLARE);
stmt.setConditionName(exprParser.name().toString());
accept(Token.CONDITION);
accept(Token.FOR);
String tokenName = lexer.stringVal();
ConditionValue condition = new ConditionValue();
if(tokenName.equalsIgnoreCase("SQLSTATE")) { //for SQLSTATE (SQLSTATE '10001')
condition.setType(ConditionType.SQLSTATE);
lexer.nextToken();
condition.setValue(exprParser.name().toString());
} else if (lexer.token() == Token.LITERAL_INT) {
condition.setType(ConditionType.MYSQL_ERROR_CODE);
condition.setValue(lexer.integerValue().toString());
lexer.nextToken();
} else {
throw new ParserException("declare condition grammer error.");
}
if (tokenName.equalsIgnoreCase("SQLSTATE")) { //for SQLSTATE (SQLSTATE '10001')
condition.setType(ConditionType.SQLSTATE);
lexer.nextToken();
condition.setValue(exprParser.name().toString());
} else if (lexer.token() == Token.LITERAL_INT) {
condition.setType(ConditionType.MYSQL_ERROR_CODE);
condition.setValue(lexer.integerValue().toString());
lexer.nextToken();
} else {
throw new ParserException("declare condition grammer error.");
}
stmt.setConditionValue(condition);
accept(Token.SEMI);
return stmt;
return stmt;
}
}
@@ -55,8 +55,8 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExplainStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHelpStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHintStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
@@ -118,7 +118,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTableStatusSta
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTriggersStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowVariantsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatement;
import com.alibaba.druid.sql.ast.statement.SQLStartTransactionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSubPartitionByKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSubPartitionByList;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
@@ -167,9 +166,9 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
boolean visit(MySqlPrepareStatement x);
void endVisit(MySqlExecuteStatement x);
boolean visit(MysqlDeallocatePrepareStatement x);
void endVisit(MysqlDeallocatePrepareStatement x);
boolean visit(MySqlExecuteStatement x);
@@ -258,9 +257,9 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
void endVisit(MySqlOutFileExpr x);
boolean visit(MySqlDescribeStatement x);
boolean visit(MySqlExplainStatement x);
void endVisit(MySqlDescribeStatement x);
void endVisit(MySqlExplainStatement x);
boolean visit(MySqlUpdateStatement x);
@@ -517,74 +516,74 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
boolean visit(MySqlSetPasswordStatement x);
void endVisit(MySqlSetPasswordStatement x);
boolean visit(MySqlHintStatement x);
void endVisit(MySqlHintStatement x);
boolean visit(MySqlOrderingExpr x);
void endVisit(MySqlOrderingExpr x);
/**
* support procedure
*/
/**
* support procedure
*/
boolean visit(MySqlWhileStatement x);
void endVisit(MySqlWhileStatement x);
boolean visit(MySqlCaseStatement x);
void endVisit(MySqlCaseStatement x);
boolean visit(MySqlDeclareStatement x);
void endVisit(MySqlDeclareStatement x);
boolean visit(MySqlSelectIntoStatement x);
void endVisit(MySqlSelectIntoStatement x);
boolean visit(MySqlWhenStatement x);
void endVisit(MySqlWhenStatement 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);
boolean visit(MySqlCursorDeclareStatement x);
void endVisit(MySqlCursorDeclareStatement x);
boolean visit(MySqlUpdateTableSource x);
void endVisit(MySqlUpdateTableSource x);
boolean visit(MySqlAlterTableAlterColumn x);
void endVisit(MySqlAlterTableAlterColumn x);
boolean visit(MySqlSubPartitionByKey x);
void endVisit(MySqlSubPartitionByKey x);
boolean visit(MySqlSubPartitionByList x);
void endVisit(MySqlSubPartitionByList x);
boolean visit(MySqlDeclareHandlerStatement x);
void endVisit(MySqlDeclareHandlerStatement x);
boolean visit(MySqlDeclareConditionStatement x);
void endVisit(MySqlDeclareConditionStatement x);
@@ -15,14 +15,119 @@
*/
package com.alibaba.druid.sql.dialect.mysql.visitor;
import com.alibaba.druid.sql.ast.statement.SQLStartTransactionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.*;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.*;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlForceIndexHint;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlIgnoreIndexHint;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlKey;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlPrimaryKey;
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.MySqlWhenStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.*;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.*;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCursorDeclareStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareConditionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareHandlerStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement;
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.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;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExtractExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlUserName;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.CobarShowStatus;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableAlterColumn;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableChangeColumn;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableCharacter;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableDiscardTablespace;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableImportTablespace;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableModifyColumn;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableOption;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterUserStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAnalyzeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlBinlogStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement.TableSpaceOption;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement.UserSpecification;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExplainStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHelpStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHintStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlOptimizeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPartitionByKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlResetStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetPasswordStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowAuthorsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinLogEventsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowBinaryLogsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCharacterSetStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCollationStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowContributorsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCreateDatabaseStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCreateEventStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCreateFunctionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCreateProcedureStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCreateTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCreateTriggerStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowCreateViewStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowEngineStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowEnginesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowErrorsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowEventsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowFunctionCodeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowFunctionStatusStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowGrantsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowIndexesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowKeysStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowMasterLogsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowMasterStatusStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowOpenTablesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowPluginsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowPrivilegesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureCodeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcedureStatusStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProcessListStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowProfilesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowRelayLogEventsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowSlaveHostsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowSlaveStatusStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatusStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTableStatusStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTriggersStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowVariantsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSubPartitionByKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSubPartitionByList;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateTableSource;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MysqlDeallocatePrepareStatement;
import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter;
public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySqlASTVisitor {
@@ -335,12 +440,12 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq
}
@Override
public boolean visit(MySqlDescribeStatement x) {
public boolean visit(MySqlExplainStatement x) {
return true;
}
@Override
public void endVisit(MySqlDescribeStatement x) {
public void endVisit(MySqlExplainStatement x) {
}
@@ -15,12 +15,6 @@
*/
package com.alibaba.druid.sql.dialect.mysql.visitor;
import java.security.AccessControlException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLExpr;
@@ -30,8 +24,27 @@ import com.alibaba.druid.sql.ast.SQLParameter;
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.SQLSubPartitionBy;
import com.alibaba.druid.sql.ast.expr.*;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddColumn;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableItem;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.ast.statement.SQLBlockStatement;
import com.alibaba.druid.sql.ast.statement.SQLCharacterDataType;
import com.alibaba.druid.sql.ast.statement.SQLColumnConstraint;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateProcedureStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLIfStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLLoopStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLShowTablesStatement;
import com.alibaba.druid.sql.ast.statement.SQLStartTransactionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlForceIndexHint;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlIgnoreIndexHint;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlKey;
@@ -47,6 +60,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlCursorDeclareStatemen
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareConditionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareHandlerStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlDeclareStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlExplainType;
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.MySqlRepeatStatement;
@@ -76,8 +90,8 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStateme
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement.UserSpecification;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExplainStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHelpStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHintStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
@@ -139,7 +153,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTableStatusSta
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTriggersStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowVariantsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatement;
import com.alibaba.druid.sql.ast.statement.SQLStartTransactionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSubPartitionByKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSubPartitionByList;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
@@ -154,6 +167,11 @@ import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.util.JdbcConstants;
import java.security.AccessControlException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTVisitor {
{
@@ -161,11 +179,11 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
this.shardingSupport = true;
}
public MySqlOutputVisitor(Appendable appender){
public MySqlOutputVisitor(Appendable appender) {
super(appender);
}
public MySqlOutputVisitor(Appendable appender, boolean parameterized){
public MySqlOutputVisitor(Appendable appender, boolean parameterized) {
super(appender, parameterized);
try {
@@ -306,7 +324,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
println();
print0(ucase ? "FOR UPDATE" : "for update");
if (x.isNoWait()) {
print0(ucase ? " NO_WAIT" : " no_wait");
print0(ucase ? " NO_WAIT" : " no_wait");
} else if (x.getWaitTime() != null) {
print0(ucase ? " WAIT " : " wait ");
x.getWaitTime().accept(this);
@@ -323,11 +341,11 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
public boolean visit(SQLColumnDefinition x) {
x.getName().accept(this);
SQLDataType dataType = x.getDataType();
if (dataType != null) {
print(' ');
dataType.accept(this);
if (dataType != null) {
print(' ');
dataType.accept(this);
}
if (x.getCharsetExpr() != null) {
@@ -364,15 +382,15 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print0(ucase ? " COMMENT " : " comment ");
x.getComment().accept(this);
}
if (x.getAsExpr() != null) {
print0(ucase ? " AS (" : " as (");
x.getAsExpr().accept(this);
print(')');
}
if (x.isSorted()) {
print0(ucase ? " SORTED" : " sorted");
print0(ucase ? " SORTED" : " sorted");
}
return false;
@@ -535,7 +553,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
println();
x.getPartitioning().accept(this);
}
if (x.getTableGroup() != null) {
println();
print0(ucase ? "TABLEGROUP " : "tablegroup ");
@@ -648,7 +666,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print('\'');
String text = x.getText();
StringBuilder buf = new StringBuilder(text.length());
for (int i = 0; i < text.length(); ++i) {
char ch = text.charAt(i);
@@ -691,16 +709,16 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print0("@@global.");
} else {
if ((!varName.startsWith("@")) // /
&& (!varName.equals("?")) //
&& (!varName.startsWith("#")) //
&& (!varName.startsWith("$")) //
&& (!varName.startsWith(":"))) {
&& (!varName.equals("?")) //
&& (!varName.startsWith("#")) //
&& (!varName.startsWith("$")) //
&& (!varName.startsWith(":"))) {
boolean subPartitionOption = false;
if (x.getParent() != null) {
subPartitionOption = x.getParent().getParent() instanceof SQLSubPartitionBy;
}
if (!subPartitionOption) {
print0("@@");
}
@@ -887,16 +905,16 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
return false;
}
@Override
public void endVisit(MysqlDeallocatePrepareStatement x) {
public void endVisit(MysqlDeallocatePrepareStatement x) {
}
public boolean visit(MysqlDeallocatePrepareStatement x) {
print0(ucase ? "DEALLOCATE PREPARE " : "deallocate prepare ");
x.getStatementName().accept(this);
return false;
print0(ucase ? "DEALLOCATE PREPARE " : "deallocate prepare ");
x.getStatementName().accept(this);
return false;
}
@Override
@@ -907,7 +925,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
@Override
public boolean visit(MySqlDeleteStatement x) {
print0(ucase ? "DELETE " : "delete ");
for (int i = 0, size = x.getHintsSize(); i < size; ++i) {
SQLCommentHint hint = x.getHints().get(i);
hint.accept(this);
@@ -988,7 +1006,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
if (x.isIgnore()) {
print0(ucase ? "IGNORE " : "ignore ");
}
if (x.isRollbackOnFail()) {
print0(ucase ? "ROLLBACK_ON_FAIL " : "rollback_on_fail ");
}
@@ -1522,7 +1540,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
} else {
print0(ucase ? "KILL " : "kill ");
}
printAndAccept(x.getThreadIds(), ", ");
return false;
}
@@ -1612,8 +1630,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
//
@Override
@@ -1674,18 +1690,47 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
@Override
public boolean visit(MySqlDescribeStatement x) {
print0(ucase ? "DESC " : "desc ");
x.getObject().accept(this);
if (x.getColName() != null) {
print(' ');
x.getColName().accept(this);
public boolean visit(MySqlExplainStatement x) {
String name = x.isDescribe() ? "desc" : "explain";
print0(ucase ? name.toUpperCase() : name);
print(' ');
// tbl_name [col_name | wild]
if (x.getTableName() != null) {
x.getTableName().accept(this);
if (x.getColumnName() != null) {
print(' ');
x.getColumnName().accept(this);
} else if (x.getWild() != null) {
print(' ');
x.getWild().accept(this);
}
} else {
// [explain_type]
if (x.getType() != null) {
print0(ucase ? x.getType().name() : x.getType().name().toLowerCase());
print(' ');
if (x.getType() == MySqlExplainType.FORMAT) {
print0("= ");
print(ucase ? x.getFormatName().name() : x.getFormatName().name().toLowerCase());
print(' ');
}
}
// {explainable_stmt | FOR CONNECTION connection_id}
if (x.getConnectionId() != null) {
print0(ucase ? "FOR CONNECTION " : "for connection ");
x.getConnectionId().accept(this);
} else {
x.getStatement().accept(this);
}
}
return false;
}
@Override
public void endVisit(MySqlDescribeStatement x) {
public void endVisit(MySqlExplainStatement x) {
}
@@ -1697,7 +1742,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
println();
print0(ucase ? "FROM " : "from ");
}
print0(ucase ? "UPDATE " : "update ");
if (x.isLowPriority()) {
@@ -1707,19 +1752,19 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
if (x.isIgnore()) {
print0(ucase ? "IGNORE " : "ignore ");
}
if (x.isCommitOnSuccess()) {
print0(ucase ? "COMMIT_ON_SUCCESS " : "commit_on_success ");
}
if (x.isRollBackOnFail()) {
print0(ucase ? "ROLLBACK_ON_FAIL " : "rollback_on_fail ");
}
if (x.isQueryOnPk()) {
print0(ucase ? "QUEUE_ON_PK " : "queue_on_pk ");
}
if (x.getTargetAffectRow() != null) {
print0(ucase ? "TARGET_AFFECT_ROW " : "target_affect_row ");
x.getTargetAffectRow().accept(this);
@@ -2503,23 +2548,23 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
println();
item.accept(this);
}
if (x.isRemovePatiting()) {
println();
print0(ucase ? "REMOVE PARTITIONING" : "remove partitioning");
}
if (x.isUpgradePatiting()) {
println();
print0(ucase ? "UPGRADE PARTITIONING" : "upgrade partitioning");
}
if (x.getTableOptions().size() > 0) {
println();
}
decrementIndent();
int i = 0;
for (Map.Entry<String, SQLObject> option : x.getTableOptions().entrySet()) {
String key = option.getKey();
@@ -2544,7 +2589,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
option.getValue().accept(this);
i++;
}
return false;
}
@@ -2706,7 +2751,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print(' ');
x.getHints().get(i).accept(this);
}
if (x.getPartitionSize() > 0) {
print0(ucase ? " PARTITION (" : " partition (");
printlnAndAccept(x.getPartitions(), ", ");
@@ -2949,7 +2994,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print0(ucase ? " ON DELETE " : " on delete ");
print0(ucase ? x.getOnDelete().name : x.getOnDelete().name_lcase);
}
if (x.getOnDelete() != null) {
print0(ucase ? " ON UPDATE " : " on update ");
print0(ucase ? x.getOnDelete().name : x.getOnDelete().name_lcase);
@@ -3537,7 +3582,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
printAndAccept(x.getColumns(), ", ");
print(")");
}
if (x.getOptions().size() != 0) {
println();
print0(ucase ? "SUBPARTITION OPTIONS (" : "subpartition options (");
@@ -3554,58 +3599,58 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
@Override
public boolean visit(MySqlDeclareHandlerStatement x) {
print0(ucase ? "DECLARE " : "declare ");
@Override
public boolean visit(MySqlDeclareHandlerStatement x) {
print0(ucase ? "DECLARE " : "declare ");
print0(ucase ? x.getHandleType().toString().toUpperCase() : x.getHandleType().toString().toLowerCase());
print0(ucase ? " HANDLER FOR " : " handler for ");
for (int i = 0; i < x.getConditionValues().size(); i++) {
ConditionValue cv = x.getConditionValues().get(i);
if (cv.getType() == ConditionType.SQLSTATE) {
print0(ucase ? " SQLSTATE " : " sqlstate ");
print0(cv.getValue());
} else if (cv.getType() == ConditionType.MYSQL_ERROR_CODE) {
print0(cv.getValue());
} else if (cv.getType() == ConditionType.SELF) {
print0(cv.getValue());
} else if (cv.getType() == ConditionType.SYSTEM){
print0(ucase ? cv.getValue().toUpperCase() : cv.getValue().toLowerCase());
}
if (i != x.getConditionValues().size() - 1) {
print0(", ");
}
}
ConditionValue cv = x.getConditionValues().get(i);
if (cv.getType() == ConditionType.SQLSTATE) {
print0(ucase ? " SQLSTATE " : " sqlstate ");
print0(cv.getValue());
} else if (cv.getType() == ConditionType.MYSQL_ERROR_CODE) {
print0(cv.getValue());
} else if (cv.getType() == ConditionType.SELF) {
print0(cv.getValue());
} else if (cv.getType() == ConditionType.SYSTEM) {
print0(ucase ? cv.getValue().toUpperCase() : cv.getValue().toLowerCase());
}
if (i != x.getConditionValues().size() - 1) {
print0(", ");
}
}
println();
return true;
}
}
@Override
public void endVisit(MySqlDeclareHandlerStatement x) {
}
@Override
public void endVisit(MySqlDeclareHandlerStatement x) {
@Override
public boolean visit(MySqlDeclareConditionStatement x) {
print0(ucase ? "DECLARE " : "declare ");
}
@Override
public boolean visit(MySqlDeclareConditionStatement x) {
print0(ucase ? "DECLARE " : "declare ");
print0(x.getConditionName());
print0(ucase ? " CONDITION FOR " : " condition for ");
if (x.getConditionValue().getType() == ConditionType.SQLSTATE) {
print0(ucase ? "SQLSTATE " : "sqlstate ");
print0(x.getConditionValue().getValue());
} else {
print0(x.getConditionValue().getValue());
}
println();
return false;
}
@Override
public void endVisit(MySqlDeclareConditionStatement x) {
}
if (x.getConditionValue().getType() == ConditionType.SQLSTATE) {
print0(ucase ? "SQLSTATE " : "sqlstate ");
print0(x.getConditionValue().getValue());
} else {
print0(x.getConditionValue().getValue());
}
println();
return false;
}
@Override
public void endVisit(MySqlDeclareConditionStatement x) {
}
} //
@@ -15,8 +15,6 @@
*/
package com.alibaba.druid.sql.dialect.mysql.visitor;
import java.util.Map;
import com.alibaba.druid.sql.ast.SQLDeclareItem;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
@@ -28,6 +26,7 @@ import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLStartTransactionStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
@@ -73,8 +72,8 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStateme
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement.UserSpecification;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExplainStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHelpStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHintStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
@@ -136,7 +135,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTableStatusSta
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTriggersStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowVariantsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatement;
import com.alibaba.druid.sql.ast.statement.SQLStartTransactionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSubPartitionByKey;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSubPartitionByList;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
@@ -150,6 +148,8 @@ import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.stat.TableStat.Mode;
import com.alibaba.druid.util.JdbcUtils;
import java.util.Map;
public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlASTVisitor {
public boolean visit(SQLSelectStatement x) {
@@ -566,17 +566,24 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
}
@Override
public boolean visit(MySqlDescribeStatement x) {
String table = x.getObject().toString();
getTableStat(table);
if (x.getColName() != null) {
addColumn(table, x.getColName().toString());
public boolean visit(MySqlExplainStatement x) {
if (x.getTableName() != null) {
String table = x.getTableName().toString();
getTableStat(table);
if (x.getColumnName() != null) {
addColumn(table, x.getColumnName().toString());
}
}
if (x.getStatement() != null) {
accept(x.getStatement());
}
return false;
}
@Override
public void endVisit(MySqlDescribeStatement x) {
public void endVisit(MySqlExplainStatement x) {
}
@@ -126,7 +126,7 @@ public enum Token {
BINARY("BINARY"),
SHOW("SHOW"),
REPLACE("REPLACE"),
// MySql procedure add by zz
WHILE("WHILE"),
DO("DO"),
@@ -15,23 +15,10 @@
*/
package com.alibaba.druid.wall.spi;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLLimit;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLOrderBy;
@@ -61,24 +48,59 @@ import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
import com.alibaba.druid.sql.ast.expr.SQLValuableExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLBlockStatement;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateSequenceStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropIndexStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropProcedureStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropSequenceStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTriggerStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement;
import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLShowTablesStatement;
import com.alibaba.druid.sql.ast.statement.SQLStartTransactionStatement;
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUnionOperator;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUseStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExplainStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHintStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement;
import com.alibaba.druid.sql.ast.SQLLimit;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowGrantsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatement;
import com.alibaba.druid.sql.ast.statement.SQLStartTransactionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
@@ -107,6 +129,20 @@ import com.alibaba.druid.wall.WallVisitor;
import com.alibaba.druid.wall.violation.ErrorCode;
import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
public class WallVisitorUtils {
private final static Log LOG = LogFactory.getLog(WallVisitorUtils.class);
@@ -2467,7 +2503,7 @@ public class WallVisitorUtils {
allow = config.isReplaceAllow();
denyMessage = "replace not allow";
errorCode = ErrorCode.REPLACE_NOT_ALLOW;
} else if (x instanceof MySqlDescribeStatement) {
} else if (x instanceof MySqlExplainStatement && ((MySqlExplainStatement)x).isDescribe()) {
allow = config.isDescribeAllow();
denyMessage = "describe not allow";
errorCode = ErrorCode.DESC_NOT_ALLOW;