From edbaa3db38b6cf2248872f974ad66bf976afaaf8 Mon Sep 17 00:00:00 2001 From: wenshao Date: Fri, 20 May 2011 09:26:26 +0000 Subject: [PATCH] git-svn-id: http://code.alibabatech.com/svn/druid/trunk@158 b9813039-fb51-4c41-a8b9-e21c2acb5095 --- .../MySqlParameterizedOutputVisitor.java | 53 +++++++++++++++++-- .../OracleParameterizedOutputVisitor.java | 9 ++++ .../MySqlParameterizedOutputVisitorTest.java | 2 + 3 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleParameterizedOutputVisitor.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlParameterizedOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlParameterizedOutputVisitor.java index ae3a4e0789..d005a89f64 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlParameterizedOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlParameterizedOutputVisitor.java @@ -1,9 +1,12 @@ package com.alibaba.druid.sql.dialect.mysql.visitor; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; +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.SQLVariantRefExpr; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; public class MySqlParameterizedOutputVisitor extends MySqlOutputVisitor { @@ -11,7 +14,7 @@ public class MySqlParameterizedOutputVisitor extends MySqlOutputVisitor { public MySqlParameterizedOutputVisitor(Appendable appender){ super(appender); } - + public void println() { print(' '); } @@ -24,9 +27,10 @@ public class MySqlParameterizedOutputVisitor extends MySqlOutputVisitor { } else { print(" IN (##)"); } + return false; } - + public boolean visit(SQLBinaryOpExpr x) { if (x.getLeft() instanceof SQLLiteralExpr && x.getRight() instanceof SQLLiteralExpr) { print(x.getLeft().toString()); @@ -37,9 +41,52 @@ public class MySqlParameterizedOutputVisitor extends MySqlOutputVisitor { return false; } + x = merge(x); + return super.visit(x); } - + + public SQLBinaryOpExpr merge(SQLBinaryOpExpr x) { + if (x.getRight() instanceof SQLLiteralExpr) { + x = new SQLBinaryOpExpr(x.getLeft(), x.getOperator(), new SQLVariantRefExpr("?")); + } + + if (x.getLeft() instanceof SQLLiteralExpr) { + x = new SQLBinaryOpExpr(new SQLVariantRefExpr("?"), x.getOperator(), x.getRight()); + } + + if (x.getRight() instanceof SQLBinaryOpExpr) { + x = new SQLBinaryOpExpr(x.getLeft(), x.getOperator(), merge((SQLBinaryOpExpr) x.getRight())); + } + + if (x.getLeft() instanceof SQLBinaryOpExpr) { + x = new SQLBinaryOpExpr((SQLBinaryOpExpr) x.getLeft(), x.getOperator(), x.getRight()); + } + + // ID = ? OR ID = ? => ID = ? + if (x.getOperator() == SQLBinaryOperator.BooleanOr) { + if ((x.getLeft() instanceof SQLBinaryOpExpr) && (x.getRight() instanceof SQLBinaryOpExpr)) { + 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 (leftColumn.equals(rightColumn)) { + if ((left.getRight() instanceof SQLVariantRefExpr) && (right.getRight() instanceof SQLVariantRefExpr)) { + return left; // merge + } + } + } + } + } + } + + return x; + } + public boolean visit(SQLIntegerExpr x) { print('?'); return false; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleParameterizedOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleParameterizedOutputVisitor.java new file mode 100644 index 0000000000..d76136839b --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/visitor/OracleParameterizedOutputVisitor.java @@ -0,0 +1,9 @@ +package com.alibaba.druid.sql.dialect.oracle.ast.visitor; + +public class OracleParameterizedOutputVisitor extends OracleOutputVisitor { + + public OracleParameterizedOutputVisitor(Appendable appender){ + super(appender); + } + +} diff --git a/src/test/java/com/alibaba/druid/sql/mysql/bvt/MySqlParameterizedOutputVisitorTest.java b/src/test/java/com/alibaba/druid/sql/mysql/bvt/MySqlParameterizedOutputVisitorTest.java index 4d1713f0ff..a13600d656 100644 --- a/src/test/java/com/alibaba/druid/sql/mysql/bvt/MySqlParameterizedOutputVisitorTest.java +++ b/src/test/java/com/alibaba/druid/sql/mysql/bvt/MySqlParameterizedOutputVisitorTest.java @@ -15,6 +15,8 @@ public class MySqlParameterizedOutputVisitorTest extends TestCase { validate("SELECT * FROM T WHERE ID IN (?, ?, ?)", "SELECT * FROM T WHERE ID IN (##)"); validate("SELECT * FROM T WHERE ID = 5", "SELECT * FROM T WHERE ID = ?"); validate("SELECT * FROM T WHERE 1 = 0 AND ID = 5", "SELECT * FROM T WHERE 1 = 0 AND ID = ?"); + validate("SELECT * FROM T WHERE ID = ? OR ID = ?", "SELECT * FROM T WHERE ID = ?"); + validate("INSERT INTO T (F1, F2) VALUES(?, ?), (?, ?), (?, ?)", "INSERT INTO T (F1, F2) VALUES (?, ?)"); } void validate(String sql, String expect) {