mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve sql parser
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
package com.alibaba.druid.sql.ast.statement;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLExplainStatement extends SQLStatementImpl {
|
||||
|
||||
protected SQLStatement statement;
|
||||
|
||||
public SQLStatement getStatement() {
|
||||
return statement;
|
||||
}
|
||||
|
||||
public void setStatement(SQLStatement statement) {
|
||||
if (statement != null) {
|
||||
statement.setParent(this);
|
||||
}
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, statement);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,6 @@ import com.alibaba.druid.sql.ast.statement.SQLCharactorDataType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnConstraint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropUserStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlForceIndexHint;
|
||||
|
||||
+15
-14
@@ -15,27 +15,36 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExplainStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OracleExplainStatement extends OracleStatementImpl {
|
||||
public class OracleExplainStatement extends SQLExplainStatement implements OracleStatement {
|
||||
|
||||
private SQLCharExpr statementId;
|
||||
private SQLExpr into;
|
||||
private SQLStatement forStatement;
|
||||
private SQLCharExpr statementId;
|
||||
private SQLExpr into;
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, statementId);
|
||||
acceptChild(visitor, into);
|
||||
acceptChild(visitor, forStatement);
|
||||
acceptChild(visitor, statement);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
accept0((OracleASTVisitor) visitor);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return SQLUtils.toOracleString(this);
|
||||
}
|
||||
|
||||
public SQLCharExpr getStatementId() {
|
||||
return statementId;
|
||||
}
|
||||
@@ -52,12 +61,4 @@ public class OracleExplainStatement extends OracleStatementImpl {
|
||||
this.into = into;
|
||||
}
|
||||
|
||||
public SQLStatement getForStatement() {
|
||||
return forStatement;
|
||||
}
|
||||
|
||||
public void setForStatement(SQLStatement forStatement) {
|
||||
this.forStatement = forStatement;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-21
@@ -140,11 +140,6 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseStatementList(List<SQLStatement> statementList) {
|
||||
parseStatementList(statementList, -1);
|
||||
}
|
||||
|
||||
public void parseStatementList(List<SQLStatement> statementList, int max) {
|
||||
for (;;) {
|
||||
if (max != -1) {
|
||||
@@ -298,12 +293,12 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.IDENTIFIER) {
|
||||
if (identifierEquals("EXPLAIN")) {
|
||||
statementList.add(this.parseExplain());
|
||||
continue;
|
||||
}
|
||||
if (lexer.token() == Token.EXPLAIN) {
|
||||
statementList.add(this.parseExplain());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.IDENTIFIER) {
|
||||
SQLExpr expr = exprParser.expr();
|
||||
OracleExprStatement stmt = new OracleExprStatement(expr);
|
||||
statementList.add(stmt);
|
||||
@@ -470,7 +465,7 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
statementList.add(stmt);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (lexer.token() == Token.TRIGGER) {
|
||||
SQLDropTriggerStatement stmt = parseDropTrigger(false);
|
||||
statementList.add(stmt);
|
||||
@@ -1453,16 +1448,8 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
return clause;
|
||||
}
|
||||
|
||||
public SQLStatement parseStatement() {
|
||||
List<SQLStatement> list = new ArrayList<SQLStatement>();
|
||||
|
||||
this.parseStatementList(list, 1);
|
||||
|
||||
return list.get(0);
|
||||
}
|
||||
|
||||
public OracleExplainStatement parseExplain() {
|
||||
acceptIdentifier("EXPLAIN");
|
||||
accept(Token.EXPLAIN);
|
||||
acceptIdentifier("PLAN");
|
||||
OracleExplainStatement stmt = new OracleExplainStatement();
|
||||
|
||||
@@ -1479,7 +1466,7 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
}
|
||||
|
||||
accept(Token.FOR);
|
||||
stmt.setForStatement(parseStatement());
|
||||
stmt.setStatement(parseStatement());
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@@ -1882,7 +1882,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
|
||||
print("FRO");
|
||||
println();
|
||||
x.getForStatement().accept(this);
|
||||
x.getStatement().accept(this);
|
||||
|
||||
decrementIndent();
|
||||
return false;
|
||||
|
||||
@@ -58,6 +58,7 @@ public class Keywords {
|
||||
map.put("DISTINCT", Token.DISTINCT);
|
||||
map.put("DROP", Token.DROP);
|
||||
map.put("ELSE", Token.ELSE);
|
||||
map.put("EXPLAIN", Token.EXPLAIN);
|
||||
|
||||
map.put("END", Token.END);
|
||||
map.put("ESCAPE", Token.ESCAPE);
|
||||
|
||||
@@ -245,6 +245,7 @@ public class SQLExprParser extends SQLParser {
|
||||
case INITIALLY:
|
||||
case SEQUENCE:
|
||||
case USER:
|
||||
case EXPLAIN:
|
||||
sqlExpr = new SQLIdentifierExpr(lexer.stringVal());
|
||||
lexer.nextToken();
|
||||
break;
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropTriggerStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropUserStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExplainStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
@@ -89,7 +90,17 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
|
||||
public void parseStatementList(List<SQLStatement> statementList) {
|
||||
parseStatementList(statementList, -1);
|
||||
}
|
||||
|
||||
public void parseStatementList(List<SQLStatement> statementList, int max) {
|
||||
for (;;) {
|
||||
if (max != -1) {
|
||||
if (statementList.size() >= max) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.EOF) {
|
||||
return;
|
||||
}
|
||||
@@ -125,6 +136,11 @@ public class SQLStatementParser extends SQLParser {
|
||||
statementList.add(parseDeleteStatement());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.token() == (Token.EXPLAIN)) {
|
||||
statementList.add(parseExplain());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.SET) {
|
||||
statementList.add(parseSet());
|
||||
@@ -587,7 +603,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
stmt.setCascade(Boolean.FALSE);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1000,4 +1016,28 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public SQLStatement parseStatement() {
|
||||
List<SQLStatement> list = new ArrayList<SQLStatement>();
|
||||
|
||||
this.parseStatementList(list, 1);
|
||||
|
||||
return list.get(0);
|
||||
}
|
||||
|
||||
public SQLExplainStatement parseExplain() {
|
||||
accept(Token.EXPLAIN);
|
||||
if (identifierEquals("PLAN")) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.FOR) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
SQLExplainStatement explain = new SQLExplainStatement();
|
||||
explain.setStatement(parseStatement());
|
||||
|
||||
return explain;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ package com.alibaba.druid.sql.parser;
|
||||
* @formatter:off
|
||||
*/
|
||||
public enum Token {
|
||||
EXPLAIN("EXPLAIN"),
|
||||
FOR("FOR"),
|
||||
IF("IF"),
|
||||
INDEX("INDEX"),
|
||||
|
||||
@@ -101,6 +101,7 @@ import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropTriggerStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropUserStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExplainStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprHint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyConstraint;
|
||||
@@ -1705,4 +1706,12 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
printAndAccept(x.getUsers(), ", ");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExplainStatement x) {
|
||||
print("EXPLAIN");
|
||||
println();
|
||||
x.getStatement().accept(this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropTriggerStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropUserStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExplainStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprHint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl;
|
||||
@@ -499,4 +500,8 @@ public interface SQLASTVisitor {
|
||||
void endVisit(SQLDropUserStatement x);
|
||||
|
||||
boolean visit(SQLDropUserStatement x);
|
||||
|
||||
void endVisit(SQLExplainStatement x);
|
||||
|
||||
boolean visit(SQLExplainStatement x);
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropTriggerStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropUserStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExplainStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprHint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl;
|
||||
@@ -964,4 +965,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
public boolean visit(SQLDropUserStatement x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SQLExplainStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExplainStatement x) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user