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 =