sql parameterized support unmerge or list. for issue #2500

This commit is contained in:
wenshao
2018-04-20 16:55:58 +08:00
parent 1e62d8961e
commit 28ac367003
4 changed files with 98 additions and 31 deletions
@@ -71,6 +71,12 @@ public class ParameterizedOutputVisitorUtils {
}
}
public static String parameterize(String sql
, String dbType
, List<Object> outParameters, VisitorFeature ...features) {
return parameterize(sql, dbType, null, outParameters, features);
}
public static String parameterize(String sql
, String dbType
, SQLSelectListCache selectListCache, List<Object> outParameters, VisitorFeature ...visitorFeatures) {
@@ -520,45 +520,47 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
List<SQLBinaryOpExpr> literalItems = null;
for (int i = 0; i < items.size(); i++) {
SQLExpr item = items.get(i);
if (item instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryItem = (SQLBinaryOpExpr) item;
SQLExpr left = binaryItem.getLeft();
SQLExpr right = binaryItem.getRight();
if (operator != SQLBinaryOperator.BooleanOr || !isEnabled(VisitorFeature.OutputParameterizedQuesUnMergeOr)) {
for (int i = 0; i < items.size(); i++) {
SQLExpr item = items.get(i);
if (item instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryItem = (SQLBinaryOpExpr) item;
SQLExpr left = binaryItem.getLeft();
SQLExpr right = binaryItem.getRight();
if (right instanceof SQLLiteralExpr && !(right instanceof SQLNullExpr)) {
if (left instanceof SQLLiteralExpr) {
if (literalItems == null) {
literalItems = new ArrayList<SQLBinaryOpExpr>();
if (right instanceof SQLLiteralExpr && !(right instanceof SQLNullExpr)) {
if (left instanceof SQLLiteralExpr) {
if (literalItems == null) {
literalItems = new ArrayList<SQLBinaryOpExpr>();
}
literalItems.add(binaryItem);
continue;
}
literalItems.add(binaryItem);
continue;
if (this.parameters != null) {
ExportParameterVisitorUtils.exportParameter(parameters, right);
}
} else if (right instanceof SQLVariantRefExpr) {
// skip
} else {
firstLeft = null;
break;
}
if (this.parameters != null) {
ExportParameterVisitorUtils.exportParameter(parameters, right);
if (firstLeft == null) {
firstLeft = binaryItem.getLeft();
firstOp = binaryItem.getOperator();
} else {
if (!SQLExprUtils.equals(firstLeft, left)) {
firstLeft = null;
break;
}
}
} else if (right instanceof SQLVariantRefExpr) {
// skip
} else {
firstLeft = null;
break;
}
if (firstLeft == null) {
firstLeft = binaryItem.getLeft();
firstOp = binaryItem.getOperator();
} else {
if (!SQLExprUtils.equals(firstLeft, left)) {
firstLeft = null;
break;
}
}
} else {
firstLeft = null;
break;
}
}
@@ -653,7 +655,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
public boolean visit(SQLBinaryOpExpr x) {
SQLBinaryOperator operator = x.getOperator();
if (this.parameterized
&& operator == SQLBinaryOperator.BooleanOr) {
&& operator == SQLBinaryOperator.BooleanOr
&& !isEnabled(VisitorFeature.OutputParameterizedQuesUnMergeOr)) {
x = SQLBinaryOpExpr.merge(this, x);
operator = x.getOperator();
@@ -24,6 +24,7 @@ public enum VisitorFeature {
OutputSkipSelectListCacheString,
OutputSkipInsertColumnsString,
OutputParameterizedQuesUnMergeInList,
OutputParameterizedQuesUnMergeOr,
/**
* @deprecated
@@ -0,0 +1,57 @@
package com.alibaba.druid.bvt.sql.mysql.param;
import com.alibaba.fastjson.JSON;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils;
import com.alibaba.druid.sql.visitor.ParameterizedVisitor;
import com.alibaba.druid.sql.visitor.VisitorFeature;
import com.alibaba.druid.util.JdbcConstants;
import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.List;
public class MySqlParameterizedOutputVisitorTest_75_or extends TestCase {
public void test_or() throws Exception {
String sql = "select * from t1 where id = 1 or id = 2 or id = 3";
List<Object> outParameters = new ArrayList<Object>(0);
String psql = ParameterizedOutputVisitorUtils.parameterize(sql, JdbcConstants.MYSQL, outParameters, VisitorFeature.OutputParameterizedQuesUnMergeOr);
assertEquals("SELECT *\n" +
"FROM t1\n" +
"WHERE id = ?\n" +
"\tOR id = ?\n" +
"\tOR id = ?", psql);
assertEquals("[1,2,3]", JSON.toJSONString(outParameters));
}
public void test_or_2() throws Exception {
String sql = "select * from t1 where id = 1 or id = 2 or id = 3";
List<Object> outParameters = new ArrayList<Object>(0);
SQLStatement stmt = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL).get(0);
StringBuilder out = new StringBuilder(sql.length());
ParameterizedVisitor visitor = ParameterizedOutputVisitorUtils.createParameterizedOutputVisitor(out, JdbcConstants.MYSQL);
visitor.config(VisitorFeature.OutputParameterizedQuesUnMergeOr, true);
if (outParameters != null) {
visitor.setOutputParameters(outParameters);
}
stmt.accept(visitor);
String psql = out.toString();
assertEquals("SELECT *\n" +
"FROM t1\n" +
"WHERE id = ?\n" +
"\tOR id = ?\n" +
"\tOR id = ?", psql);
assertEquals("[1,2,3]", JSON.toJSONString(outParameters));
}
}