From 1ceddf40c0e5f049213fff00caba683d630c5033 Mon Sep 17 00:00:00 2001 From: Donnie Pinkston <donnie@cms.caltech.edu> Date: Wed, 30 Jan 2019 14:44:36 -0800 Subject: [PATCH] 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. --- .../nanodb/functions/StdDevVarAggregate.java | 30 +++++++++---------- .../nanodb/functions/SumAvgAggregate.java | 3 +- .../nanodb/sqlparse/NanoSQLTranslator.java | 6 ++-- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/main/java/edu/caltech/nanodb/functions/StdDevVarAggregate.java b/src/main/java/edu/caltech/nanodb/functions/StdDevVarAggregate.java index 1f8142c..1b9efe5 100755 --- a/src/main/java/edu/caltech/nanodb/functions/StdDevVarAggregate.java +++ b/src/main/java/edu/caltech/nanodb/functions/StdDevVarAggregate.java @@ -49,7 +49,7 @@ public class StdDevVarAggregate extends AggregateFunction { // Store the new value values.add(value); } - + if (sum == null) { // This is the first value. Store it. sum = value; @@ -61,17 +61,18 @@ public class StdDevVarAggregate extends AggregateFunction { } } - + @Override public Object getResult() { if (sum == null || values == null) return null; 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. 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. Object sumSquaresResids = squareDifference(values.get(0), avg); for (int i = 1; i < count; i++) { @@ -79,12 +80,11 @@ public class StdDevVarAggregate extends AggregateFunction { ArithmeticOperator.Type.ADD, sumSquaresResids, squareDifference(values.get(i), avg)); } - + // Compute the variance. Object var = ArithmeticOperator.evalObjects( - ArithmeticOperator.Type.DIVIDE, sumSquaresResids, - Integer.valueOf(count)); - + ArithmeticOperator.Type.DIVIDE, sumSquaresResids, count); + // Compute standard deviation if necessary. if (computeStdDev) { return ArithmeticOperator.evalObjects( @@ -95,8 +95,8 @@ public class StdDevVarAggregate extends AggregateFunction { } } } - - + + @Override public ColumnType getReturnType(List<Expression> args, Schema schema) { if (args.size() != 1) { @@ -109,11 +109,11 @@ public class StdDevVarAggregate extends AggregateFunction { // same type as the values of the column. return args.get(0).getColumnInfo(schema).getType(); } - - - /** + + + /** * Helper function that computes the square of the difference between - * two values. + * two values. */ private Object squareDifference(Object value, Object avg) { return ArithmeticOperator.evalObjects(ArithmeticOperator.Type.POWER, diff --git a/src/main/java/edu/caltech/nanodb/functions/SumAvgAggregate.java b/src/main/java/edu/caltech/nanodb/functions/SumAvgAggregate.java index 5d09a91..d7bfe18 100644 --- a/src/main/java/edu/caltech/nanodb/functions/SumAvgAggregate.java +++ b/src/main/java/edu/caltech/nanodb/functions/SumAvgAggregate.java @@ -91,9 +91,10 @@ public class SumAvgAggregate extends AggregateFunction { return null; } else if (computeAverage) { + // TODO: Need to generate NUMERIC result. Using double right now. // Compute average from the sum and count. return ArithmeticOperator.evalObjects( - ArithmeticOperator.Type.DIVIDE, sum, Integer.valueOf(count)); + ArithmeticOperator.Type.DIVIDE, sum, (double) count); } else { // Just return the sum. diff --git a/src/main/java/edu/caltech/nanodb/sqlparse/NanoSQLTranslator.java b/src/main/java/edu/caltech/nanodb/sqlparse/NanoSQLTranslator.java index d213621..3a7f236 100644 --- a/src/main/java/edu/caltech/nanodb/sqlparse/NanoSQLTranslator.java +++ b/src/main/java/edu/caltech/nanodb/sqlparse/NanoSQLTranslator.java @@ -882,11 +882,11 @@ public class NanoSQLTranslator extends NanoSQLBaseVisitor<Object> { ColumnName colName = ((ColumnValue) e).getColumnName(); if (colName.isColumnWildcard()) functionName += "#STAR"; + else if (distinct) + functionName += "#DISTINCT"; } } - else if (distinct) { - functionName += "#DISTINCT"; - } + // TODO: Report error if someone uses DISTINCT with multiple args. FunctionCall fnCall = new FunctionCall(functionName, distinct, args); if (functionDirectory != null) -- GitLab