Fix for issue 68 - findRowCount sql error when using a @Formula property in the where clause

This commit is contained in:
Rob Bygrave
2014-01-16 20:36:23 +13:00
parent 664f08fd6f
commit 73452a5f68
9 changed files with 119 additions and 7 deletions
@@ -19,6 +19,10 @@ public class ManyWhereJoins implements Serializable {
private final TreeSet<String> joins = new TreeSet<String>();
private StringBuilder formulaProperties = new StringBuilder();
private boolean formulaWithJoin;
/**
* Add a many where join.
*/
@@ -73,4 +77,36 @@ public class ManyWhereJoins implements Serializable {
return joins;
}
/**
* In findRowCount query found a formula property with a join clause so building a select clause
* specifically for the findRowCount query.
*/
public void addFormulaWithJoin(String propertyName) {
if (formulaWithJoin) {
formulaProperties.append(",");
} else {
formulaProperties = new StringBuilder();
formulaWithJoin = true;
}
formulaProperties.append(propertyName);
}
public boolean isHasMany() {
return formulaWithJoin || !joins.isEmpty();
}
/**
* Return true if the findRowCount query just needs the id property in the select clause.
*/
public boolean isSelectId() {
return !formulaWithJoin;
}
/**
* Return the formula properties to build the select clause for a findRowCount query.
*/
public String getFormulaProperties() {
return formulaProperties.toString();
}
}
@@ -63,6 +63,11 @@ public final class BeanFkeyProperty implements ElPropertyValue {
public boolean isDeployOnly() {
return true;
}
@Override
public boolean containsFormulaWithJoin() {
return false;
}
/**
* Returns false.
@@ -837,6 +837,12 @@ public class BeanProperty implements ElPropertyValue {
return false;
}
@Override
public boolean containsFormulaWithJoin() {
return formula && sqlFormulaJoin != null;
}
public boolean containsManySince(String sinceProperty) {
return containsMany();
}
@@ -122,7 +122,13 @@ public class ElPropertyChain implements ElPropertyValue {
return false;
}
public boolean containsMany() {
@Override
public boolean containsFormulaWithJoin() {
// Not cascading the check at this stage
return false;
}
public boolean containsMany() {
return containsMany;
}
@@ -17,6 +17,11 @@ public interface ElPropertyDeploy {
*/
public static final String ROOT_ELPREFIX = "${}";
/**
* Return true if the property is a formula with a join clause.
*/
public boolean containsFormulaWithJoin();
/**
* Return true if there is a property on the path that is a many property.
*/
@@ -40,11 +40,18 @@ public abstract class AbstractExpression implements SpiExpression {
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoin) {
String propertyName = getPropertyName();
String propertyName = getPropertyName();
if (propertyName != null){
ElPropertyDeploy elProp = desc.getElPropertyDeploy(propertyName);
if (elProp != null && elProp.containsMany()){
manyWhereJoin.add(elProp);
if (elProp != null) {
if (elProp.containsFormulaWithJoin()) {
// for findRowCount query select clause
manyWhereJoin.addFormulaWithJoin(propertyName);
}
if (elProp.containsMany()){
// for findRowCount we join to a many property
manyWhereJoin.add(elProp);
}
}
}
}
@@ -16,6 +16,7 @@ import com.avaje.ebean.config.dbplatform.SqlLimitRequest;
import com.avaje.ebean.config.dbplatform.SqlLimitResponse;
import com.avaje.ebean.config.dbplatform.SqlLimiter;
import com.avaje.ebean.text.PathProperties;
import com.avaje.ebeaninternal.api.ManyWhereJoins;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.ebeaninternal.server.core.OrmQueryRequest;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
@@ -130,9 +131,16 @@ public class CQueryBuilder implements Constants {
// always set the order by to null for row count query
query.setOrder(null);
boolean hasMany = !query.getManyWhereJoins().isEmpty();
query.setSelectId();
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
query.select(manyWhereJoins.getFormulaProperties());
}
String sqlSelect = "select count(*)";
if (hasMany) {
@@ -108,6 +108,11 @@ public class CtCompoundPropertyElAdapter implements ElPropertyValue {
throw new RuntimeException("Not Supported or Expected");
}
@Override
public boolean containsFormulaWithJoin() {
return false;
}
public boolean containsMany() {
return false;
}