diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/tables/aggregate/Aggregate.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/tables/aggregate/Aggregate.java index 5598f154..c6001695 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/tables/aggregate/Aggregate.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/tables/aggregate/Aggregate.java @@ -24,15 +24,18 @@ package com.kingsrook.qqq.backend.core.model.actions.tables.aggregate; import java.io.Serializable; import java.util.Objects; +import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType; /******************************************************************************* - ** + ** Define an "aggregate", e.g., to be selected in an Aggregate action. + ** Such as SUM(cost). *******************************************************************************/ public class Aggregate implements Serializable { private String fieldName; private AggregateOperator operator; + private QFieldType fieldType; @@ -55,12 +58,14 @@ public class Aggregate implements Serializable { return true; } + if(o == null || getClass() != o.getClass()) { return false; } + Aggregate aggregate = (Aggregate) o; - return Objects.equals(fieldName, aggregate.fieldName) && operator == aggregate.operator; + return Objects.equals(fieldName, aggregate.fieldName) && operator == aggregate.operator && fieldType == aggregate.fieldType; } @@ -71,7 +76,7 @@ public class Aggregate implements Serializable @Override public int hashCode() { - return Objects.hash(fieldName, operator); + return Objects.hash(fieldName, operator, fieldType); } @@ -153,4 +158,35 @@ public class Aggregate implements Serializable return (this); } + + + /******************************************************************************* + ** Getter for fieldType + *******************************************************************************/ + public QFieldType getFieldType() + { + return (this.fieldType); + } + + + + /******************************************************************************* + ** Setter for fieldType + *******************************************************************************/ + public void setFieldType(QFieldType fieldType) + { + this.fieldType = fieldType; + } + + + + /******************************************************************************* + ** Fluent setter for fieldType + *******************************************************************************/ + public Aggregate withFieldType(QFieldType fieldType) + { + this.fieldType = fieldType; + return (this); + } + } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/columnstats/ColumnStatsStep.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/columnstats/ColumnStatsStep.java index 40777447..24efecdb 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/columnstats/ColumnStatsStep.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/columnstats/ColumnStatsStep.java @@ -108,7 +108,7 @@ public class ColumnStatsStep implements BackendStep //////////////////////////////////////////// // do a count query grouped by this field // //////////////////////////////////////////// - Aggregate aggregate = new Aggregate(table.getPrimaryKeyField(), AggregateOperator.COUNT); + Aggregate aggregate = new Aggregate(table.getPrimaryKeyField(), AggregateOperator.COUNT).withFieldType(QFieldType.DECIMAL); GroupBy groupBy = new GroupBy(field.getType(), fieldName); if(StringUtils.hasContent(orderBy)) @@ -171,7 +171,7 @@ public class ColumnStatsStep implements BackendStep QFieldMetaData countNonNullField = new QFieldMetaData("count", QFieldType.INTEGER).withLabel("Rows with a value").withDisplayFormat(DisplayFormat.COMMAS); QFieldMetaData countDistinctField = new QFieldMetaData("countDistinct", QFieldType.INTEGER).withLabel("Distinct values").withDisplayFormat(DisplayFormat.COMMAS); QFieldMetaData sumField = new QFieldMetaData("sum", QFieldType.DECIMAL).withDisplayFormat(field.getDisplayFormat()); - QFieldMetaData avgField = new QFieldMetaData("average", QFieldType.DECIMAL).withDisplayFormat(field.getDisplayFormat()); + QFieldMetaData avgField = new QFieldMetaData("average", QFieldType.DECIMAL).withDisplayFormat(DisplayFormat.DECIMAL2_COMMAS); QFieldMetaData minField = new QFieldMetaData("min", field.getType()).withDisplayFormat(field.getDisplayFormat()); QFieldMetaData maxField = new QFieldMetaData("max", field.getType()).withDisplayFormat(field.getDisplayFormat()); @@ -205,6 +205,11 @@ public class ColumnStatsStep implements BackendStep doMax = false; } + if(field.getName().equals(table.getPrimaryKeyField())) + { + doSum = false; + } + ArrayList fields = new ArrayList<>(); fields.add(countNonNullField); fields.add(countDistinctField); @@ -233,10 +238,13 @@ public class ColumnStatsStep implements BackendStep doCountDistinct = false; } - Aggregate countNonNullAggregate = new Aggregate(fieldName, AggregateOperator.COUNT); - Aggregate countDistinctAggregate = new Aggregate(fieldName, AggregateOperator.COUNT_DISTINCT); - Aggregate sumAggregate = new Aggregate(fieldName, AggregateOperator.SUM); - Aggregate avgAggregate = new Aggregate(fieldName, AggregateOperator.AVG); + ///////////////////////////////////////////////////////////////////////////////// + // just in case any of these don't fit in an integer, use decimal for them all // + ///////////////////////////////////////////////////////////////////////////////// + Aggregate countNonNullAggregate = new Aggregate(fieldName, AggregateOperator.COUNT).withFieldType(QFieldType.DECIMAL); + Aggregate countDistinctAggregate = new Aggregate(fieldName, AggregateOperator.COUNT_DISTINCT).withFieldType(QFieldType.DECIMAL); + Aggregate sumAggregate = new Aggregate(fieldName, AggregateOperator.SUM).withFieldType(QFieldType.DECIMAL); + Aggregate avgAggregate = new Aggregate(fieldName, AggregateOperator.AVG).withFieldType(QFieldType.DECIMAL); Aggregate minAggregate = new Aggregate(fieldName, AggregateOperator.MIN); Aggregate maxAggregate = new Aggregate(fieldName, AggregateOperator.MAX); AggregateInput statsAggregateInput = new AggregateInput(); diff --git a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSAggregateAction.java b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSAggregateAction.java index ab4a1222..b7ba77ea 100644 --- a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSAggregateAction.java +++ b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSAggregateAction.java @@ -119,14 +119,18 @@ public class RDBMSAggregateAction extends AbstractRDBMSAction implements Aggrega JoinsContext.FieldAndTableNameOrAlias fieldAndTableNameOrAlias = joinsContext.getFieldAndTableNameOrAlias(aggregate.getFieldName()); QFieldMetaData field = fieldAndTableNameOrAlias.field(); - if(field.getType().equals(QFieldType.INTEGER) && (aggregate.getOperator().equals(AggregateOperator.AVG) || aggregate.getOperator().equals(AggregateOperator.SUM))) + QFieldType fieldType = aggregate.getFieldType(); + if(fieldType == null) { - field = new QFieldMetaData().withType(QFieldType.DECIMAL); + if(field.getType().equals(QFieldType.INTEGER) && (aggregate.getOperator().equals(AggregateOperator.AVG))) + { + fieldType = QFieldType.DECIMAL; + } } - if(aggregate.getOperator().equals(AggregateOperator.COUNT) || aggregate.getOperator().equals(AggregateOperator.COUNT_DISTINCT)) + if(fieldType != null) { - field = new QFieldMetaData().withType(QFieldType.DECIMAL); + field = new QFieldMetaData().withType(fieldType); } Serializable value = getFieldValueFromResultSet(field, resultSet, selectionIndex++);