#789 - findCount() ... with where raw(...) expression that includes a "many" produces incorrect SQL

This commit is contained in:
Robin Bygrave
2016-07-31 14:57:12 +12:00
parent 780ee7c7c0
commit 56fee2ea9b
9 changed files with 98 additions and 30 deletions
@@ -137,10 +137,10 @@ public class ManyWhereJoins implements Serializable {
}
/**
* Return true if the findRowCount query just needs the id property in the select clause.
* Return true if the query select includes a formula with join.
*/
public boolean isSelectId() {
return !formulaWithJoin;
public boolean isFormulaWithJoin() {
return formulaWithJoin;
}
/**
@@ -123,7 +123,7 @@ public class CQueryBuilder {
if (!sqlTree.isIncludeJoins()) {
// simple - delete from table ...
return aliasStrip(buildSql("delete", request, predicates, sqlTree).getSql());
return aliasStrip(buildSql("delete", request, predicates, sqlTree).getSql());
}
// wrap as - delete from table where id in (select id ...)
String sql = buildSql(null, request, predicates, sqlTree).getSql();
@@ -135,11 +135,11 @@ public class CQueryBuilder {
private <T> String buildUpdateSql(OrmQueryRequest<T> request, String rootTableAlias, CQueryPredicates predicates, SqlTree sqlTree) {
String updateClause = "update "+request.getBeanDescriptor().getBaseTable()+" set "+predicates.getDbUpdateClause();
String updateClause = "update " + request.getBeanDescriptor().getBaseTable() + " set " + predicates.getDbUpdateClause();
if (!sqlTree.isIncludeJoins()) {
// simple - update table set ... where ...
return aliasStrip(buildSqlUpdate(updateClause, request, predicates, sqlTree).getSql());
return aliasStrip(buildSqlUpdate(updateClause, request, predicates, sqlTree).getSql());
}
// wrap as - update table set ... where id in (select id ...)
String sql = buildSqlUpdate(null, request, predicates, sqlTree).getSql();
@@ -161,7 +161,7 @@ public class CQueryBuilder {
* Replace the root table alias.
*/
private String aliasReplace(String sql, String replaceWith) {
sql = StringHelper.replaceString(sql, "${RTA}.", replaceWith+".");
sql = StringHelper.replaceString(sql, "${RTA}.", replaceWith + ".");
return StringHelper.replaceString(sql, "${RTA}", replaceWith);
}
@@ -225,20 +225,10 @@ public class CQueryBuilder {
ManyWhereJoins manyWhereJoins = query.getManyWhereJoins();
boolean hasMany = manyWhereJoins.isHasMany();
if (manyWhereJoins.isSelectId()) {
// just select the id property
query.setSelectId();
} else {
// select the id and the required formula properties
if (manyWhereJoins.isFormulaWithJoin()) {
query.select(manyWhereJoins.getFormulaProperties());
}
String sqlSelect = "select count(*)";
if (hasMany) {
// need to count distinct id's ...
query.setSqlDistinct(true);
sqlSelect = null;
} else {
query.setSelectId();
}
CQueryPredicates predicates = new CQueryPredicates(binder, request);
@@ -257,6 +247,14 @@ public class CQueryBuilder {
sqlTree.addSoftDeletePredicate(query);
}
boolean hasMany = sqlTree.hasMany();
String sqlSelect = "select count(*)";
if (hasMany) {
// need to count distinct id's ...
query.setSqlDistinct(true);
sqlSelect = null;
}
SqlLimitResponse s = buildSql(sqlSelect, request, predicates, sqlTree);
String sql = s.getSql();
if (hasMany || query.isRawSql()) {
@@ -488,7 +486,7 @@ public class CQueryBuilder {
}
if (stripAlias) {
// strip the table alias for use in update statement
idSql = StringHelper.replaceString(idSql, "t0.","");
idSql = StringHelper.replaceString(idSql, "t0.", "");
}
sb.append(idSql).append(" ");
hasWhere = true;
@@ -153,4 +153,10 @@ public class SqlTree {
return encryptedProps;
}
/**
* Return true if the query has a many join.
*/
public boolean hasMany() {
return manyProperty != null || rootNode.hasMany();
}
}
@@ -57,4 +57,9 @@ public interface SqlTreeNode {
* Load a version of a @History bean with effective dates.
*/
<T> Version<T> loadVersion(DbReadContext ctx) throws SQLException;
/**
* Return true if the query has a many join.
*/
boolean hasMany();
}
@@ -1,11 +1,5 @@
package com.avaje.ebeaninternal.server.query;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.avaje.ebean.Version;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.EntityBean;
@@ -24,6 +18,12 @@ import com.avaje.ebeaninternal.server.deploy.TableJoin;
import com.avaje.ebeaninternal.server.deploy.id.IdBinder;
import com.avaje.ebeaninternal.server.lib.util.StringHelper;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Normal bean included in the query.
*/
@@ -570,4 +570,14 @@ public class SqlTreeNodeBean implements SqlTreeNode {
return true;
}
@Override
public boolean hasMany() {
for (SqlTreeNode child : children) {
if (child.hasMany()) {
return true;
}
}
return false;
}
}
@@ -146,4 +146,9 @@ public class SqlTreeNodeExtraJoin implements SqlTreeNode {
public <T> Version<T> loadVersion(DbReadContext ctx) throws SQLException {
return null;
}
@Override
public boolean hasMany() {
return manyJoin;
}
}
@@ -1,13 +1,13 @@
package com.avaje.ebeaninternal.server.query;
import java.sql.SQLException;
import java.util.List;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import com.avaje.ebeaninternal.server.deploy.DbReadContext;
import com.avaje.ebeaninternal.server.deploy.DbSqlContext;
import java.sql.SQLException;
import java.util.List;
public final class SqlTreeNodeManyRoot extends SqlTreeNodeBean {
private final BeanPropertyAssocMany<?> manyProp;
@@ -38,4 +38,8 @@ public final class SqlTreeNodeManyRoot extends SqlTreeNodeBean {
super.appendFrom(ctx, joinType.autoToOuter());
}
@Override
public boolean hasMany() {
return true;
}
}
@@ -109,4 +109,9 @@ public class SqlTreeNodeManyWhereJoin implements SqlTreeNode {
// nothing to do here
return null;
}
@Override
public boolean hasMany() {
return true;
}
}