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 2015/09/03 00:16:04 UTC
[16/50] incubator-calcite git commit: [CALCITE-783] Infer collation
of Project using monotonicity (Milinda Pathirage)
[CALCITE-783] Infer collation of Project using monotonicity (Milinda Pathirage)
Close apache/incubator-calcite#104
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/c711fed6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/c711fed6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/c711fed6
Branch: refs/heads/branch-release
Commit: c711fed6e2392f296554719a98b2d737da53c9b5
Parents: f7ec3e8
Author: Milinda Pathirage <mi...@gmail.com>
Authored: Thu Jul 9 11:46:58 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Jul 20 20:58:24 2015 -0700
----------------------------------------------------------------------
.../calcite/rel/logical/LogicalAggregate.java | 21 ++++++++-
.../calcite/rel/metadata/RelMdCollation.java | 45 ++++++++++++++++---
.../java/org/apache/calcite/rex/RexBuilder.java | 5 ++-
.../org/apache/calcite/rex/RexCallBinding.java | 46 ++++++++++++++++----
.../calcite/sql2rel/SqlToRelConverter.java | 3 +-
.../sql2rel/StandardConvertletTable.java | 3 +-
6 files changed, 104 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c711fed6/core/src/main/java/org/apache/calcite/rel/logical/LogicalAggregate.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalAggregate.java b/core/src/main/java/org/apache/calcite/rel/logical/LogicalAggregate.java
index e0bca76..650e8a6 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalAggregate.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalAggregate.java
@@ -19,6 +19,8 @@ package org.apache.calcite.rel.logical;
import org.apache.calcite.plan.Convention;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelInput;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelShuttle;
@@ -26,6 +28,9 @@ import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.util.ImmutableBitSet;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+
import java.util.List;
/**
@@ -85,13 +90,25 @@ public final class LogicalAggregate extends Aggregate {
}
/** Creates a LogicalAggregate. */
- public static LogicalAggregate create(RelNode input,
+ public static LogicalAggregate create(final RelNode input,
boolean indicator,
ImmutableBitSet groupSet,
List<ImmutableBitSet> groupSets,
List<AggregateCall> aggCalls) {
final RelOptCluster cluster = input.getCluster();
- final RelTraitSet traitSet = cluster.traitSetOf(Convention.NONE);
+ final RelTraitSet traitSet = cluster.traitSetOf(Convention.NONE).replaceIfs(
+ RelCollationTraitDef.INSTANCE,
+ new Supplier<List<RelCollation>>() {
+ public List<RelCollation> get() {
+ List<RelCollation> collations =
+ input.getTraitSet().getTraits(RelCollationTraitDef.INSTANCE);
+ if (collations != null) {
+ return collations;
+ }
+
+ return ImmutableList.of();
+ }
+ });
return new LogicalAggregate(cluster, traitSet, input, indicator, groupSet,
groupSets, aggCalls);
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c711fed6/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
----------------------------------------------------------------------
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 52a7c43..cf0614b 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
@@ -55,7 +55,9 @@ import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.SortedSet;
/**
@@ -187,18 +189,16 @@ public class RelMdCollation {
return ImmutableList.of();
}
final Multimap<Integer, Integer> targets = LinkedListMultimap.create();
+ final Map<Integer, SqlMonotonicity> targetsWithMonotonicity =
+ new HashMap<>();
for (Ord<RexNode> project : Ord.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);
- if (false) {
- final SqlMonotonicity monotonicity =
- call.getOperator().getMonotonicity(binding);
- // TODO: do something with this monotonicity
- }
+ RexCallBinding.create(input.getCluster().getTypeFactory(), call, inputCollations);
+ targetsWithMonotonicity.put(project.i, call.getOperator().getMonotonicity(binding));
}
}
final List<RelFieldCollation> fieldCollations = Lists.newArrayList();
@@ -218,9 +218,42 @@ public class RelMdCollation {
assert !fieldCollations.isEmpty();
collations.add(RelCollations.of(fieldCollations));
}
+
+ final List<RelFieldCollation> fieldCollationsForRexCalls = Lists.newArrayList();
+ for (Map.Entry<Integer, SqlMonotonicity> targetMonotonicity
+ : targetsWithMonotonicity.entrySet()) {
+ if (targetMonotonicity.getValue() != SqlMonotonicity.NOT_MONOTONIC
+ && targetMonotonicity.getValue() != SqlMonotonicity.CONSTANT) {
+ fieldCollationsForRexCalls.add(new RelFieldCollation(targetMonotonicity.getKey(),
+ monotonicityToDirection(targetMonotonicity.getValue())));
+ }
+ }
+
+ if (!fieldCollationsForRexCalls.isEmpty()) {
+ collations.add(RelCollations.of(fieldCollationsForRexCalls));
+ }
+
return ImmutableList.copyOf(collations);
}
+ private static RelFieldCollation.Direction monotonicityToDirection(SqlMonotonicity monotonicity) {
+ switch (monotonicity) {
+ case INCREASING:
+ return RelFieldCollation.Direction.ASCENDING;
+ case DECREASING:
+ return RelFieldCollation.Direction.DESCENDING;
+ case STRICTLY_INCREASING:
+ return RelFieldCollation.Direction.STRICTLY_ASCENDING;
+ case STRICTLY_DECREASING:
+ return RelFieldCollation.Direction.STRICTLY_DESCENDING;
+ case MONOTONIC:
+ return RelFieldCollation.Direction.CLUSTERED;
+ default:
+ throw new IllegalStateException(
+ String.format("SQL monotonicity of type %s is not allowed at this stage.", monotonicity));
+ }
+ }
+
/** Helper method to determine a
* {@link org.apache.calcite.rel.core.Window}'s collation.
*
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c711fed6/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
index 335293a..2cb47d5 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
@@ -20,6 +20,7 @@ import org.apache.calcite.avatica.util.ByteString;
import org.apache.calcite.avatica.util.DateTimeUtils;
import org.apache.calcite.avatica.util.Spaces;
import org.apache.calcite.avatica.util.TimeUnit;
+import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.type.RelDataType;
@@ -263,7 +264,9 @@ public class RexBuilder {
public RelDataType deriveReturnType(
SqlOperator op,
List<? extends RexNode> exprs) {
- return op.inferReturnType(new RexCallBinding(typeFactory, op, exprs));
+ return op.inferReturnType(
+ new RexCallBinding(typeFactory, op, exprs,
+ ImmutableList.<RelCollation>of()));
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c711fed6/core/src/main/java/org/apache/calcite/rex/RexCallBinding.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexCallBinding.java b/core/src/main/java/org/apache/calcite/rex/RexCallBinding.java
index 373b90f..c2828aa 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexCallBinding.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexCallBinding.java
@@ -16,6 +16,8 @@
*/
package org.apache.calcite.rex;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.runtime.CalciteException;
@@ -40,26 +42,31 @@ public class RexCallBinding extends SqlOperatorBinding {
private final List<RexNode> operands;
+ private final List<RelCollation> inputCollations;
+
//~ Constructors -----------------------------------------------------------
public RexCallBinding(
RelDataTypeFactory typeFactory,
SqlOperator sqlOperator,
- List<? extends RexNode> operands) {
+ List<? extends RexNode> operands,
+ List<RelCollation> inputCollations) {
super(typeFactory, sqlOperator);
this.operands = ImmutableList.copyOf(operands);
+ this.inputCollations = ImmutableList.copyOf(inputCollations);
}
/** Creates a binding of the appropriate type. */
public static RexCallBinding create(RelDataTypeFactory typeFactory,
- RexCall call) {
+ RexCall call,
+ List<RelCollation> inputCollations) {
switch (call.getKind()) {
case CAST:
return new RexCastCallBinding(typeFactory, call.getOperator(),
- call.getOperands(), call.getType());
+ call.getOperands(), call.getType(), inputCollations);
}
return new RexCallBinding(typeFactory, call.getOperator(),
- call.getOperands());
+ call.getOperands(), inputCollations);
}
//~ Methods ----------------------------------------------------------------
@@ -77,7 +84,28 @@ public class RexCallBinding extends SqlOperatorBinding {
}
@Override public SqlMonotonicity getOperandMonotonicity(int ordinal) {
- throw new AssertionError(); // to be completed
+ RexNode operand = operands.get(ordinal);
+
+ if (operand instanceof RexInputRef) {
+ for (RelCollation ic : inputCollations) {
+ if (ic.getFieldCollations().isEmpty()) {
+ continue;
+ }
+
+ for (RelFieldCollation rfc : ic.getFieldCollations()) {
+ if (rfc.getFieldIndex() == ((RexInputRef) operand).getIndex()) {
+ return rfc.direction.monotonicity();
+ // TODO: Is it possible to have more than one RelFieldCollation for a RexInputRef?
+ }
+ }
+ }
+ } else if (operand instanceof RexCall) {
+ final RexCallBinding binding =
+ RexCallBinding.create(typeFactory, (RexCall) operand, inputCollations);
+ ((RexCall) operand).getOperator().getMonotonicity(binding);
+ }
+
+ return SqlMonotonicity.NOT_MONOTONIC;
}
@Override public boolean isOperandNull(int ordinal, boolean allowCast) {
@@ -104,10 +132,12 @@ public class RexCallBinding extends SqlOperatorBinding {
private static class RexCastCallBinding extends RexCallBinding {
private final RelDataType type;
- public RexCastCallBinding(RelDataTypeFactory typeFactory,
+ public RexCastCallBinding(
+ RelDataTypeFactory typeFactory,
SqlOperator sqlOperator, List<? extends RexNode> operands,
- RelDataType type) {
- super(typeFactory, sqlOperator, operands);
+ RelDataType type,
+ List<RelCollation> inputCollations) {
+ super(typeFactory, sqlOperator, operands, inputCollations);
this.type = type;
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c711fed6/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index e733d13..fe16f23 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -4688,7 +4688,8 @@ public class SqlToRelConverter {
new RexCallBinding(
rexBuilder.getTypeFactory(),
SqlStdOperatorTable.HISTOGRAM_AGG,
- exprs);
+ exprs,
+ ImmutableList.<RelCollation>of());
RexNode over =
rexBuilder.makeOver(
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c711fed6/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
index 8bf28e0..b184982 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
@@ -20,6 +20,7 @@ import org.apache.calcite.avatica.util.DateTimeUtils;
import org.apache.calcite.avatica.util.TimeUnit;
import org.apache.calcite.avatica.util.TimeUnitRange;
import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeFamily;
@@ -718,7 +719,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final int groupCount = cx.getGroupCount();
if (returnType == null) {
RexCallBinding binding =
- new RexCallBinding(cx.getTypeFactory(), fun, exprs) {
+ new RexCallBinding(cx.getTypeFactory(), fun, exprs, ImmutableList.<RelCollation>of()) {
@Override public int getGroupCount() {
return groupCount;
}