SQL参数合并

git-svn-id: http://code.alibabatech.com/svn/druid/trunk@217 b9813039-fb51-4c41-a8b9-e21c2acb5095
This commit is contained in:
wenshao
2011-05-30 05:48:55 +00:00
parent 7efc722dc1
commit 3c17d5dcf7
3 changed files with 54 additions and 25 deletions
@@ -4,13 +4,11 @@ import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
@@ -1,5 +1,6 @@
package com.alibaba.druid.sql.dialect.oracle.ast.visitor;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
@@ -40,14 +41,14 @@ public class OracleParameterizedOutputVisitor extends OracleOutputVisitor {
return super.visit(x);
}
public SQLBinaryOpExpr merge(SQLBinaryOpExpr x) {
if (x.getLeft() instanceof SQLLiteralExpr && x.getRight() instanceof SQLLiteralExpr) {
x.getLeft().getAttributes().put(ATTR_PARAMS_SKIP, true);
x.getRight().getAttributes().put(ATTR_PARAMS_SKIP, true);
return x;
}
if (x.getRight() instanceof SQLLiteralExpr) {
x = new SQLBinaryOpExpr(x.getLeft(), x.getOperator(), new SQLVariantRefExpr("?"));
}
@@ -61,7 +62,7 @@ public class OracleParameterizedOutputVisitor extends OracleOutputVisitor {
}
if (x.getLeft() instanceof SQLBinaryOpExpr) {
x = new SQLBinaryOpExpr((SQLBinaryOpExpr) x.getLeft(), x.getOperator(), x.getRight());
x = new SQLBinaryOpExpr(merge((SQLBinaryOpExpr) x.getLeft()), x.getOperator(), x.getRight());
}
// ID = ? OR ID = ? => ID = ?
@@ -70,27 +71,13 @@ public class OracleParameterizedOutputVisitor extends OracleOutputVisitor {
SQLBinaryOpExpr left = (SQLBinaryOpExpr) x.getLeft();
SQLBinaryOpExpr right = (SQLBinaryOpExpr) x.getRight();
if (left.getOperator() == SQLBinaryOperator.Equality && right.getOperator() == SQLBinaryOperator.Equality) {
if ((left.getLeft() instanceof SQLIdentifierExpr) && (right.getLeft() instanceof SQLIdentifierExpr)) {
String leftColumn = left.getLeft().toString();
String rightColumn = right.getLeft().toString();
if (mergeEqual(left, right)) {
return left;
}
if (leftColumn.equals(rightColumn)) {
if ((left.getRight() instanceof SQLVariantRefExpr) && (right.getRight() instanceof SQLVariantRefExpr)) {
return left; // merge
}
}
}
if ((left.getLeft() instanceof SQLPropertyExpr) && (right.getLeft() instanceof SQLPropertyExpr)) {
String leftColumn = left.getLeft().toString();
String rightColumn = right.getLeft().toString();
if (leftColumn.equals(rightColumn)) {
if ((left.getRight() instanceof SQLVariantRefExpr) && (right.getRight() instanceof SQLVariantRefExpr)) {
return left; // merge
}
}
if (isLiteralExpr(left.getLeft()) && left.getOperator() == SQLBinaryOperator.BooleanOr) {
if (mergeEqual(left.getRight(), right)) {
return left;
}
}
}
@@ -98,6 +85,49 @@ public class OracleParameterizedOutputVisitor extends OracleOutputVisitor {
return x;
}
private boolean mergeEqual(SQLExpr a, SQLExpr b) {
if (!(a instanceof SQLBinaryOpExpr)) {
return false;
}
if (!(b instanceof SQLBinaryOpExpr)) {
return false;
}
SQLBinaryOpExpr binaryA = (SQLBinaryOpExpr) a;
SQLBinaryOpExpr binaryB = (SQLBinaryOpExpr) b;
if (binaryA.getOperator() != SQLBinaryOperator.Equality) {
return false;
}
if (binaryB.getOperator() != SQLBinaryOperator.Equality) {
return false;
}
if (!(binaryA.getRight() instanceof SQLLiteralExpr || binaryA.getRight() instanceof SQLVariantRefExpr)) {
return false;
}
if (!(binaryB.getRight() instanceof SQLLiteralExpr || binaryB.getRight() instanceof SQLVariantRefExpr)) {
return false;
}
return binaryA.getLeft().toString().equals(binaryB.getLeft().toString());
}
private boolean isLiteralExpr(SQLExpr expr) {
if (expr instanceof SQLLiteralExpr) {
return true;
}
if (expr instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binary = (SQLBinaryOpExpr) expr;
return isLiteralExpr(binary.getLeft()) && isLiteralExpr(binary.getRight());
}
return false;
}
public boolean visit(SQLIntegerExpr x) {
if (Boolean.TRUE.equals(x.getAttribute(ATTR_PARAMS_SKIP))) {
@@ -20,6 +20,7 @@ public class MySqlParameterizedOutputVisitorTest extends TestCase {
validate("SELECT * FROM T WHERE ID = ? OR ID = ?", "SELECT * FROM T WHERE ID = ?");
validate("SELECT * FROM T WHERE A.ID = ? OR A.ID = ?", "SELECT * FROM T WHERE A.ID = ?");
validate("SELECT * FROM T WHERE 1 = 0 OR a.id = ? OR a.id = ? OR a.id = ? OR a.id = ?", "SELECT * FROM T WHERE 1 = 0 OR a.id = ?");
validateOracle("SELECT * FROM T WHERE 1 = 0 OR a.id = ? OR a.id = ? OR a.id = ? OR a.id = ?", "SELECT * FROM T WHERE 1 = 0 OR a.id = ?; ");
validateOracle("SELECT * FROM T WHERE A.ID = ? OR A.ID = ?", "SELECT * FROM T WHERE A.ID = ?; ");
validate("INSERT INTO T (F1, F2) VALUES(?, ?), (?, ?), (?, ?)", "INSERT INTO T (F1, F2) VALUES (?, ?)");