Let caller specify type to use for an aggregate expression

This commit is contained in:
2023-03-16 11:38:26 -05:00
parent 939dcc308c
commit b16eaca394
3 changed files with 61 additions and 13 deletions

View File

@ -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);
}
}

View File

@ -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<QFieldMetaData> 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();

View File

@ -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++);