select/update/delete add method 'addCondition & removeCondition'. for issue #1865

This commit is contained in:
wenshao
2017-10-03 14:42:18 +08:00
parent ecdf296f61
commit d847599e53
10 changed files with 409 additions and 7 deletions
@@ -15,7 +15,11 @@
*/
package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExprGroup;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -210,4 +214,82 @@ public class SQLDeleteStatement extends SQLStatementImpl implements SQLReplaceab
}
this.with = with;
}
public void addCondition(String conditionSql) {
if (conditionSql == null || conditionSql.length() == 0) {
return;
}
SQLExpr condition = SQLUtils.toSQLExpr(conditionSql, dbType);
addCondition(condition);
}
public void addCondition(SQLExpr expr) {
if (expr == null) {
return;
}
this.setWhere(SQLBinaryOpExpr.and(where, expr));
}
public boolean removeCondition(String conditionSql) {
if (conditionSql == null || conditionSql.length() == 0) {
return false;
}
SQLExpr condition = SQLUtils.toSQLExpr(conditionSql, dbType);
return removeCondition(condition);
}
public boolean removeCondition(SQLExpr condition) {
if (condition == null) {
return false;
}
if (where instanceof SQLBinaryOpExprGroup) {
SQLBinaryOpExprGroup group = (SQLBinaryOpExprGroup) where;
int removedCount = 0;
List<SQLExpr> items = group.getItems();
for (int i = items.size() - 1; i >= 0; i--) {
if (items.get(i).equals(condition)) {
items.remove(i);
removedCount++;
}
}
if (items.size() == 0) {
where = null;
}
return removedCount > 0;
}
if (where instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryOpWhere = (SQLBinaryOpExpr) where;
SQLBinaryOperator operator = binaryOpWhere.getOperator();
if (operator == SQLBinaryOperator.BooleanAnd || operator == SQLBinaryOperator.BooleanOr) {
List<SQLExpr> items = SQLBinaryOpExpr.split(binaryOpWhere);
int removedCount = 0;
for (int i = items.size() - 1; i >= 0; i--) {
SQLExpr item = items.get(i);
if (item.equals(condition)) {
if (SQLUtils.replaceInParent(item, null)) {
removedCount++;
}
}
}
return removedCount > 0;
}
}
if (condition.equals(where)) {
where = null;
return true;
}
return false;
}
}
@@ -55,6 +55,8 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
protected String cachedSelectList; // optimized for SelectListCache
protected String dbType;
public SQLSelectQueryBlock(){
}
@@ -580,6 +582,67 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
this.setWhere(SQLBinaryOpExpr.and(where, expr));
}
public boolean removeCondition(String conditionSql) {
if (conditionSql == null || conditionSql.length() == 0) {
return false;
}
SQLExpr condition = SQLUtils.toSQLExpr(conditionSql, dbType);
return removeCondition(condition);
}
public boolean removeCondition(SQLExpr condition) {
if (condition == null) {
return false;
}
if (where instanceof SQLBinaryOpExprGroup) {
SQLBinaryOpExprGroup group = (SQLBinaryOpExprGroup) where;
int removedCount = 0;
List<SQLExpr> items = group.getItems();
for (int i = items.size() - 1; i >= 0; i--) {
if (items.get(i).equals(condition)) {
items.remove(i);
removedCount++;
}
}
if (items.size() == 0) {
where = null;
}
return removedCount > 0;
}
if (where instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryOpWhere = (SQLBinaryOpExpr) where;
SQLBinaryOperator operator = binaryOpWhere.getOperator();
if (operator == SQLBinaryOperator.BooleanAnd || operator == SQLBinaryOperator.BooleanOr) {
List<SQLExpr> items = SQLBinaryOpExpr.split(binaryOpWhere);
int removedCount = 0;
for (int i = items.size() - 1; i >= 0; i--) {
SQLExpr item = items.get(i);
if (item.equals(condition)) {
if (SQLUtils.replaceInParent(item, null)) {
removedCount++;
}
}
}
return removedCount > 0;
}
}
if (condition.equals(where)) {
where = null;
return true;
}
return false;
}
public void limit(int rowCount, int offset) {
SQLLimit limit = new SQLLimit();
limit.setRowCount(new SQLIntegerExpr(rowCount));
@@ -597,4 +660,12 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
public void setCachedSelectList(String cachedSelectList) {
this.cachedSelectList = cachedSelectList;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
}
@@ -20,6 +20,9 @@ import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExprGroup;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -179,4 +182,82 @@ public class SQLUpdateStatement extends SQLStatementImpl implements SQLReplaceab
}
this.with = with;
}
public void addCondition(String conditionSql) {
if (conditionSql == null || conditionSql.length() == 0) {
return;
}
SQLExpr condition = SQLUtils.toSQLExpr(conditionSql, dbType);
addCondition(condition);
}
public void addCondition(SQLExpr expr) {
if (expr == null) {
return;
}
this.setWhere(SQLBinaryOpExpr.and(where, expr));
}
public boolean removeCondition(String conditionSql) {
if (conditionSql == null || conditionSql.length() == 0) {
return false;
}
SQLExpr condition = SQLUtils.toSQLExpr(conditionSql, dbType);
return removeCondition(condition);
}
public boolean removeCondition(SQLExpr condition) {
if (condition == null) {
return false;
}
if (where instanceof SQLBinaryOpExprGroup) {
SQLBinaryOpExprGroup group = (SQLBinaryOpExprGroup) where;
int removedCount = 0;
List<SQLExpr> items = group.getItems();
for (int i = items.size() - 1; i >= 0; i--) {
if (items.get(i).equals(condition)) {
items.remove(i);
removedCount++;
}
}
if (items.size() == 0) {
where = null;
}
return removedCount > 0;
}
if (where instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryOpWhere = (SQLBinaryOpExpr) where;
SQLBinaryOperator operator = binaryOpWhere.getOperator();
if (operator == SQLBinaryOperator.BooleanAnd || operator == SQLBinaryOperator.BooleanOr) {
List<SQLExpr> items = SQLBinaryOpExpr.split(binaryOpWhere);
int removedCount = 0;
for (int i = items.size() - 1; i >= 0; i--) {
SQLExpr item = items.get(i);
if (item.equals(condition)) {
if (SQLUtils.replaceInParent(item, null)) {
removedCount++;
}
}
}
return removedCount > 0;
}
}
if (condition.equals(where)) {
where = null;
return true;
}
return false;
}
}
@@ -21,11 +21,9 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.db2.ast.DB2Object;
import com.alibaba.druid.sql.dialect.db2.visitor.DB2ASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class DB2SelectQueryBlock extends SQLSelectQueryBlock implements DB2Object {
private Isolation isolation;
private boolean forReadOnly;
@@ -54,6 +52,10 @@ public class DB2SelectQueryBlock extends SQLSelectQueryBlock implements DB2Objec
visitor.endVisit(this);
}
public DB2SelectQueryBlock() {
dbType = JdbcConstants.DB2;
}
public Isolation getIsolation() {
return isolation;
}
@@ -26,6 +26,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObject;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
import oracle.sql.SQLUtil;
public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlObject {
@@ -42,7 +43,7 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlO
private List<SQLCommentHint> hints;
public MySqlSelectQueryBlock(){
dbType = JdbcConstants.MYSQL;
}
public MySqlSelectQueryBlock clone() {
@@ -28,6 +28,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class OdpsSelectQueryBlock extends SQLSelectQueryBlock {
@@ -36,6 +37,8 @@ public class OdpsSelectQueryBlock extends SQLSelectQueryBlock {
protected List<SQLHint> hints;
public OdpsSelectQueryBlock(){
dbType = JdbcConstants.ODPS;
distributeBy = new ArrayList<SQLExpr>();
sortBy = new ArrayList<SQLSelectOrderByItem>(2);
}
@@ -48,8 +51,6 @@ public class OdpsSelectQueryBlock extends SQLSelectQueryBlock {
this.orderBy = orderBy;
}
@Override
public int hashCode() {
final int prime = 31;
@@ -31,6 +31,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.ModelClause;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class OracleSelectQueryBlock extends SQLSelectQueryBlock implements OracleSQLObject {
@@ -72,7 +73,7 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock implements Oracl
}
public OracleSelectQueryBlock(){
dbType = JdbcConstants.ORACLE;
}
public ModelClause getModelClause() {
@@ -25,6 +25,7 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.PGSQLObject;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSQLObjectImpl;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class PGSelectQueryBlock extends SQLSelectQueryBlock implements PGSQLObject{
@@ -40,6 +41,10 @@ public class PGSelectQueryBlock extends SQLSelectQueryBlock implements PGSQLObje
TEMPORARY, TEMP, UNLOGGED
}
public PGSelectQueryBlock() {
dbType = JdbcConstants.POSTGRESQL;
}
public IntoOption getIntoOption() {
return intoOption;
}
@@ -20,11 +20,16 @@ import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class SQLServerSelectQueryBlock extends SQLSelectQueryBlock {
private SQLServerTop top;
public SQLServerSelectQueryBlock() {
dbType = JdbcConstants.SQL_SERVER;
}
public SQLServerTop getTop() {
return top;
}
@@ -0,0 +1,153 @@
package com.alibaba.druid.bvt.bug;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.parser.SQLParserFeature;
import com.alibaba.druid.sql.parser.SQLParserUtils;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.util.JdbcConstants;
import junit.framework.TestCase;
import java.util.List;
public class Issue1865 extends TestCase {
public void test_for_select() throws Exception {
final String dbType = JdbcConstants.MYSQL;
String sql = "select * from t where id = 2 and name = 'wenshao'";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType);
SQLSelectStatement stmt = (SQLSelectStatement) parser.parseStatement();
SQLSelectQueryBlock queryBlock = stmt.getSelect().getQueryBlock();
assertTrue(queryBlock.removeCondition("name = 'wenshao'"));
assertEquals("SELECT *\n" +
"FROM t\n" +
"WHERE id = 2", stmt.toString());
assertTrue(
queryBlock.removeCondition("id = 2"));
assertEquals("SELECT *\n" +
"FROM t", stmt.toString());
}
public void test_for_select_group() throws Exception {
final String dbType = JdbcConstants.MYSQL;
String sql = "select * from t where id = 2 and name = 'wenshao'";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType, SQLParserFeature.EnableSQLBinaryOpExprGroup);
SQLSelectStatement stmt = (SQLSelectStatement) parser.parseStatement();
SQLSelectQueryBlock queryBlock = stmt.getSelect().getQueryBlock();
assertTrue(queryBlock.removeCondition("name = 'wenshao'"));
assertEquals("SELECT *\n" +
"FROM t\n" +
"WHERE id = 2", stmt.toString());
assertTrue(
queryBlock.removeCondition("id = 2"));
assertEquals("SELECT *\n" +
"FROM t", stmt.toString());
}
public void test_for_delete() throws Exception {
final String dbType = JdbcConstants.MYSQL;
String sql = "delete from t where id = 2 and name = 'wenshao'";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType);
SQLDeleteStatement stmt = (SQLDeleteStatement) parser.parseStatement();
assertTrue(stmt.removeCondition("name = 'wenshao'"));
assertEquals("DELETE FROM t\n" +
"WHERE id = 2", stmt.toString());
assertTrue(
stmt.removeCondition("id = 2"));
assertEquals("DELETE FROM t", stmt.toString());
stmt.addCondition("id = 3");
assertEquals("DELETE FROM t\n" +
"WHERE id = 3", stmt.toString());
}
public void test_for_delete_group() throws Exception {
final String dbType = JdbcConstants.MYSQL;
String sql = "delete from t where id = 2 and name = 'wenshao'";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType, SQLParserFeature.EnableSQLBinaryOpExprGroup);
SQLDeleteStatement stmt = (SQLDeleteStatement) parser.parseStatement();
assertTrue(stmt.removeCondition("name = 'wenshao'"));
assertEquals("DELETE FROM t\n" +
"WHERE id = 2", stmt.toString());
assertTrue(
stmt.removeCondition("id = 2"));
assertEquals("DELETE FROM t", stmt.toString());
stmt.addCondition("id = 3");
assertEquals("DELETE FROM t\n" +
"WHERE id = 3", stmt.toString());
}
public void test_for_update() throws Exception {
final String dbType = JdbcConstants.MYSQL;
String sql = "update t set val = ? where id = 2 and name = 'wenshao'";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType);
SQLUpdateStatement stmt = (SQLUpdateStatement) parser.parseStatement();
assertTrue(stmt.removeCondition("name = 'wenshao'"));
assertEquals("UPDATE t\n" +
"SET val = ?\n" +
"WHERE id = 2", stmt.toString());
assertTrue(
stmt.removeCondition("id = 2"));
assertEquals("UPDATE t\n" +
"SET val = ?", stmt.toString());
stmt.addCondition("id = 3");
assertEquals("UPDATE t\n" +
"SET val = ?\n" +
"WHERE id = 3", stmt.toString());
}
public void test_for_update_group() throws Exception {
final String dbType = JdbcConstants.MYSQL;
String sql = "update t set val = ? where id = 2 and name = 'wenshao'";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType, SQLParserFeature.EnableSQLBinaryOpExprGroup);
SQLUpdateStatement stmt = (SQLUpdateStatement) parser.parseStatement();
assertTrue(stmt.removeCondition("name = 'wenshao'"));
assertEquals("UPDATE t\n" +
"SET val = ?\n" +
"WHERE id = 2", stmt.toString());
assertTrue(
stmt.removeCondition("id = 2"));
assertEquals("UPDATE t\n" +
"SET val = ?", stmt.toString());
stmt.addCondition("id = 3");
assertEquals("UPDATE t\n" +
"SET val = ?\n" +
"WHERE id = 3", stmt.toString());
}
}