improved sql parser.

This commit is contained in:
wenshao
2017-06-28 15:34:43 +08:00
parent c64c40e81d
commit 2f6e406e33
19 changed files with 971 additions and 14 deletions
@@ -35,6 +35,8 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements SQLReplaceable, Seri
private SQLBinaryOperator operator;
private String dbType;
private boolean bracket = false;
public SQLBinaryOpExpr(){
}
@@ -99,6 +101,14 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements SQLReplaceable, Seri
this.operator = operator;
}
public boolean isBracket() {
return bracket;
}
public void setBracket(boolean bracket) {
this.bracket = bracket;
}
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.left);
@@ -87,4 +87,14 @@ public class SQLQueryExpr extends SQLExprImpl implements Serializable {
}
return true;
}
public SQLQueryExpr clone() {
SQLQueryExpr x = new SQLQueryExpr();
if (subQuery != null) {
x.setSubQuery(subQuery.clone());
}
return x;
}
}
@@ -43,9 +43,6 @@ public class DB2OutputVisitor extends SQLASTOutputVisitor implements DB2ASTVisit
if (x.isForReadOnly()) {
println();
print0(ucase ? "FOR READ ONLY" : "for read only");
} else if (x.isForUpdate()) {
println();
print0(ucase ? "FOR UPDATE" : "for update");
}
if (x.getIsolation() != null) {
@@ -1695,7 +1695,7 @@ public class OracleStatementParser extends SQLStatementParser {
if (lexer.token() == Token.ALL) {
lexer.nextToken();
stmt.setOption(OracleMultiInsertStatement.Option.ALL);
} else if (lexer.token() == Token.FIRST) {
} else if (lexer.token() == Token.FIRST || identifierEquals("FIRST")) {
lexer.nextToken();
stmt.setOption(OracleMultiInsertStatement.Option.FIRST);
}
@@ -144,8 +144,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
}
public boolean visit(OracleDbLinkExpr x) {
x.getExpr().accept(this);
print('@');
SQLExpr expr = x.getExpr();
if (expr != null) {
expr.accept(this);
print('@');
}
print0(x.getDbLink());
return false;
}
@@ -228,6 +228,10 @@ public class SQLExprParser extends SQLParser {
sqlExpr = listExpr;
}
if (sqlExpr instanceof SQLBinaryOpExpr) {
((SQLBinaryOpExpr) sqlExpr).setBracket(true);
}
accept(Token.RPAREN);
break;
@@ -33,6 +33,7 @@ import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerEven
import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerType;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlRepeatStatement;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.JdbcUtils;
public class SQLStatementParser extends SQLParser {
@@ -129,6 +130,14 @@ public class SQLStatementParser extends SQLParser {
continue;
}
case WITH:
if (!JdbcConstants.POSTGRESQL.equals(dbType)){
SQLStatement stmt = parseSelect();
stmt.setParent(parent);
statementList.add(stmt);
continue;
}
break;
case SELECT: {
SQLStatement stmt = parseSelect();
stmt.setParent(parent);
@@ -476,10 +476,17 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
if (x.getRight() instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr right = (SQLBinaryOpExpr) x.getRight();
boolean rightRational = right.getOperator() == SQLBinaryOperator.BooleanAnd
|| right.getOperator() == SQLBinaryOperator.BooleanOr;
SQLBinaryOperator rightOp = right.getOperator();
SQLBinaryOperator op = x.getOperator();
boolean rightRational = rightOp == SQLBinaryOperator.BooleanAnd
|| rightOp == SQLBinaryOperator.BooleanOr;
if (right.getOperator().priority >= x.getOperator().priority) {
if (rightOp.priority >= op.priority
|| (right.isBracket()
&& rightOp != op
&& rightOp.isLogical()
&& op.isLogical()
)) {
if (rightRational) {
incrementIndent();
}
@@ -507,10 +514,16 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
private void visitBinaryLeft(SQLExpr left, SQLBinaryOperator op) {
if (left instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryLeft = (SQLBinaryOpExpr) left;
boolean leftRational = binaryLeft.getOperator() == SQLBinaryOperator.BooleanAnd
|| binaryLeft.getOperator() == SQLBinaryOperator.BooleanOr;
SQLBinaryOperator leftOp = binaryLeft.getOperator();
boolean leftRational = leftOp == SQLBinaryOperator.BooleanAnd
|| leftOp == SQLBinaryOperator.BooleanOr;
if (binaryLeft.getOperator().priority > op.priority) {
if (leftOp.priority > op.priority
|| (binaryLeft.isBracket()
&& leftOp != op
&& leftOp.isLogical()
&& op.isLogical()
)) {
if (leftRational) {
incrementIndent();
}