From a25096c21140aa62bce6ddb2b2f6c9fa18b4edc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Wed, 23 May 2012 08:08:51 +0800 Subject: [PATCH] bug fixed for big or --- .../sql/visitor/SQLASTOutputVisitor.java | 109 ++++++++++-------- .../sql/visitor/SQLEvalVisitorUtils.java | 5 + .../com/alibaba/druid/bvt/sql/BigOrTest.java | 23 ++++ 3 files changed, 92 insertions(+), 45 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/BigOrTest.java 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 ce562d9e52..596d72b8ac 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -16,6 +16,7 @@ package com.alibaba.druid.sql.visitor; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import com.alibaba.druid.sql.ast.SQLCommentHint; @@ -227,44 +228,43 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { incrementIndent(); } - if (x.getLeft() instanceof SQLBinaryOpExpr) { - SQLBinaryOpExpr left = (SQLBinaryOpExpr) x.getLeft(); - boolean leftRational = left.getOperator() == SQLBinaryOperator.BooleanAnd - || left.getOperator() == SQLBinaryOperator.BooleanOr; - - if (left.getOperator().priority > x.getOperator().priority) { - if (leftRational) { - incrementIndent(); - } - print('('); - left.accept(this); - print(')'); - - if (leftRational) { - decrementIndent(); - } + List groupList = new ArrayList(); + SQLExpr left = x.getLeft(); + for (;;) { + if (left instanceof SQLBinaryOpExpr && ((SQLBinaryOpExpr) left).getOperator() == x.getOperator()) { + SQLBinaryOpExpr binaryLeft = (SQLBinaryOpExpr) left; + groupList.add(binaryLeft.getRight()); + left = binaryLeft.getLeft(); } else { - left.accept(this); + groupList.add(left); + break; } - } else { - x.getLeft().accept(this); } + for (int i = groupList.size() - 1; i >= 0; --i) { + SQLExpr item = groupList.get(i); + visitBinaryLeft(item, x.getOperator()); + + if (relational) { + println(); + } else { + print(" "); + } + print(x.getOperator().name); + print(" "); + } + + + visitorBinaryRight(x); + if (isRoot && relational) { decrementIndent(); } - if (relational) { - if (isRoot) { - incrementIndent(); - } - println(); - } else { - print(" "); - } - print(x.getOperator().name); - print(" "); + return false; + } + private void visitorBinaryRight(SQLBinaryOpExpr x) { if (x.getRight() instanceof SQLBinaryOpExpr) { SQLBinaryOpExpr right = (SQLBinaryOpExpr) x.getRight(); boolean rightRational = right.getOperator() == SQLBinaryOperator.BooleanAnd @@ -288,12 +288,31 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { } else { x.getRight().accept(this); } + } - if (isRoot && relational) { - decrementIndent(); + 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; + + if (binaryLeft.getOperator().priority > op.priority) { + if (leftRational) { + incrementIndent(); + } + print('('); + left.accept(this); + print(')'); + + if (leftRational) { + decrementIndent(); + } + } else { + left.accept(this); + } + } else { + left.accept(this); } - - return false; } public boolean visit(SQLCaseExpr x) { @@ -606,7 +625,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { printAndAccept(x.getTableSources(), ", "); return false; } - + public boolean visit(SQLDropViewStatement x) { print("DROP VIEW "); printAndAccept(x.getTableSources(), ", "); @@ -803,24 +822,24 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { println(); boolean needParen = false; - + if (x.getOrderBy() != null) { needParen = true; } - + if (needParen) { print('('); x.getRight().accept(this); print(')'); } else { - x.getRight().accept(this); + x.getRight().accept(this); } - + if (x.getOrderBy() != null) { println(); x.getOrderBy().accept(this); } - + return false; } @@ -1045,7 +1064,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { print(")"); return false; } - + @Override public boolean visit(SQLAlterTableDropColumnItem x) { print("DROP COLUMN "); @@ -1057,7 +1076,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { public void endVisit(SQLAlterTableAddColumn x) { } - + @Override public boolean visit(SQLDropIndexStatement x) { print("DROP INDEX "); @@ -1066,21 +1085,21 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { x.getTableName().accept(this); return false; } - + @Override public boolean visit(SQLSavePointStatement x) { print("SAVEPOINT "); x.getName().accept(this); return false; } - + @Override public boolean visit(SQLReleaseSavePointStatement x) { print("RELEASE SAVEPOINT "); x.getName().accept(this); return false; } - + @Override public boolean visit(SQLRollbackStatement x) { print("ROLLBACK"); @@ -1090,7 +1109,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { } return false; } - + public boolean visit(SQLCommentHint x) { print("/*"); print(x.getText()); diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java index 5a845b1190..cce8c1de68 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java @@ -98,7 +98,12 @@ public class SQLEvalVisitorUtils { } public static boolean visit(SQLEvalVisitor visitor, SQLVariantRefExpr x) { + if (!"?".equals(x.getName())) { + return false; + } + Map attributes = x.getAttributes(); + Integer varIndex = (Integer) attributes.get(EVAL_VAR_INDEX); if (varIndex == null) { varIndex = visitor.incrementAndGetVariantIndex(); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/BigOrTest.java b/src/test/java/com/alibaba/druid/bvt/sql/BigOrTest.java new file mode 100644 index 0000000000..582d528768 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/BigOrTest.java @@ -0,0 +1,23 @@ +package com.alibaba.druid.bvt.sql; + +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; + +public class BigOrTest extends TestCase { + + public void testBigOr() throws Exception { + StringBuilder buf = new StringBuilder(); + buf.append("SELECT * FROM T WHERE FID = ?"); + for (int i = 0; i < 10000; ++i) { + buf.append(" OR FID = " + i); + } + String sql = buf.toString(); + List stmtList = SQLUtils.parseStatements(sql, null); + String text = SQLUtils.toSQLString(stmtList.get(0)); + System.out.println(text); + } +}