You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2016/10/12 00:00:14 UTC
[8/8] calcite git commit: [CALCITE-1404] Implement FILTER on
aggregate functions in Interpreter
[CALCITE-1404] Implement FILTER on aggregate functions in Interpreter
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/92b3d381
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/92b3d381
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/92b3d381
Branch: refs/heads/master
Commit: 92b3d381de4c0f6670cff06d54ce06b8231e6684
Parents: 0f2d666
Author: Julian Hyde <jh...@apache.org>
Authored: Mon Oct 10 16:47:03 2016 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Tue Oct 11 16:13:43 2016 -0700
----------------------------------------------------------------------
.../calcite/interpreter/AggregateNode.java | 36 ++++++++++++++++++--
.../apache/calcite/test/InterpreterTest.java | 17 +++++++++
2 files changed, 51 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/92b3d381/core/src/main/java/org/apache/calcite/interpreter/AggregateNode.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/interpreter/AggregateNode.java b/core/src/main/java/org/apache/calcite/interpreter/AggregateNode.java
index 835c7e3..1cffac4 100644
--- a/core/src/main/java/org/apache/calcite/interpreter/AggregateNode.java
+++ b/core/src/main/java/org/apache/calcite/interpreter/AggregateNode.java
@@ -83,7 +83,7 @@ public class AggregateNode extends AbstractSingleNode<Aggregate> {
ImmutableList.Builder<AccumulatorFactory> builder = ImmutableList.builder();
for (AggregateCall aggregateCall : rel.getAggCallList()) {
- builder.add(getAccumulator(aggregateCall));
+ builder.add(getAccumulator(aggregateCall, false));
}
accumulatorFactories = builder.build();
}
@@ -101,7 +101,17 @@ public class AggregateNode extends AbstractSingleNode<Aggregate> {
}
}
- private AccumulatorFactory getAccumulator(final AggregateCall call) {
+ private AccumulatorFactory getAccumulator(final AggregateCall call,
+ boolean ignoreFilter) {
+ if (call.filterArg >= 0 && !ignoreFilter) {
+ final AccumulatorFactory factory = getAccumulator(call, true);
+ return new AccumulatorFactory() {
+ public Accumulator get() {
+ final Accumulator accumulator = factory.get();
+ return new FilterAccumulator(accumulator, call.filterArg);
+ }
+ };
+ }
if (call.getAggregation() == SqlStdOperatorTable.COUNT) {
return new AccumulatorFactory() {
public Accumulator get() {
@@ -488,6 +498,28 @@ public class AggregateNode extends AbstractSingleNode<Aggregate> {
}
}
}
+
+ /** Accumulator that applies a filter to another accumulator.
+ * The filter is a BOOLEAN field in the input row. */
+ private static class FilterAccumulator implements Accumulator {
+ private final Accumulator accumulator;
+ private final int filterArg;
+
+ FilterAccumulator(Accumulator accumulator, int filterArg) {
+ this.accumulator = accumulator;
+ this.filterArg = filterArg;
+ }
+
+ public void send(Row row) {
+ if (row.getValues()[filterArg] == Boolean.TRUE) {
+ accumulator.send(row);
+ }
+ }
+
+ public Object end() {
+ return accumulator.end();
+ }
+ }
}
// End AggregateNode.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/92b3d381/core/src/test/java/org/apache/calcite/test/InterpreterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/InterpreterTest.java b/core/src/test/java/org/apache/calcite/test/InterpreterTest.java
index fc360e1..1227917 100644
--- a/core/src/test/java/org/apache/calcite/test/InterpreterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/InterpreterTest.java
@@ -205,6 +205,23 @@ public class InterpreterTest {
"[Ringo, 1]");
}
+ @Test public void testAggregateGroupFilter() throws Exception {
+ rootSchema.add("beatles", new ScannableTableTest.BeatlesTable());
+ final String sql = "select \"j\",\n"
+ + " count(*) filter (where char_length(\"j\") > 4)\n"
+ + "from \"beatles\" group by \"j\"";
+ SqlNode parse = planner.parse(sql);
+ SqlNode validate = planner.validate(parse);
+ RelNode convert = planner.rel(validate).rel;
+
+ final Interpreter interpreter = new Interpreter(dataContext, convert);
+ assertRowsUnordered(interpreter,
+ "[George, 1]",
+ "[Paul, 0]",
+ "[John, 0]",
+ "[Ringo, 1]");
+ }
+
/** Tests executing a plan on a single-column
* {@link org.apache.calcite.schema.ScannableTable} using an interpreter. */
@Test public void testInterpretSimpleScannableTable() throws Exception {