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 {