sql parser refactor.

This commit is contained in:
wenshao
2017-06-10 15:58:52 +08:00
parent 5434b65260
commit a318ebae29
17 changed files with 394 additions and 99 deletions
@@ -24,6 +24,7 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName {
private String name;
private transient String lowerName;
private transient Boolean parameter;
public SQLIdentifierExpr(){
@@ -53,8 +54,12 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName {
return lowerName;
}
public void setLowerName(String lowerName) {
this.lowerName = lowerName;
public Boolean isParameter() {
return parameter;
}
public void setParameter(Boolean parameter) {
this.parameter = parameter;
}
public void output(StringBuffer buf) {
@@ -39,6 +39,13 @@ public class SQLCreateProcedureStatement extends SQLStatementImpl {
private SQLName authid;
// for mysql
private boolean deterministic;
private boolean containsSql;
private boolean noSql;
private boolean readSqlData;
private boolean modifiesSqlData;
@Override
public void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
@@ -119,4 +126,44 @@ public class SQLCreateProcedureStatement extends SQLStatementImpl {
public void setJavaCallSpec(String javaCallSpec) {
this.javaCallSpec = javaCallSpec;
}
public boolean isDeterministic() {
return deterministic;
}
public void setDeterministic(boolean deterministic) {
this.deterministic = deterministic;
}
public boolean isContainsSql() {
return containsSql;
}
public void setContainsSql(boolean containsSql) {
this.containsSql = containsSql;
}
public boolean isNoSql() {
return noSql;
}
public void setNoSql(boolean noSql) {
this.noSql = noSql;
}
public boolean isReadSqlData() {
return readSqlData;
}
public void setReadSqlData(boolean readSqlData) {
this.readSqlData = readSqlData;
}
public boolean isModifiesSqlData() {
return modifiesSqlData;
}
public void setModifiesSqlData(boolean modifiesSqlData) {
this.modifiesSqlData = modifiesSqlData;
}
}
@@ -2030,6 +2030,8 @@ public class MySqlStatementParser extends SQLStatementParser {
if (identifierEquals("USING")) {
lexer.nextToken();
exprParser.exprList(stmt.getParameters(), stmt);
} else if (lexer.token() == Token.IDENTIFIER) {
exprParser.exprList(stmt.getParameters(), stmt);
}
return stmt;
@@ -3252,8 +3254,31 @@ public class MySqlStatementParser extends SQLStatementParser {
parserParameters(stmt.getParameters(), stmt);
accept(Token.RPAREN);// match ")"
}
SQLStatement block;
for (;;) {
if (identifierEquals("DETERMINISTIC")) {
lexer.nextToken();
stmt.setDeterministic(true);
continue;
}
if (identifierEquals("CONTAINS")) {
lexer.nextToken();
acceptIdentifier("SQL");
stmt.setContainsSql(true);
continue;
}
if (identifierEquals("SQL")) {
lexer.nextToken();
acceptIdentifier("SECURITY");
SQLName authid = this.exprParser.name();
stmt.setAuthid(authid);
}
break;
}
SQLStatement block;
if (lexer.token() == Token.BEGIN) {
block = this.parseBlock();
} else {
@@ -3565,7 +3590,7 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.THEN);
this.parseProcedureStatementList(stmt.getStatements());
this.parseStatementList(stmt.getStatements(), -1, stmt);
while (lexer.token() == Token.ELSE) {
lexer.nextToken();
@@ -3578,12 +3603,13 @@ public class MySqlStatementParser extends SQLStatementParser {
elseIf.setCondition(this.exprParser.expr());
accept(Token.THEN);
this.parseProcedureStatementList(elseIf.getStatements());
this.parseStatementList(elseIf.getStatements(), -1, elseIf);
stmt.getElseIfList().add(elseIf);
} else {
SQLIfStatement.Else elseItem = new SQLIfStatement.Else();
this.parseProcedureStatementList(elseItem.getStatements());
this.parseStatementList(elseItem.getStatements(), -1, elseItem);
stmt.setElseItem(elseItem);
break;
}
@@ -3610,7 +3636,7 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.DO);
this.parseProcedureStatementList(stmt.getStatements());
this.parseStatementList(stmt.getStatements(), -1, stmt);
accept(Token.END);
@@ -3638,7 +3664,7 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.DO);
this.parseProcedureStatementList(stmt.getStatements());
this.parseStatementList(stmt.getStatements(), -1, stmt);
accept(Token.END);
@@ -3672,14 +3698,14 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.THEN);
// when block
parseProcedureStatementList(when.getStatements());
this.parseStatementList(when.getStatements(), -1, when);
stmt.addWhenStatement(when);
}
if (lexer.token() == Token.ELSE) {
// parse else block
SQLIfStatement.Else elseStmt = new SQLIfStatement.Else();
parseProcedureStatementList(elseStmt.getStatements());
this.parseStatementList(elseStmt.getStatements(), -1, elseStmt);
stmt.setElseItem(elseStmt);
}
} else// grammar 2
@@ -3696,7 +3722,7 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.THEN);
// when block
parseProcedureStatementList(when.getStatements());
this.parseStatementList(when.getStatements(), -1, when);
stmt.addWhenStatement(when);
}
@@ -3704,7 +3730,7 @@ public class MySqlStatementParser extends SQLStatementParser {
accept(Token.ELSE);
// else block
SQLIfStatement.Else elseStmt = new SQLIfStatement.Else();
parseProcedureStatementList(elseStmt.getStatements());
this.parseStatementList(elseStmt.getStatements(), -1, elseStmt);
stmt.setElseItem(elseStmt);
}
}
@@ -3799,7 +3825,7 @@ public class MySqlStatementParser extends SQLStatementParser {
public SQLLoopStatement parseLoop() {
SQLLoopStatement loopStmt = new SQLLoopStatement();
accept(Token.LOOP);
parseProcedureStatementList(loopStmt.getStatements());
this.parseStatementList(loopStmt.getStatements(), -1, loopStmt);
accept(Token.END);
accept(Token.LOOP);
accept(Token.SEMI);
@@ -3814,7 +3840,7 @@ public class MySqlStatementParser extends SQLStatementParser {
SQLLoopStatement loopStmt = new SQLLoopStatement();
loopStmt.setLabelName(label);
accept(Token.LOOP);
parseProcedureStatementList(loopStmt.getStatements());
this.parseStatementList(loopStmt.getStatements(), -1, loopStmt);
accept(Token.END);
accept(Token.LOOP);
if (lexer.token() != Token.SEMI) {
@@ -3832,7 +3858,7 @@ public class MySqlStatementParser extends SQLStatementParser {
SQLBlockStatement block = new SQLBlockStatement();
block.setLabelName(label);
accept(Token.BEGIN);
parseProcedureStatementList(block.getStatementList());
this.parseStatementList(block.getStatementList(), -1, block);
accept(Token.END);
acceptIdentifier(label);
return block;
@@ -3888,7 +3914,7 @@ public class MySqlStatementParser extends SQLStatementParser {
MySqlRepeatStatement repeatStmt = new MySqlRepeatStatement();
repeatStmt.setLabelName(label);
accept(Token.REPEAT);
parseProcedureStatementList(repeatStmt.getStatements());
this.parseStatementList(repeatStmt.getStatements(), -1, repeatStmt);
accept(Token.UNTIL);
repeatStmt.setCondition(exprParser.expr());
accept(Token.END);
@@ -3141,45 +3141,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
return false;
}
/**
* visit procedure create node
*/
@Override
public boolean visit(SQLCreateProcedureStatement x) {
if (x.isOrReplace()) {
print0(ucase ? "CREATE OR REPLACE PROCEDURE " : "create or replace procedure ");
} else {
print0(ucase ? "CREATE PROCEDURE " : "create procedure ");
}
x.getName().accept(this);
int paramSize = x.getParameters().size();
print0(" (");
if (paramSize > 0) {
incrementIndent();
println();
for (int i = 0; i < paramSize; ++i) {
if (i != 0) {
print0(", ");
println();
}
SQLParameter param = x.getParameters().get(i);
param.accept(this);
}
decrementIndent();
println();
}
print(')');
println();
x.getBlock().setParent(x);
x.getBlock().accept(this);
return false;
}
@Override
public boolean visit(SQLIfStatement x) {
print0(ucase ? "IF " : "if ");
@@ -3587,6 +3548,72 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
return false;
}
/**
* visit procedure create node
*/
@Override
public boolean visit(SQLCreateProcedureStatement x) {
if (x.isOrReplace()) {
print0(ucase ? "CREATE OR REPLACE PROCEDURE " : "create or replace procedure ");
} else {
print0(ucase ? "CREATE PROCEDURE " : "create procedure ");
}
x.getName().accept(this);
int paramSize = x.getParameters().size();
print0(" (");
if (paramSize > 0) {
incrementIndent();
println();
for (int i = 0; i < paramSize; ++i) {
if (i != 0) {
print0(", ");
println();
}
SQLParameter param = x.getParameters().get(i);
param.accept(this);
}
decrementIndent();
println();
}
print(')');
if (x.isDeterministic()) {
println();
print(ucase ? "DETERMINISTIC" : "deterministic");
}
if (x.isContainsSql()) {
println();
print0(ucase ? "CONTAINS SQL" : "contains sql");
}
if (x.isNoSql()) {
println();
print(ucase ? "NO SQL" : "no sql");
}
if (x.isModifiesSqlData()) {
println();
print(ucase ? "MODIFIES SQL DATA" : "modifies sql data");
}
SQLName authid = x.getAuthid();
if (authid != null) {
println();
print(ucase ? "SQL SECURITY " : "sql security ");
authid.accept(this);
}
println();
x.getBlock().setParent(x);
x.getBlock().accept(this);
return false;
}
@Override
public boolean visit(SQLCreateFunctionStatement x) {
print0(ucase ? "CREATE FUNCTION " : "create function ");
@@ -103,6 +103,8 @@ public class SQLStatementParser extends SQLParser {
case EOF:
case END:
case UNTIL:
case ELSE:
case WHEN:
if (lexer.isKeepComments() && lexer.hasComment() && statementList.size() > 0) {
SQLStatement stmt = statementList.get(statementList.size() - 1);
stmt.addAfterComment(lexer.readAndResetComments());
@@ -289,6 +291,12 @@ public class SQLStatementParser extends SQLParser {
statementList.add(stmt);
continue;
}
case LEAVE: {
SQLStatement stmt = parseLeave();
stmt.setParent(parent);
statementList.add(stmt);
continue;
}
default:
break;
}
@@ -435,6 +443,10 @@ public class SQLStatementParser extends SQLParser {
throw new ParserException("not supported. " + lexer.info());
}
public SQLStatement parseLeave() {
throw new ParserException("not supported. " + lexer.info());
}
public SQLStatement parseReturn() {
if (lexer.token() == Token.RETURN
|| identifierEquals("RETURN")) {
@@ -574,12 +574,16 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
}
if (expr instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) expr;
if (isParam(identifierExpr)) {
return null;
}
Column attrColumn = (Column) expr.getAttribute(ATTR_COLUMN);
if (attrColumn != null) {
return attrColumn;
}
String column = ((SQLIdentifierExpr) expr).getName();
String column = identifierExpr.getName();
String table = getCurrentTable();
if (table != null && aliasMap.containsKey(table)) {
table = aliasMap.get(table);
@@ -715,12 +719,18 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
return false;
}
if (x.getInto() != null && x.getInto().getExpr() instanceof SQLName) {
SQLName into = (SQLName) x.getInto().getExpr();
String ident = into.toString();
TableStat stat = getTableStat(ident);
if (stat != null) {
stat.incrementInsertCount();
SQLExprTableSource into = x.getInto();
if (into != null && into.getExpr() instanceof SQLName) {
SQLName intoExpr = (SQLName) into.getExpr();
boolean isParam = intoExpr instanceof SQLIdentifierExpr && isParam((SQLIdentifierExpr) intoExpr);
if (!isParam) {
String ident = intoExpr.toString();
TableStat stat = getTableStat(ident);
if (stat != null) {
stat.incrementInsertCount();
}
}
}
@@ -761,6 +771,36 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
return true;
}
public static boolean isParam(SQLIdentifierExpr x) {
if (x.isParameter() != null) {
return x.isParameter();
}
for (SQLObject parent = x.getParent(); parent != null; parent = parent.getParent()) {
if (parent instanceof SQLCreateProcedureStatement) {
SQLCreateProcedureStatement stmt = (SQLCreateProcedureStatement) parent;
for (SQLParameter parameter : stmt.getParameters()) {
if (x.equals(parameter.getName())) {
x.setParameter(true);
return true;
}
}
break;
}
if (parent instanceof SQLBlockStatement) {
SQLBlockStatement stmt = (SQLBlockStatement) parent;
for (SQLParameter parameter : stmt.getParameters()) {
if (x.equals(parameter.getName())) {
x.setParameter(true);
return true;
}
}
}
}
return false;
}
public void endVisit(SQLSelectQueryBlock x) {
String originalTable = (String) x.getAttribute("_old_local_");
x.putAttribute("table", getCurrentTable());
@@ -945,6 +985,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
}
public boolean visit(SQLIdentifierExpr x) {
if (isParam(x)) {
return false;
}
String currentTable = getCurrentTable();
if (containsSubQuery(currentTable)) {
@@ -1208,7 +1252,12 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
public boolean visit(SQLExprTableSource x) {
if (isSimpleExprTableSource(x)) {
String ident = x.getExpr().toString();
SQLExpr expr = x.getExpr();
if (expr instanceof SQLIdentifierExpr && isParam((SQLIdentifierExpr) expr)) {
return false;
}
String ident = expr.toString();
if (variants.containsKey(ident)) {
return false;