This is an automated email from the ASF dual-hosted git repository.

yanlin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/master by this push:
     new 1e6b742  [CALCITE-4374] Support materialized view recognition when 
query distinct aggregate on target GROUP BY columns (xzh)
1e6b742 is described below

commit 1e6b7425ec20e2bddc6331a21016475a43f9d995
Author: xzh <[email protected]>
AuthorDate: Tue Nov 3 17:22:38 2020 +0800

    [CALCITE-4374] Support materialized view recognition when query distinct 
aggregate on target GROUP BY columns (xzh)
---
 .../apache/calcite/plan/SubstitutionVisitor.java   | 17 ++++++--
 .../MaterializedViewSubstitutionVisitorTest.java   | 51 ++++++++++++++++++++++
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java 
b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
index 2fe5b88..6d5cac7 100644
--- a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
+++ b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
@@ -1895,10 +1895,9 @@ public class SubstitutionVisitor {
       // Same level of aggregation. Generate a project.
       final List<Integer> projects = new ArrayList<>();
       final int groupCount = query.groupSet.cardinality();
-      final List<Integer> targetGroupList = target.groupSet.asList();
       for (Integer inputIndex : query.groupSet.asList()) {
         // Use the index in target group by.
-        int i = targetGroupList.indexOf(inputIndex);
+        int i = targetGroupByIndexList.indexOf(inputIndex);
         projects.add(i);
       }
       for (AggregateCall aggregateCall : query.aggCalls) {
@@ -1930,7 +1929,19 @@ public class SubstitutionVisitor {
       }
       final List<AggregateCall> aggregateCalls = new ArrayList<>();
       for (AggregateCall aggregateCall : query.aggCalls) {
-        if (aggregateCall.isDistinct()) {
+        if (aggregateCall.isDistinct() && aggregateCall.getArgList().size() == 
1) {
+          final int aggIndex = aggregateCall.getArgList().get(0);
+          final int newIndex = targetGroupByIndexList.indexOf(aggIndex);
+          if (newIndex >= 0) {
+            aggregateCalls.add(
+                AggregateCall.create(aggregateCall.getAggregation(),
+                    aggregateCall.isDistinct(), aggregateCall.isApproximate(),
+                    aggregateCall.ignoreNulls(),
+                    ImmutableList.of(newIndex), -1,
+                    aggregateCall.collation, aggregateCall.type,
+                    aggregateCall.name));
+            continue;
+          }
           return null;
         }
         int i = target.aggCalls.indexOf(aggregateCall);
diff --git 
a/core/src/test/java/org/apache/calcite/test/MaterializedViewSubstitutionVisitorTest.java
 
b/core/src/test/java/org/apache/calcite/test/MaterializedViewSubstitutionVisitorTest.java
index dab21cd..464ce3f 100644
--- 
a/core/src/test/java/org/apache/calcite/test/MaterializedViewSubstitutionVisitorTest.java
+++ 
b/core/src/test/java/org/apache/calcite/test/MaterializedViewSubstitutionVisitorTest.java
@@ -1515,6 +1515,57 @@ public class MaterializedViewSubstitutionVisitorTest 
extends AbstractMaterialize
         .ok();
   }
 
+  @Test void testQueryDistinctColumnInTargetGroupByList0() {
+    final String mv = ""
+        + "select \"name\", \"commission\", \"deptno\"\n"
+        + "from \"emps\" group by \"name\", \"commission\", \"deptno\"";
+    final String query = ""
+        + "select \"name\", \"commission\", count(distinct \"deptno\") as 
cnt\n"
+        + "from \"emps\" group by \"name\", \"commission\"";
+    sql(mv, query).ok();
+  }
+
+  @Test void testQueryDistinctColumnInTargetGroupByList1() {
+    final String mv = ""
+        + "select \"name\", \"deptno\" "
+        + "from \"emps\" group by \"name\", \"deptno\"";
+    final String query = ""
+        + "select \"name\", count(distinct \"deptno\")\n"
+        + "from \"emps\" group by \"name\"";
+    sql(mv, query).ok();
+  }
+
+  @Test void testQueryDistinctColumnInTargetGroupByList2() {
+    final String mv = ""
+        + "select \"name\", \"deptno\", \"empid\"\n"
+        + "from \"emps\" group by \"name\", \"deptno\", \"empid\"";
+    final String query = ""
+        + "select \"name\", count(distinct \"deptno\"), count(distinct 
\"empid\")\n"
+        + "from \"emps\" group by \"name\"";
+    sql(mv, query).ok();
+  }
+
+  @Test void testQueryDistinctColumnInTargetGroupByList3() {
+    final String mv = ""
+        + "select \"name\", \"deptno\", \"empid\", count(\"commission\")\n"
+        + "from \"emps\" group by \"name\", \"deptno\", \"empid\"";
+    final String query = ""
+        + "select \"name\", count(distinct \"deptno\"), count(distinct 
\"empid\"), count"
+        + "(\"commission\")\n"
+        + "from \"emps\" group by \"name\"";
+    sql(mv, query).ok();
+  }
+
+  @Test void testQueryDistinctColumnInTargetGroupByList4() {
+    final String mv = ""
+        + "select \"name\", \"deptno\", \"empid\"\n"
+        + "from \"emps\" group by \"name\", \"deptno\", \"empid\"";
+    final String query = ""
+        + "select \"name\", count(distinct \"deptno\")\n"
+        + "from \"emps\" group by \"name\"";
+    sql(mv, query).ok();
+  }
+
   final JavaTypeFactoryImpl typeFactory =
       new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
   private final RexBuilder rexBuilder = new RexBuilder(typeFactory);

Reply via email to