From 99337c1ffb5712eeacc70228c466cbe6b681a197 Mon Sep 17 00:00:00 2001 From: wenshao Date: Sat, 25 Mar 2017 20:10:44 +0800 Subject: [PATCH] refactor sql parser about the desc and explain parts of the code --- .../ast/statement/SQLDescribeStatement.java | 45 ++++++++++++- .../ast/statement/MySqlExplainStatement.java | 20 ++---- .../mysql/parser/MySqlStatementParser.java | 62 ++++++++--------- .../mysql/visitor/MySqlOutputVisitor.java | 9 +-- .../sql/dialect/odps/ast/OdpsDescStmt.java | 66 ------------------- .../odps/parser/OdpsStatementParser.java | 41 +----------- .../dialect/odps/visitor/OdpsASTVisitor.java | 4 -- .../odps/visitor/OdpsASTVisitorAdapter.java | 10 --- .../odps/visitor/OdpsOutputVisitor.java | 25 ------- .../odps/visitor/OdpsSchemaStatVisitor.java | 10 --- .../druid/sql/parser/SQLStatementParser.java | 44 +++++++++++++ .../sql/visitor/SQLASTOutputVisitor.java | 19 ++++++ .../druid/sql/visitor/SQLASTVisitor.java | 3 + .../sql/visitor/SQLASTVisitorAdapter.java | 11 +++- .../druid/sql/visitor/SchemaStatVisitor.java | 25 +++++++ .../druid/wall/spi/WallVisitorUtils.java | 42 +----------- .../com/alibaba/druid/bvt/bug/Issue1645.java | 3 +- .../druid/bvt/sql/cobar/DALParserTest.java | 5 +- 18 files changed, 191 insertions(+), 253 deletions(-) delete mode 100644 src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsDescStmt.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDescribeStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDescribeStatement.java index 604938964d..9c0e278b1e 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDescribeStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDescribeStatement.java @@ -15,14 +15,24 @@ */ package com.alibaba.druid.sql.ast.statement; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLStatementImpl; import com.alibaba.druid.sql.visitor.SQLASTVisitor; +import java.util.ArrayList; +import java.util.List; + public class SQLDescribeStatement extends SQLStatementImpl { protected SQLName object; + protected SQLName column; + + // for odps + protected SQLObjectType objectType; + protected List partition = new ArrayList(); + public SQLName getObject() { return object; } @@ -30,9 +40,40 @@ public class SQLDescribeStatement extends SQLStatementImpl { public void setObject(SQLName object) { this.object = object; } - + + public SQLName getColumn() { + return column; + } + + public void setColumn(SQLName column) { + if (column != null) { + column.setParent(this); + } + this.column = column; + } + + public List getPartition() { + return partition; + } + + public void setPartition(List partition) { + this.partition = partition; + } + + public SQLObjectType getObjectType() { + return objectType; + } + + public void setObjectType(SQLObjectType objectType) { + this.objectType = objectType; + } + @Override protected void accept0(SQLASTVisitor visitor) { - throw new UnsupportedOperationException(this.getClass().getName()); + if (visitor.visit(this)) { + acceptChild(visitor, object); + acceptChild(visitor, column); + } + visitor.endVisit(this); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlExplainStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlExplainStatement.java index 9f01794528..a1e1059990 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlExplainStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlExplainStatement.java @@ -33,9 +33,7 @@ public class MySqlExplainStatement extends SQLExplainStatement implements MySqlS private SQLName columnName; private SQLExpr wild; - private MySqlExplainType type; - - private MySqlFormatName formatName; + private String format; private SQLExpr connectionId; @@ -106,20 +104,12 @@ public class MySqlExplainStatement extends SQLExplainStatement implements MySqlS this.wild = wild; } - public MySqlExplainType getType() { - return type; + public String getFormat() { + return format; } - public void setType(MySqlExplainType type) { - this.type = type; - } - - public MySqlFormatName getFormatName() { - return formatName; - } - - public void setFormatName(MySqlFormatName formatName) { - this.formatName = formatName; + public void setFormat(String format) { + this.format = format; } public SQLExpr getConnectionId() { 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 98ba833318..3c2b7e3052 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 @@ -654,7 +654,7 @@ public class MySqlStatementParser extends SQLStatementParser { } if (lexer.token() == Token.EXPLAIN) { - MySqlExplainStatement stmt = this.parseExplain(); + SQLStatement stmt = this.parseExplain(); statementList.add(stmt); return true; } @@ -829,44 +829,40 @@ public class MySqlStatementParser extends SQLStatementParser { private MySqlExplainStatement parseExplain(MySqlExplainStatement explain) { + + if (lexer.token() == Token.HINT) { + List hints = this.exprParser.parseHints(); + explain.setHints(hints); + } // 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; + boolean table = false; + if (lexer.token() == Token.IDENTIFIER) { + String stringVal = lexer.stringVal(); - // 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); - } - } + if (stringVal.equalsIgnoreCase(EXTENDED) + || stringVal.equalsIgnoreCase(PARTITIONS)) { + explain.setType(stringVal); + lexer.nextToken(); + } else if (stringVal.equalsIgnoreCase(FORMAT)) { + explain.setType(stringVal); + lexer.nextToken(); + accept(Token.EQ); - lexer.nextToken(); + String format = lexer.stringVal(); + explain.setFormat(format); + accept(Token.IDENTIFIER); + } else { + explain.setTableName(exprParser.name()); + if (lexer.token() == Token.IDENTIFIER) { + explain.setColumnName(exprParser.name()); + } else if (lexer.token() == Token.LITERAL_CHARS) { + explain.setWild(exprParser.expr()); + } + table = true; + } } - // {explainable_stmt | FOR CONNECTION connection_id} if (lexer.token() == Token.FOR) { lexer.nextToken(); acceptIdentifier(CONNECTION); 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 c4a393120e..1990ed7022 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 @@ -1723,12 +1723,13 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV } } else { // [explain_type] - if (x.getType() != null) { - print0(ucase ? x.getType().name() : x.getType().name().toLowerCase()); + String type = x.getType(); + if (type != null) { + print0(type); print(' '); - if (x.getType() == MySqlExplainType.FORMAT) { + if ("format".equalsIgnoreCase(type)) { print0("= "); - print(ucase ? x.getFormatName().name() : x.getFormatName().name().toLowerCase()); + print0(x.getFormat()); print(' '); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsDescStmt.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsDescStmt.java deleted file mode 100644 index 378bcd2b3a..0000000000 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsDescStmt.java +++ /dev/null @@ -1,66 +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.odps.ast; - -import java.util.ArrayList; -import java.util.List; - -import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.ast.statement.SQLDescribeStatement; -import com.alibaba.druid.sql.ast.statement.SQLObjectType; -import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor; -import com.alibaba.druid.sql.visitor.SQLASTVisitor; -import com.alibaba.druid.util.JdbcConstants; - -public class OdpsDescStmt extends SQLDescribeStatement { - - private SQLObjectType objectType; - - private List partition = new ArrayList(); - - public OdpsDescStmt() { - this.setDbType(JdbcConstants.ODPS); - } - - @Override - protected void accept0(SQLASTVisitor visitor) { - accept0((OdpsASTVisitor) visitor); - } - - protected void accept0(OdpsASTVisitor visitor) { - if (visitor.visit(this)) { - acceptChild(visitor, object); - } - visitor.endVisit(this); - } - - public SQLObjectType getObjectType() { - return objectType; - } - - public void setObjectType(SQLObjectType objectType) { - this.objectType = objectType; - } - - public List getPartition() { - return partition; - } - - public void setPartition(List partition) { - this.partition = partition; - } - -} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java index 8194a3938d..91f80e24ab 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java @@ -33,7 +33,6 @@ import com.alibaba.druid.sql.ast.statement.SQLShowTablesStatement; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.dialect.odps.ast.OdpsAddStatisticStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsDescStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsGrantStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement; @@ -179,7 +178,7 @@ public class OdpsStatementParser extends SQLStatementParser { } if (lexer.token() == Token.DESC || identifierEquals("DESCRIBE")) { - OdpsDescStmt stmt = parseDescribe(); + SQLStatement stmt = parseDescribe(); statementList.add(stmt); return true; } @@ -589,42 +588,4 @@ public class OdpsStatementParser extends SQLStatementParser { break; } } - - public OdpsDescStmt parseDescribe() { - if (lexer.token() == Token.DESC || identifierEquals("DESCRIBE")) { - lexer.nextToken(); - } else { - throw new ParserException("expect DESC, actual " + lexer.token()); - } - - OdpsDescStmt stmt = new OdpsDescStmt(); - if (identifierEquals("ROLE")) { - lexer.nextToken(); - stmt.setObjectType(SQLObjectType.ROLE); - } else if (identifierEquals("PACKAGE")) { - lexer.nextToken(); - stmt.setObjectType(SQLObjectType.PACKAGE); - } else if (identifierEquals("INSTANCE")) { - lexer.nextToken(); - stmt.setObjectType(SQLObjectType.INSTANCE); - } - stmt.setObject(this.exprParser.name()); - - if (lexer.token() == Token.PARTITION) { - lexer.nextToken(); - this.accept(Token.LPAREN); - for (;;) { - stmt.getPartition().add(this.exprParser.expr()); - if (lexer.token() == Token.COMMA) { - lexer.nextToken(); - continue; - } - if (lexer.token() == Token.RPAREN) { - lexer.nextToken(); - break; - } - } - } - return stmt; - } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java index c1c0b9e36f..cad5ba40d5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java @@ -104,10 +104,6 @@ public interface OdpsASTVisitor extends SQLASTVisitor { boolean visit(OdpsGrantStmt x); - void endVisit(OdpsDescStmt x); - - boolean visit(OdpsDescStmt x); - void endVisit(OdpsLateralViewTableSource x); boolean visit(OdpsLateralViewTableSource x); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java index f0b9c65f7a..0696861131 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java @@ -231,16 +231,6 @@ public class OdpsASTVisitorAdapter extends SQLASTVisitorAdapter implements OdpsA return true; } - @Override - public void endVisit(OdpsDescStmt x) { - - } - - @Override - public boolean visit(OdpsDescStmt x) { - return true; - } - @Override public void endVisit(OdpsLateralViewTableSource x) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java index ce60bd424c..5eeae0bf11 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java @@ -815,31 +815,6 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis return false; } - @Override - public void endVisit(OdpsDescStmt x) { - - } - - @Override - public boolean visit(OdpsDescStmt x) { - print0(ucase ? "DESC " : "desc "); - if (x.getObjectType() != null) { - print0(x.getObjectType().name()); - print(' '); - } - - if(x.getObject() != null) { - x.getObject().accept(this); - } - - if (x.getPartition().size() > 0) { - print0(ucase ? " PARTITION (" : " partition ("); - printAndAccept(x.getPartition(), ", "); - print(')'); - } - return false; - } - @Override public void endVisit(OdpsLateralViewTableSource x) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java index e31c109c24..deb642f6da 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java @@ -264,16 +264,6 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV return super.visit((SQLGrantStatement) x); } - @Override - public void endVisit(OdpsDescStmt x) { - - } - - @Override - public boolean visit(OdpsDescStmt x) { - return true; - } - @Override public void endVisit(OdpsLateralViewTableSource x) { diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index 499464e636..980758287c 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -2352,4 +2352,48 @@ public class SQLStatementParser extends SQLParser { public void parseHints(List hints) { this.getExprParser().parseHints(hints); } + + public SQLStatement parseDescribe() { + if (lexer.token() == Token.DESC || identifierEquals("DESCRIBE")) { + lexer.nextToken(); + } else { + throw new ParserException("expect DESC, actual " + lexer.token()); + } + + SQLDescribeStatement stmt = new SQLDescribeStatement(); + stmt.setDbType(dbType); + + if (identifierEquals("ROLE")) { + lexer.nextToken(); + stmt.setObjectType(SQLObjectType.ROLE); + } else if (identifierEquals("PACKAGE")) { + lexer.nextToken(); + stmt.setObjectType(SQLObjectType.PACKAGE); + } else if (identifierEquals("INSTANCE")) { + lexer.nextToken(); + stmt.setObjectType(SQLObjectType.INSTANCE); + } + stmt.setObject(this.exprParser.name()); + + Token token = lexer.token(); + if (token == Token.PARTITION) { + lexer.nextToken(); + this.accept(Token.LPAREN); + for (;;) { + stmt.getPartition().add(this.exprParser.expr()); + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + if (lexer.token() == Token.RPAREN) { + lexer.nextToken(); + break; + } + } + } else if (token == Token.IDENTIFIER) { + SQLName column = this.exprParser.name(); + stmt.setColumn(column); + } + return stmt; + } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 61e1a921e3..222a4c3817 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -3929,4 +3929,23 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet return false; } + + public boolean visit(SQLDescribeStatement x) { + print0(ucase ? "DESC " : "desc "); + if (x.getObjectType() != null) { + print0(x.getObjectType().name()); + print(' '); + } + + if(x.getObject() != null) { + x.getObject().accept(this); + } + + if (x.getPartition().size() > 0) { + print0(ucase ? " PARTITION (" : " partition ("); + printAndAccept(x.getPartition(), ", "); + print(')'); + } + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java index b12c2aaba8..6485b63b38 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitor.java @@ -685,4 +685,7 @@ public interface SQLASTVisitor { void endVisit(SQLStartTransactionStatement x); boolean visit(SQLStartTransactionStatement x); + + void endVisit(SQLDescribeStatement x); + boolean visit(SQLDescribeStatement x); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java index d2dfc6271a..735703fc19 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTVisitorAdapter.java @@ -1555,7 +1555,6 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { } - @Override public void endVisit(SQLStartTransactionStatement x) { @@ -1565,4 +1564,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor { public boolean visit(SQLStartTransactionStatement x) { return true; } + + @Override + public void endVisit(SQLDescribeStatement x) { + + } + + @Override + public boolean visit(SQLDescribeStatement x) { + return true; + } } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index bd664b5fbe..4eb0b49079 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -53,6 +53,7 @@ import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.expr.SQLSequenceExpr; import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExpr; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExplainStatement; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter; import com.alibaba.druid.sql.dialect.odps.ast.OdpsValuesTableSource; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExpr; @@ -1941,5 +1942,29 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { tableStat.incrementDropIndexCount(); return false; } + + @Override + public boolean visit(SQLDescribeStatement x) { + String tableName = x.getObject().toString(); + + TableStat tableStat = this.getTableStat(tableName); + tableStat.incrementDropIndexCount(); + + SQLName column = x.getColumn(); + if (column != null) { + String columnName = column.toString(); + this.addColumn(tableName, columnName); + } + return false; + } + + public boolean visit(SQLExplainStatement x) { + if (x.getStatement() != null) { + accept(x.getStatement()); + } + + return false; + } + // // } diff --git a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java index fe5bd61153..c8efd63b94 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -48,45 +48,8 @@ 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.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.*; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause; -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; @@ -2503,7 +2466,8 @@ public class WallVisitorUtils { allow = config.isReplaceAllow(); denyMessage = "replace not allow"; errorCode = ErrorCode.REPLACE_NOT_ALLOW; - } else if (x instanceof MySqlExplainStatement && ((MySqlExplainStatement)x).isDescribe()) { + } else if (x instanceof SQLDescribeStatement + || (x instanceof MySqlExplainStatement && ((MySqlExplainStatement)x).isDescribe())) { allow = config.isDescribeAllow(); denyMessage = "describe not allow"; errorCode = ErrorCode.DESC_NOT_ALLOW; diff --git a/src/test/java/com/alibaba/druid/bvt/bug/Issue1645.java b/src/test/java/com/alibaba/druid/bvt/bug/Issue1645.java index 642528297b..d463c8039e 100644 --- a/src/test/java/com/alibaba/druid/bvt/bug/Issue1645.java +++ b/src/test/java/com/alibaba/druid/bvt/bug/Issue1645.java @@ -11,8 +11,7 @@ public class Issue1645 extends TestCase { public void test_for_issue() throws Exception { String sql = "explain extended select * from foo"; String formatedSql = SQLUtils.format(sql, JdbcConstants.MYSQL); - assertEquals("EXPLAIN extended\n" + - "SELECT *\n" + + assertEquals("EXPLAIN extended SELECT *\n" + "FROM foo", formatedSql); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java b/src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java index d743e5b74a..b0eb1d82f0 100755 --- a/src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java @@ -18,6 +18,7 @@ */ package com.alibaba.druid.bvt.sql.cobar; +import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExplainStatement; import junit.framework.TestCase; @@ -81,7 +82,7 @@ public class DALParserTest extends TestCase { public void testdesc() throws Exception { String sql = "desc tb1"; MySqlStatementParser parser = new MySqlStatementParser(sql); - MySqlExplainStatement desc = parser.parseDescribe(); + SQLStatement desc = parser.parseDescribe(); parser.match(Token.EOF); String output = SQLUtils.toMySqlString(desc); Assert.assertEquals("DESC tb1", output); @@ -90,7 +91,7 @@ public class DALParserTest extends TestCase { public void testdesc_1() throws Exception { String sql = "desc db.tb1"; MySqlStatementParser parser = new MySqlStatementParser(sql); - MySqlExplainStatement desc = parser.parseDescribe(); + SQLStatement desc = parser.parseDescribe(); parser.match(Token.EOF); String output = SQLUtils.toMySqlString(desc); Assert.assertEquals("DESC db.tb1", output);