You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by hy...@apache.org on 2019/06/30 20:27:59 UTC

[calcite] 02/04: address reviews

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

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

commit cebaa2d91d88e59f44123f2a2344103996054ca4
Author: Zhenghua Gao <do...@gmail.com>
AuthorDate: Fri Jun 28 12:12:30 2019 +0800

    address reviews
---
 .../calcite/rel/metadata/RelMdCollation.java       | 121 ++++++++++-----------
 .../org/apache/calcite/test/RelOptRulesTest.java   |   6 +-
 2 files changed, 63 insertions(+), 64 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
index 2b6bbb5..7ac26e4 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
@@ -247,13 +247,69 @@ public class RelMdCollation
             .stream()
             .map((p) -> program.expandLocalRef(p))
             .collect(Collectors.toList());
-    return enumrableCalc(mq, input, projects);
+    return project(mq, input, projects);
   }
 
   /** Helper method to determine a {@link Project}'s collation. */
   public static List<RelCollation> project(RelMetadataQuery mq,
       RelNode input, List<? extends RexNode> projects) {
-    return enumrableCalc(mq, input, projects);
+    final SortedSet<RelCollation> collations = new TreeSet<>();
+    final List<RelCollation> inputCollations = mq.collations(input);
+    if (inputCollations == null || inputCollations.isEmpty()) {
+      return ImmutableList.of();
+    }
+    final Multimap<Integer, Integer> targets = LinkedListMultimap.create();
+    final Map<Integer, SqlMonotonicity> targetsWithMonotonicity =
+        new HashMap<>();
+    for (Ord<RexNode> project : Ord.<RexNode>zip(projects)) {
+      if (project.e instanceof RexInputRef) {
+        targets.put(((RexInputRef) project.e).getIndex(), project.i);
+      } else if (project.e instanceof RexCall) {
+        final RexCall call = (RexCall) project.e;
+        final RexCallBinding binding =
+            RexCallBinding.create(input.getCluster().getTypeFactory(), call, inputCollations);
+        targetsWithMonotonicity.put(project.i, call.getOperator().getMonotonicity(binding));
+      }
+    }
+    final List<RelFieldCollation> fieldCollations = new ArrayList<>();
+    loop:
+    for (RelCollation ic : inputCollations) {
+      if (ic.getFieldCollations().isEmpty()) {
+        continue;
+      }
+      fieldCollations.clear();
+      for (RelFieldCollation ifc : ic.getFieldCollations()) {
+        final Collection<Integer> integers = targets.get(ifc.getFieldIndex());
+        if (integers.isEmpty()) {
+          continue loop; // cannot do this collation
+        }
+        fieldCollations.add(ifc.withFieldIndex(integers.iterator().next()));
+      }
+      assert !fieldCollations.isEmpty();
+      collations.add(RelCollations.of(fieldCollations));
+    }
+
+    final List<RelFieldCollation> fieldCollationsForRexCalls =
+            new ArrayList<>();
+    for (Map.Entry<Integer, SqlMonotonicity> entry : targetsWithMonotonicity.entrySet()) {
+      final SqlMonotonicity value = entry.getValue();
+      switch (value) {
+      case NOT_MONOTONIC:
+      case CONSTANT:
+        break;
+      default:
+        fieldCollationsForRexCalls.add(
+            new RelFieldCollation(entry.getKey(),
+                RelFieldCollation.Direction.of(value)));
+        break;
+      }
+    }
+
+    if (!fieldCollationsForRexCalls.isEmpty()) {
+      collations.add(RelCollations.of(fieldCollationsForRexCalls));
+    }
+
+    return ImmutableList.copyOf(collations);
   }
 
   /** Helper method to determine a
@@ -428,67 +484,6 @@ public class RelMdCollation
     }
     return ImmutableList.of();
   }
-
-  private static List<RelCollation> enumrableCalc(RelMetadataQuery mq,
-      RelNode input, List<? extends RexNode> projects) {
-    final SortedSet<RelCollation> collations = new TreeSet<>();
-    final List<RelCollation> inputCollations = mq.collations(input);
-    if (inputCollations == null || inputCollations.isEmpty()) {
-      return ImmutableList.of();
-    }
-    final Multimap<Integer, Integer> targets = LinkedListMultimap.create();
-    final Map<Integer, SqlMonotonicity> targetsWithMonotonicity =
-        new HashMap<>();
-    for (Ord<RexNode> project : Ord.<RexNode>zip(projects)) {
-      if (project.e instanceof RexInputRef) {
-        targets.put(((RexInputRef) project.e).getIndex(), project.i);
-      } else if (project.e instanceof RexCall) {
-        final RexCall call = (RexCall) project.e;
-        final RexCallBinding binding =
-            RexCallBinding.create(input.getCluster().getTypeFactory(), call, inputCollations);
-        targetsWithMonotonicity.put(project.i, call.getOperator().getMonotonicity(binding));
-      }
-    }
-    final List<RelFieldCollation> fieldCollations = new ArrayList<>();
-    loop:
-    for (RelCollation ic : inputCollations) {
-      if (ic.getFieldCollations().isEmpty()) {
-        continue;
-      }
-      fieldCollations.clear();
-      for (RelFieldCollation ifc : ic.getFieldCollations()) {
-        final Collection<Integer> integers = targets.get(ifc.getFieldIndex());
-        if (integers.isEmpty()) {
-          continue loop; // cannot do this collation
-        }
-        fieldCollations.add(ifc.withFieldIndex(integers.iterator().next()));
-      }
-      assert !fieldCollations.isEmpty();
-      collations.add(RelCollations.of(fieldCollations));
-    }
-
-    final List<RelFieldCollation> fieldCollationsForRexCalls =
-        new ArrayList<>();
-    for (Map.Entry<Integer, SqlMonotonicity> entry : targetsWithMonotonicity.entrySet()) {
-      final SqlMonotonicity value = entry.getValue();
-      switch (value) {
-      case NOT_MONOTONIC:
-      case CONSTANT:
-        break;
-      default:
-        fieldCollationsForRexCalls.add(
-            new RelFieldCollation(entry.getKey(),
-                RelFieldCollation.Direction.of(value)));
-        break;
-      }
-    }
-
-    if (!fieldCollationsForRexCalls.isEmpty()) {
-      collations.add(RelCollations.of(fieldCollationsForRexCalls));
-    }
-
-    return ImmutableList.copyOf(collations);
-  }
 }
 
 // End RelMdCollation.java
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 73a1258..79fa2bf 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -5626,6 +5626,10 @@ public class RelOptRulesTest extends RelOptTestBase {
         .withPre(preProgram).with(program).check();
   }
 
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-3151">[CALCITE-3151
+   * RexCall's Monotonicity is not considered in determining a Calc's collation</a>
+   */
   @Test public void testMonotonicityUDF() throws Exception {
     final SqlFunction monotonicityFun =
         new SqlFunction("MONOFUN", SqlKind.OTHER_FUNCTION, ReturnTypes.BIGINT, null,
@@ -5640,7 +5644,7 @@ public class RelOptRulesTest extends RelOptTestBase {
         };
 
     // Build a tree equivalent to the SQL
-    //  SELECT sal, MONOFUN() AS n FROM emp
+    // SELECT sal, MONOFUN() AS n FROM emp
     final RelBuilder builder =
         RelBuilder.create(RelBuilderTest.config().build());
     final RelNode root =