Commit 1ceddf40 authored by Donald H. (Donnie) Pinkston, III's avatar Donald H. (Donnie) Pinkston, III
Browse files

Aggregate function bugfixes

A number of bugfixes caused by some of the changes in the arithmetic
type-coercion rules, and the parser-framework changes.

COUNT(DISTINCT a) wasn't being handled correctly due to an issue in
the NanoSQLTranslator flow-control.

The SumAvg/StdDevVar aggregate implementations are now updated to
produce double-precision results when calculating their values.  The
type-converter had been changed to do integer division when the LHS
and RHS are both integers, and this was breaking tests of these
aggregate functions.
parent 0812fe0c
Showing with 20 additions and 19 deletions
+20 -19
...@@ -49,7 +49,7 @@ public class StdDevVarAggregate extends AggregateFunction { ...@@ -49,7 +49,7 @@ public class StdDevVarAggregate extends AggregateFunction {
// Store the new value // Store the new value
values.add(value); values.add(value);
} }
if (sum == null) { if (sum == null) {
// This is the first value. Store it. // This is the first value. Store it.
sum = value; sum = value;
...@@ -61,17 +61,18 @@ public class StdDevVarAggregate extends AggregateFunction { ...@@ -61,17 +61,18 @@ public class StdDevVarAggregate extends AggregateFunction {
} }
} }
@Override @Override
public Object getResult() { public Object getResult() {
if (sum == null || values == null) if (sum == null || values == null)
return null; return null;
else { else {
int count = values.size(); // TODO: Need to generate NUMERIC result. Using double right now.
double count = (double) values.size();
// Compute average from the sum and count. // Compute average from the sum and count.
Object avg = ArithmeticOperator.evalObjects( Object avg = ArithmeticOperator.evalObjects(
ArithmeticOperator.Type.DIVIDE, sum, Integer.valueOf(count)); ArithmeticOperator.Type.DIVIDE, sum, count);
// Compute the sum of the square of the residuals. // Compute the sum of the square of the residuals.
Object sumSquaresResids = squareDifference(values.get(0), avg); Object sumSquaresResids = squareDifference(values.get(0), avg);
for (int i = 1; i < count; i++) { for (int i = 1; i < count; i++) {
...@@ -79,12 +80,11 @@ public class StdDevVarAggregate extends AggregateFunction { ...@@ -79,12 +80,11 @@ public class StdDevVarAggregate extends AggregateFunction {
ArithmeticOperator.Type.ADD, sumSquaresResids, ArithmeticOperator.Type.ADD, sumSquaresResids,
squareDifference(values.get(i), avg)); squareDifference(values.get(i), avg));
} }
// Compute the variance. // Compute the variance.
Object var = ArithmeticOperator.evalObjects( Object var = ArithmeticOperator.evalObjects(
ArithmeticOperator.Type.DIVIDE, sumSquaresResids, ArithmeticOperator.Type.DIVIDE, sumSquaresResids, count);
Integer.valueOf(count));
// Compute standard deviation if necessary. // Compute standard deviation if necessary.
if (computeStdDev) { if (computeStdDev) {
return ArithmeticOperator.evalObjects( return ArithmeticOperator.evalObjects(
...@@ -95,8 +95,8 @@ public class StdDevVarAggregate extends AggregateFunction { ...@@ -95,8 +95,8 @@ public class StdDevVarAggregate extends AggregateFunction {
} }
} }
} }
@Override @Override
public ColumnType getReturnType(List<Expression> args, Schema schema) { public ColumnType getReturnType(List<Expression> args, Schema schema) {
if (args.size() != 1) { if (args.size() != 1) {
...@@ -109,11 +109,11 @@ public class StdDevVarAggregate extends AggregateFunction { ...@@ -109,11 +109,11 @@ public class StdDevVarAggregate extends AggregateFunction {
// same type as the values of the column. // same type as the values of the column.
return args.get(0).getColumnInfo(schema).getType(); return args.get(0).getColumnInfo(schema).getType();
} }
/** /**
* Helper function that computes the square of the difference between * Helper function that computes the square of the difference between
* two values. * two values.
*/ */
private Object squareDifference(Object value, Object avg) { private Object squareDifference(Object value, Object avg) {
return ArithmeticOperator.evalObjects(ArithmeticOperator.Type.POWER, return ArithmeticOperator.evalObjects(ArithmeticOperator.Type.POWER,
......
...@@ -91,9 +91,10 @@ public class SumAvgAggregate extends AggregateFunction { ...@@ -91,9 +91,10 @@ public class SumAvgAggregate extends AggregateFunction {
return null; return null;
} }
else if (computeAverage) { else if (computeAverage) {
// TODO: Need to generate NUMERIC result. Using double right now.
// Compute average from the sum and count. // Compute average from the sum and count.
return ArithmeticOperator.evalObjects( return ArithmeticOperator.evalObjects(
ArithmeticOperator.Type.DIVIDE, sum, Integer.valueOf(count)); ArithmeticOperator.Type.DIVIDE, sum, (double) count);
} }
else { else {
// Just return the sum. // Just return the sum.
......
...@@ -882,11 +882,11 @@ public class NanoSQLTranslator extends NanoSQLBaseVisitor<Object> { ...@@ -882,11 +882,11 @@ public class NanoSQLTranslator extends NanoSQLBaseVisitor<Object> {
ColumnName colName = ((ColumnValue) e).getColumnName(); ColumnName colName = ((ColumnValue) e).getColumnName();
if (colName.isColumnWildcard()) if (colName.isColumnWildcard())
functionName += "#STAR"; functionName += "#STAR";
else if (distinct)
functionName += "#DISTINCT";
} }
} }
else if (distinct) { // TODO: Report error if someone uses DISTINCT with multiple args.
functionName += "#DISTINCT";
}
FunctionCall fnCall = new FunctionCall(functionName, distinct, args); FunctionCall fnCall = new FunctionCall(functionName, distinct, args);
if (functionDirectory != null) if (functionDirectory != null)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment