diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/by/AggregationProcessor.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/by/AggregationProcessor.java index d01f774f6f5..3aef55a0c50 100644 --- a/engine/table/src/main/java/io/deephaven/engine/table/impl/by/AggregationProcessor.java +++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/by/AggregationProcessor.java @@ -127,15 +127,7 @@ import static io.deephaven.engine.table.ChunkSource.WithPrev.ZERO_LENGTH_CHUNK_SOURCE_WITH_PREV_ARRAY; import static io.deephaven.engine.table.Table.AGGREGATION_ROW_LOOKUP_ATTRIBUTE; import static io.deephaven.engine.table.impl.by.IterativeChunkedAggregationOperator.ZERO_LENGTH_ITERATIVE_CHUNKED_AGGREGATION_OPERATOR_ARRAY; -import static io.deephaven.engine.table.impl.by.RollupConstants.ROLLUP_COLUMN_SUFFIX; -import static io.deephaven.engine.table.impl.by.RollupConstants.ROLLUP_DISTINCT_SSM_COLUMN_ID; -import static io.deephaven.engine.table.impl.by.RollupConstants.ROLLUP_NAN_COUNT_COLUMN_ID; -import static io.deephaven.engine.table.impl.by.RollupConstants.ROLLUP_NI_COUNT_COLUMN_ID; -import static io.deephaven.engine.table.impl.by.RollupConstants.ROLLUP_NONNULL_COUNT_COLUMN_ID; -import static io.deephaven.engine.table.impl.by.RollupConstants.ROLLUP_PI_COUNT_COLUMN_ID; -import static io.deephaven.engine.table.impl.by.RollupConstants.ROLLUP_RUNNING_SUM2_COLUMN_ID; -import static io.deephaven.engine.table.impl.by.RollupConstants.ROLLUP_RUNNING_SUM_COLUMN_ID; -import static io.deephaven.engine.table.impl.by.RollupConstants.ROW_REDIRECTION_PREFIX; +import static io.deephaven.engine.table.impl.by.RollupConstants.*; import static io.deephaven.util.QueryConstants.*; import static io.deephaven.util.type.TypeUtils.getBoxedType; import static io.deephaven.util.type.TypeUtils.isNumeric; @@ -584,7 +576,10 @@ final void descendingSortedFirstOrLastUnsupported(@NotNull final SortColumn sort isFirst ? "SortedFirst" : "SortedLast", sortColumn)); } - final void addWeightedAvgOrSumOperator(@NotNull final String weightName, final boolean isSum) { + final void addWeightedAvgOrSumOperator( + @NotNull final String weightName, + final boolean isSum, + final boolean exposeInternal) { final ColumnSource weightSource = table.getColumnSource(weightName); final boolean weightSourceIsFloatingPoint; if (isInteger(weightSource.getChunkType())) { @@ -653,7 +648,7 @@ final void addWeightedAvgOrSumOperator(@NotNull final String weightName, final b } } else { resultOperator = new ChunkedWeightedAverageOperator( - r.source.getChunkType(), doubleWeightOperator, r.pair.output().name()); + r.source.getChunkType(), doubleWeightOperator, r.pair.output().name(), exposeInternal); } addOperator(resultOperator, r.source, r.pair.input().name(), weightName); }); @@ -824,12 +819,12 @@ public void visit(@NotNull final AggSpecUnique unique) { @Override public void visit(@NotNull final AggSpecWAvg wAvg) { - addWeightedAvgOrSumOperator(wAvg.weight().name(), false); + addWeightedAvgOrSumOperator(wAvg.weight().name(), false, false); } @Override public void visit(@NotNull final AggSpecWSum wSum) { - addWeightedAvgOrSumOperator(wSum.weight().name(), true); + addWeightedAvgOrSumOperator(wSum.weight().name(), true, false); } @Override @@ -904,13 +899,6 @@ default void visit(@NotNull final AggSpecPercentile pct) { default void visit(@NotNull final AggSpecTDigest tDigest) { rollupUnsupported("TDigest"); } - - @Override - @FinalDefault - default void visit(@NotNull final AggSpecWAvg wAvg) { - // TODO(deephaven-core#3350): AggWAvg support for rollup() - rollupUnsupported("WAvg", 3350); - } } private static void rollupUnsupported(@NotNull final String operationName) { @@ -1042,7 +1030,14 @@ public void visit(@NotNull final AggSpecUnique unique) { @Override public void visit(@NotNull final AggSpecWSum wSum) { - addWeightedAvgOrSumOperator(wSum.weight().name(), true); + // Weighted sum does not need to expose internal columns to re-aggregate. + addWeightedAvgOrSumOperator(wSum.weight().name(), true, false); + } + + @Override + public void visit(@NotNull final AggSpecWAvg wAvg) { + // Weighted average needs access internal columns to re-aggregate. + addWeightedAvgOrSumOperator(wAvg.weight().name(), false, true); } @Override @@ -1190,6 +1185,12 @@ public void visit(@NotNull final AggSpecWSum wSum) { reaggregateAsSum(); } + @Override + public void visit(@NotNull final AggSpecWAvg wAvg) { + reaggregateWAvgOperator(); + } + + @Override public void visit(@NotNull final AggSpecVar var) { reaggregateStdOrVarOperators(false); @@ -1288,6 +1289,28 @@ private void reaggregateAvgOperator() { } } + private void reaggregateWAvgOperator() { + for (final Pair pair : resultPairs) { + final String resultName = pair.output().name(); + + // Make a recording operator for the sum of weights column + final String sumOfWeightsName = resultName + ROLLUP_SUM_WEIGHTS_COLUMN_ID + ROLLUP_COLUMN_SUFFIX; + final ColumnSource sumOfWeightsSource = table.getColumnSource(sumOfWeightsName); + + final DoubleWeightRecordingInternalOperator doubleWeightOperator = + new DoubleWeightRecordingInternalOperator(sumOfWeightsSource.getChunkType()); + addOperator(doubleWeightOperator, sumOfWeightsSource, resultName, sumOfWeightsName); + + final ColumnSource weightedAveragesSource = table.getColumnSource(resultName); + + // The sum of weights column is directly usable as the weights for the WAvg re-aggregation. + final IterativeChunkedAggregationOperator resultOperator = new ChunkedWeightedAverageOperator( + weightedAveragesSource.getChunkType(), doubleWeightOperator, resultName, true); + + addOperator(resultOperator, weightedAveragesSource, resultName, sumOfWeightsName); + } + } + private void reaggregateStdOrVarOperators(final boolean isStd) { for (final Pair pair : resultPairs) { final String resultName = pair.output().name(); diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/by/ChunkedWeightedAverageOperator.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/by/ChunkedWeightedAverageOperator.java index 6151848afbf..9f36fe874a7 100644 --- a/engine/table/src/main/java/io/deephaven/engine/table/impl/by/ChunkedWeightedAverageOperator.java +++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/by/ChunkedWeightedAverageOperator.java @@ -18,12 +18,16 @@ import org.apache.commons.lang3.mutable.MutableInt; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.Map; +import static io.deephaven.engine.table.impl.by.RollupConstants.*; + class ChunkedWeightedAverageOperator implements IterativeChunkedAggregationOperator { + private final ChunkType chunkType; private final DoubleWeightRecordingInternalOperator weightOperator; private final String resultName; - private final ChunkType chunkType; + private final boolean exposeInternalColumns; private long tableSize; private final LongArraySource normalCount; @@ -32,11 +36,15 @@ class ChunkedWeightedAverageOperator implements IterativeChunkedAggregationOpera private final DoubleArraySource weightedSum; private final DoubleArraySource resultColumn; - ChunkedWeightedAverageOperator(ChunkType chunkType, DoubleWeightRecordingInternalOperator weightOperator, - String name) { + ChunkedWeightedAverageOperator( + ChunkType chunkType, + DoubleWeightRecordingInternalOperator weightOperator, + String name, + boolean exposeInternalColumns) { this.chunkType = chunkType; this.weightOperator = weightOperator; this.resultName = name; + this.exposeInternalColumns = exposeInternalColumns; tableSize = 0; normalCount = new LongArraySource(); @@ -416,12 +424,22 @@ public void ensureCapacity(long tableSize) { @Override public Map> getResultColumns() { - return Collections.singletonMap(resultName, resultColumn); + if (exposeInternalColumns) { + final Map> results = new LinkedHashMap<>(2); + results.put(resultName, resultColumn); + results.put(resultName + ROLLUP_SUM_WEIGHTS_COLUMN_ID + ROLLUP_COLUMN_SUFFIX, sumOfWeights); + return results; + } else { + return Collections.singletonMap(resultName, resultColumn); + } } @Override public void startTrackingPrevValues() { resultColumn.startTrackingPrevValues(); + if (exposeInternalColumns) { + sumOfWeights.startTrackingPrevValues(); + } } private class Context implements BucketedContext, SingletonContext { diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/by/RollupConstants.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/by/RollupConstants.java index 74ebd8fa93c..8a0f2b6e217 100644 --- a/engine/table/src/main/java/io/deephaven/engine/table/impl/by/RollupConstants.java +++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/by/RollupConstants.java @@ -32,6 +32,12 @@ private RollupConstants() {} */ static final String ROLLUP_RUNNING_SUM_COLUMN_ID = "_RS_"; + /** + * Middle column name component (between source column name and {@link #ROLLUP_COLUMN_SUFFIX suffix}) for sum of + * weights columns used in rollup wavg aggregations. + */ + static final String ROLLUP_SUM_WEIGHTS_COLUMN_ID = "_RSW_"; + /** * Middle column name component (between source column name and {@link #ROLLUP_COLUMN_SUFFIX suffix}) for running * sum of squares columns used in rollup aggregations. diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/by/WeightedAverageOperator.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/by/WeightedAverageOperator.java deleted file mode 100644 index c527ad9cb92..00000000000 --- a/engine/table/src/main/java/io/deephaven/engine/table/impl/by/WeightedAverageOperator.java +++ /dev/null @@ -1,433 +0,0 @@ -/** - * Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending - */ -package io.deephaven.engine.table.impl.by; - -import io.deephaven.engine.table.ColumnSource; -import io.deephaven.engine.table.WritableColumnSource; -import io.deephaven.util.QueryConstants; -import io.deephaven.util.type.TypeUtils; - -class WeightedAverageOperator { - interface Operator { - State getState(long resultKey); - - Class getResultType(); - - void setDestination(WritableColumnSource columnSource); - } - - interface State { - void addValue(long key); - - void addPrevValue(long key); - - void removeValue(long prevKey); - - void updateResult(); - } - - @SuppressWarnings("unchecked") - static Operator getOperator(ColumnSource components, ColumnSource weights) { - Class componentType = (Class) io.deephaven.util.type.TypeUtils.getBoxedType(components.getType()); - Class weightType = (Class) TypeUtils.getBoxedType(weights.getType()); - - if (componentType == Double.class) - return getDoubleOperator(weightType, (ColumnSource) components, weights); - if (componentType == Float.class) - return getFloatOperator(weightType, (ColumnSource) components, weights); - if (componentType == Character.class) - return getCharOperator(weightType, (ColumnSource) components, weights); - if (componentType == Byte.class) - return getByteOperator(weightType, (ColumnSource) components, weights); - if (componentType == Short.class) - return getShortOperator(weightType, (ColumnSource) components, weights); - if (componentType == Integer.class) - return getIntegerOperator(weightType, (ColumnSource) components, weights); - if (componentType == Long.class) - return getLongOperator(weightType, (ColumnSource) components, weights); - - throw new UnsupportedOperationException( - "Can not perform a weighted average with component type: " + componentType); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private static Operator getDoubleOperator(Class weightType, ColumnSource components, - ColumnSource weights) { - if (weightType == Double.class) - return new OperatorImpl(new DoubleGetter(components), new DoubleGetter(weights)); - if (weightType == Float.class) - return new OperatorImpl(new DoubleGetter(components), new FloatGetter(weights)); - if (weightType == Character.class) - return new OperatorImpl(new DoubleGetter(components), new CharGetter(weights)); - if (weightType == Byte.class) - return new OperatorImpl(new DoubleGetter(components), new ByteGetter(weights)); - if (weightType == Short.class) - return new OperatorImpl(new DoubleGetter(components), new ShortGetter(weights)); - if (weightType == Integer.class) - return new OperatorImpl(new DoubleGetter(components), new IntegerGetter(weights)); - if (weightType == Long.class) - return new OperatorImpl(new DoubleGetter(components), new LongGetter(weights)); - - throw new UnsupportedOperationException("Can not perform a weighted average with weight type: " + weightType); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private static Operator getFloatOperator(Class weightType, ColumnSource components, - ColumnSource weights) { - if (weightType == Double.class) - return new OperatorImpl(new FloatGetter(components), new DoubleGetter(weights)); - if (weightType == Float.class) - return new OperatorImpl(new FloatGetter(components), new FloatGetter(weights)); - if (weightType == Character.class) - return new OperatorImpl(new FloatGetter(components), new CharGetter(weights)); - if (weightType == Byte.class) - return new OperatorImpl(new FloatGetter(components), new ByteGetter(weights)); - if (weightType == Short.class) - return new OperatorImpl(new FloatGetter(components), new ShortGetter(weights)); - if (weightType == Integer.class) - return new OperatorImpl(new FloatGetter(components), new IntegerGetter(weights)); - if (weightType == Long.class) - return new OperatorImpl(new FloatGetter(components), new LongGetter(weights)); - - throw new UnsupportedOperationException("Can not perform a weighted average with weight type: " + weightType); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private static Operator getCharOperator(Class weightType, ColumnSource components, - ColumnSource weights) { - if (weightType == Double.class) - return new OperatorImpl(new CharGetter(components), new DoubleGetter(weights)); - if (weightType == Float.class) - return new OperatorImpl(new CharGetter(components), new FloatGetter(weights)); - if (weightType == Character.class) - return new OperatorImpl(new CharGetter(components), new CharGetter(weights)); - if (weightType == Byte.class) - return new OperatorImpl(new CharGetter(components), new ByteGetter(weights)); - if (weightType == Short.class) - return new OperatorImpl(new CharGetter(components), new ShortGetter(weights)); - if (weightType == Integer.class) - return new OperatorImpl(new CharGetter(components), new IntegerGetter(weights)); - if (weightType == Long.class) - return new OperatorImpl(new CharGetter(components), new LongGetter(weights)); - - throw new UnsupportedOperationException("Can not perform a weighted average with weight type: " + weightType); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private static Operator getByteOperator(Class weightType, ColumnSource components, ColumnSource weights) { - if (weightType == Double.class) - return new OperatorImpl(new ByteGetter(components), new DoubleGetter(weights)); - if (weightType == Float.class) - return new OperatorImpl(new ByteGetter(components), new FloatGetter(weights)); - if (weightType == Character.class) - return new OperatorImpl(new ByteGetter(components), new CharGetter(weights)); - if (weightType == Byte.class) - return new OperatorImpl(new ByteGetter(components), new ByteGetter(weights)); - if (weightType == Short.class) - return new OperatorImpl(new ByteGetter(components), new ShortGetter(weights)); - if (weightType == Integer.class) - return new OperatorImpl(new ByteGetter(components), new IntegerGetter(weights)); - if (weightType == Long.class) - return new OperatorImpl(new ByteGetter(components), new LongGetter(weights)); - - throw new UnsupportedOperationException("Can not perform a weighted average with weight type: " + weightType); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private static Operator getShortOperator(Class weightType, ColumnSource components, - ColumnSource weights) { - if (weightType == Double.class) - return new OperatorImpl(new ShortGetter(components), new DoubleGetter(weights)); - if (weightType == Float.class) - return new OperatorImpl(new ShortGetter(components), new FloatGetter(weights)); - if (weightType == Character.class) - return new OperatorImpl(new ShortGetter(components), new CharGetter(weights)); - if (weightType == Byte.class) - return new OperatorImpl(new ShortGetter(components), new ByteGetter(weights)); - if (weightType == Short.class) - return new OperatorImpl(new ShortGetter(components), new ShortGetter(weights)); - if (weightType == Integer.class) - return new OperatorImpl(new ShortGetter(components), new IntegerGetter(weights)); - if (weightType == Long.class) - return new OperatorImpl(new ShortGetter(components), new LongGetter(weights)); - - throw new UnsupportedOperationException("Can not perform a weighted average with weight type: " + weightType); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private static Operator getIntegerOperator(Class weightType, ColumnSource components, - ColumnSource weights) { - if (weightType == Double.class) - return new OperatorImpl(new IntegerGetter(components), new DoubleGetter(weights)); - if (weightType == Float.class) - return new OperatorImpl(new IntegerGetter(components), new FloatGetter(weights)); - if (weightType == Character.class) - return new OperatorImpl(new IntegerGetter(components), new CharGetter(weights)); - if (weightType == Byte.class) - return new OperatorImpl(new IntegerGetter(components), new ByteGetter(weights)); - if (weightType == Short.class) - return new OperatorImpl(new IntegerGetter(components), new ShortGetter(weights)); - if (weightType == Integer.class) - return new OperatorImpl(new IntegerGetter(components), new IntegerGetter(weights)); - if (weightType == Long.class) - return new OperatorImpl(new IntegerGetter(components), new LongGetter(weights)); - - throw new UnsupportedOperationException("Can not perform a weighted average with weight type: " + weightType); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private static Operator getLongOperator(Class weightType, ColumnSource components, ColumnSource weights) { - if (weightType == Double.class) - return new OperatorImpl(new LongGetter(components), new DoubleGetter(weights)); - if (weightType == Float.class) - return new OperatorImpl(new LongGetter(components), new FloatGetter(weights)); - if (weightType == Character.class) - return new OperatorImpl(new LongGetter(components), new CharGetter(weights)); - if (weightType == Byte.class) - return new OperatorImpl(new LongGetter(components), new ByteGetter(weights)); - if (weightType == Short.class) - return new OperatorImpl(new LongGetter(components), new ShortGetter(weights)); - if (weightType == Integer.class) - return new OperatorImpl(new LongGetter(components), new IntegerGetter(weights)); - if (weightType == Long.class) - return new OperatorImpl(new LongGetter(components), new LongGetter(weights)); - - throw new UnsupportedOperationException("Can not perform a weighted average with weight type: " + weightType); - } - - private interface ValueGetter { - double get(long key); - - double getPrev(long key); - } - - private static class OperatorImpl implements Operator { - private WritableColumnSource dest; - private final ValueGetter componentGetter; - private final ValueGetter weightGetter; - - OperatorImpl(ValueGetter componentGetter, ValueGetter weightGetter) { - this.componentGetter = componentGetter; - this.weightGetter = weightGetter; - } - - @Override - public State getState(long resultKey) { - return new State(resultKey); - } - - @Override - public Class getResultType() { - return double.class; - } - - @Override - public void setDestination(WritableColumnSource dest) { - this.dest = dest; - } - - private class State implements WeightedAverageOperator.State { - double weightedSum; - double sumOfWeights; - double nanCount; - double nonNullCount; - private final long resultIndex; - - State(long resultIndex) { - this.resultIndex = resultIndex; - } - - @Override - public void addValue(long key) { - doAdd(componentGetter.get(key), weightGetter.get(key)); - } - - @Override - public void addPrevValue(long key) { - doAdd(componentGetter.getPrev(key), weightGetter.getPrev(key)); - } - - private void doAdd(double component, double weight) { - if (Double.isNaN(component) || Double.isNaN(weight)) { - nanCount++; - return; - } - if (component == QueryConstants.NULL_DOUBLE || weight == QueryConstants.NULL_DOUBLE) { - return; - } - weightedSum += (component * weight); - sumOfWeights += weight; - nonNullCount++; - } - - @Override - public void removeValue(long key) { - final double component = componentGetter.getPrev(key); - final double weight = weightGetter.getPrev(key); - - if (Double.isNaN(component) || Double.isNaN(weight)) { - nanCount--; - return; - } - if (component == QueryConstants.NULL_DOUBLE || weight == QueryConstants.NULL_DOUBLE) { - return; - } - weightedSum -= (component * weight); - sumOfWeights -= weight; - nonNullCount--; - } - - private double getResult() { - if (nanCount > 0) - return Double.NaN; - if (nonNullCount == 0) - return QueryConstants.NULL_DOUBLE; - return weightedSum / sumOfWeights; - } - - @Override - public void updateResult() { - dest.set(resultIndex, getResult()); - } - } - } - - private static class DoubleGetter implements ValueGetter { - private final ColumnSource columnSource; - - private DoubleGetter(ColumnSource columnSource) { - this.columnSource = columnSource; - } - - @Override - public double get(long key) { - return columnSource.getDouble(key); - } - - @Override - public double getPrev(long key) { - return columnSource.getPrevDouble(key); - } - } - - private static class FloatGetter implements ValueGetter { - private final ColumnSource columnSource; - - private FloatGetter(ColumnSource columnSource) { - this.columnSource = columnSource; - } - - @Override - public double get(long key) { - final float aFloat = columnSource.getFloat(key); - return aFloat == QueryConstants.NULL_FLOAT ? QueryConstants.NULL_DOUBLE : aFloat; - } - - @Override - public double getPrev(long key) { - final float aFloat = columnSource.getPrevFloat(key); - return aFloat == QueryConstants.NULL_FLOAT ? QueryConstants.NULL_DOUBLE : aFloat; - } - } - - private static class CharGetter implements ValueGetter { - private final ColumnSource columnSource; - - private CharGetter(ColumnSource columnSource) { - this.columnSource = columnSource; - } - - @Override - public double get(long key) { - final char aChar = columnSource.getChar(key); - return aChar == QueryConstants.NULL_CHAR ? QueryConstants.NULL_DOUBLE : aChar; - } - - @Override - public double getPrev(long key) { - final char aChar = columnSource.getPrevChar(key); - return aChar == QueryConstants.NULL_CHAR ? QueryConstants.NULL_DOUBLE : aChar; - } - } - - private static class ByteGetter implements ValueGetter { - private final ColumnSource columnSource; - - private ByteGetter(ColumnSource columnSource) { - this.columnSource = columnSource; - } - - @Override - public double get(long key) { - final byte aByte = columnSource.getByte(key); - return aByte == QueryConstants.NULL_BYTE ? QueryConstants.NULL_DOUBLE : aByte; - } - - @Override - public double getPrev(long key) { - final byte aByte = columnSource.getPrevByte(key); - return aByte == QueryConstants.NULL_BYTE ? QueryConstants.NULL_DOUBLE : aByte; - } - } - - private static class ShortGetter implements ValueGetter { - private final ColumnSource columnSource; - - private ShortGetter(ColumnSource columnSource) { - this.columnSource = columnSource; - } - - @Override - public double get(long key) { - final short aShort = columnSource.getShort(key); - return aShort == QueryConstants.NULL_SHORT ? QueryConstants.NULL_DOUBLE : aShort; - } - - @Override - public double getPrev(long key) { - final short aShort = columnSource.getPrevShort(key); - return aShort == QueryConstants.NULL_SHORT ? QueryConstants.NULL_DOUBLE : aShort; - } - } - - private static class IntegerGetter implements ValueGetter { - private final ColumnSource columnSource; - - private IntegerGetter(ColumnSource columnSource) { - this.columnSource = columnSource; - } - - @Override - public double get(long key) { - final int anInt = columnSource.getInt(key); - return anInt == QueryConstants.NULL_INT ? QueryConstants.NULL_DOUBLE : anInt; - } - - @Override - public double getPrev(long key) { - final int anInt = columnSource.getPrevInt(key); - return anInt == QueryConstants.NULL_INT ? QueryConstants.NULL_DOUBLE : anInt; - } - } - - private static class LongGetter implements ValueGetter { - private final ColumnSource columnSource; - - private LongGetter(ColumnSource columnSource) { - this.columnSource = columnSource; - } - - @Override - public double get(long key) { - final long aLong = columnSource.getLong(key); - return aLong == QueryConstants.NULL_INT ? QueryConstants.NULL_DOUBLE : aLong; - } - - @Override - public double getPrev(long key) { - final long aLong = columnSource.getPrevLong(key); - return aLong == QueryConstants.NULL_INT ? QueryConstants.NULL_DOUBLE : aLong; - } - } -} diff --git a/py/server/tests/test_table.py b/py/server/tests/test_table.py index 334d9415a3c..b2392e84591 100644 --- a/py/server/tests/test_table.py +++ b/py/server/tests/test_table.py @@ -50,12 +50,12 @@ def setUp(self): sum_(["aggSum=var"]), abs_sum(["aggAbsSum=var"]), var(["aggVar=var"]), + weighted_avg("var", ["weights"]), ] self.aggs_not_for_rollup = [group(["aggGroup=var"]), partition("aggPartition"), median(["aggMed=var"]), pct(0.20, ["aggPct=var"]), - weighted_avg("var", ["weights"]), ] self.aggs = self.aggs_for_rollup + self.aggs_not_for_rollup self.test_update_graph = get_exec_ctx().update_graph