diff --git a/src/main/java/io/ebeaninternal/server/deploy/FormulaPropertyPath.java b/src/main/java/io/ebeaninternal/server/deploy/FormulaPropertyPath.java index c63d39b3e..df7333c01 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/FormulaPropertyPath.java +++ b/src/main/java/io/ebeaninternal/server/deploy/FormulaPropertyPath.java @@ -8,7 +8,7 @@ import java.sql.Types; class FormulaPropertyPath { - private static final String[] AGG_FUNCTIONS = {"count", "max", "min", "avg"}; + private static final String[] AGG_FUNCTIONS = {"count", "max", "min", "avg", "sum"}; private static final String DISTINCT_ = "distinct "; @@ -118,12 +118,8 @@ class FormulaPropertyPath { } } - String logicalName = (alias == null) ? formula : alias; - BeanProperty targetProperty = null; - if (alias != null) { - targetProperty = descriptor._findBeanProperty(alias); - } - + String logicalName = (alias == null) ? internalExpression : alias; + BeanProperty targetProperty = descriptor._findBeanProperty(logicalName); String parsedAggregation = buildFormula(parsed); return new DynamicPropertyAggregationFormula(logicalName, scalarType, parsedAggregation, isAggregate(), targetProperty, alias); } diff --git a/src/test/java/org/tests/aggregateformula/TestAggregateFormula.java b/src/test/java/org/tests/aggregateformula/TestAggregateFormula.java new file mode 100644 index 000000000..4605e283e --- /dev/null +++ b/src/test/java/org/tests/aggregateformula/TestAggregateFormula.java @@ -0,0 +1,94 @@ +package org.tests.aggregateformula; + +import io.ebean.BaseTestCase; +import io.ebean.Ebean; +import org.ebeantest.LoggedSqlCollector; +import org.junit.Test; +import org.tests.model.basic.Contact; +import org.tests.model.basic.Order; +import org.tests.model.basic.ResetBasicData; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestAggregateFormula extends BaseTestCase { + + @Test + public void sum_withoutAlias() { + + ResetBasicData.reset(); + + LoggedSqlCollector.start(); + + List orders = Ebean.find(Order.class) + .select("status, sum(id)") + .findList(); + + List sql = LoggedSqlCollector.stop(); + assertThat(sql.get(0)).contains("select t0.status, sum(t0.id) from o_order t0 group by t0.status"); + + assertThat(orders).isNotEmpty(); + for (Order order : orders) { + assertThat(order.getStatus()).isNotNull(); + assertThat(order.getId()).isNotNull(); + } + } + + @Test + public void sum_withAlias() { + + ResetBasicData.reset(); + + LoggedSqlCollector.start(); + + List orders = Ebean.find(Order.class) + .select("status, sum(id) as id") + .findList(); + + List sql = LoggedSqlCollector.stop(); + assertThat(sql.get(0)).contains("select t0.status, sum(t0.id) id from o_order t0 group by t0.status"); + + assertThat(orders).isNotEmpty(); + for (Order order : orders) { + assertThat(order.getStatus()).isNotNull(); + assertThat(order.getId()).isNotNull(); + } + } + + @Test + public void sumWithManyToOne_min() { + + ResetBasicData.reset(); + + LoggedSqlCollector.start(); + + List contacts = Ebean.find(Contact.class) + .select("customer, min(cretime)") + .findList(); + + List sql = LoggedSqlCollector.stop(); + assertThat(sql.get(0)).contains("select t0.customer_id, min(t0.cretime) from contact t0 group by t0.customer_id"); + + assertThat(contacts).isNotEmpty(); + } + + @Test + public void sumWithManyToOne_minMax() { + + ResetBasicData.reset(); + + LoggedSqlCollector.start(); + + List contacts = Ebean.find(Contact.class) + .select("customer, min(cretime), max(updtime)") + .findList(); + + List sql = LoggedSqlCollector.stop(); + assertThat(sql.get(0)).contains("select t0.customer_id, min(t0.cretime), max(t0.updtime) from contact t0 group by t0.customer_id"); + + assertThat(contacts).isNotEmpty(); + } + + +} diff --git a/src/test/java/org/tests/model/aggregation/TestAggregationTopLevel.java b/src/test/java/org/tests/model/aggregation/TestAggregationTopLevel.java index 73f693fda..72ace657a 100644 --- a/src/test/java/org/tests/model/aggregation/TestAggregationTopLevel.java +++ b/src/test/java/org/tests/model/aggregation/TestAggregationTopLevel.java @@ -73,6 +73,61 @@ public class TestAggregationTopLevel extends BaseTestCase { assertThat(result).isNotEmpty(); } + @Test + public void groupBy_date_dynamicFormula() { + + Query query = Ebean.find(DMachineStats.class) + .select("date, sum(totalKms), sum(hours)") + .where().gt("date", LocalDate.now().minusDays(10)) + .having().gt("hours", 2) + .query(); + + List result = query.findList(); + assertThat(sqlOf(query)).contains("select t0.date, sum(t0.total_kms), sum(t0.hours) from d_machine_stats t0 where t0.date > ? group by t0.date having t0.hours > ?"); + assertThat(result).isNotEmpty(); + } + + @Test + public void groupBy_MachineAndDate_dynamicFormula() { + + Query query = Ebean.find(DMachineStats.class) + .select("machine, date, max(rate)") + .where().gt("date", LocalDate.now().minusDays(10)) + .query(); + + List result = query.findList(); + assertThat(sqlOf(query)).contains("select t0.machine_id, t0.date, max(t0.rate) from d_machine_stats t0 where t0.date > ? group by t0.machine_id, t0.date"); + assertThat(result).isNotEmpty(); + } + + @Test + public void groupBy_MachineWithJoin_dynamicFormula() { + + Query query = Ebean.find(DMachineStats.class) + .select("max(rate), sum(totalKms)") + .fetch("machine", "name") + .where().gt("date", LocalDate.now().minusDays(10)) + .query(); + + List result = query.findList(); + assertThat(sqlOf(query)).contains("select max(t0.rate), sum(t0.total_kms), t1.id, t1.name from d_machine_stats t0 left join dmachine t1 on t1.id = t0.machine_id where t0.date > ? group by t1.id, t1.name"); + assertThat(result).isNotEmpty(); + } + + @Test + public void groupBy_MachineDateWithJoin_dynamicFormula() { + + Query query = Ebean.find(DMachineStats.class) + .select("machine, date, max(rate), sum(totalKms)") + .fetch("machine", "name") + .where().gt("date", LocalDate.now().minusDays(10)) + .query(); + + List result = query.findList(); + assertThat(sqlOf(query)).contains("select t0.date, max(t0.rate), sum(t0.total_kms), t1.id, t1.name from d_machine_stats t0 left join dmachine t1 on t1.id = t0.machine_id where t0.date > ? group by t0.date, t1.id, t1.name"); + assertThat(result).isNotEmpty(); + } + private static void loadData() { List machines = new ArrayList<>();