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/02/08 18:25:03 UTC
[4/9] incubator-calcite git commit: [CALCITE-88] Add collation as a
trait and a kind of RelNode metadata
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java b/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java
index e108c78..2b129bb 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java
@@ -36,6 +36,7 @@ import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.logical.LogicalTableFunctionScan;
import org.apache.calcite.rel.logical.LogicalTableModify;
import org.apache.calcite.rel.logical.LogicalValues;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.rules.ProjectRemoveRule;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeField;
@@ -157,9 +158,8 @@ public class RelFieldTrimmer implements ReflectiveVisitor {
* @param setOpFactory SetOp factory
* @param useNamesInIdentityProjCalc
* Include field names in identity project determination
- *
- * @deprecated Remove before
- * {@link org.apache.calcite.util.Bug#upgrade Calcite-1.1}. */
+ */
+ @Deprecated // to be removed before 1.1
public RelFieldTrimmer(SqlValidator validator,
RelFactories.ProjectFactory projectFactory,
RelFactories.FilterFactory filterFactory,
@@ -231,6 +231,13 @@ public class RelFieldTrimmer implements ReflectiveVisitor {
// So, disable trimming.
fieldsUsed = ImmutableBitSet.range(input.getRowType().getFieldCount());
}
+ final ImmutableList<RelCollation> collations =
+ RelMetadataQuery.collations(rel);
+ for (RelCollation collation : collations) {
+ for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
+ fieldsUsed = fieldsUsed.set(fieldCollation.getFieldIndex());
+ }
+ }
return dispatchTrimFields(input, fieldsUsed, extraFields);
}
@@ -1014,7 +1021,8 @@ public class RelFieldTrimmer implements ReflectiveVisitor {
RelOptUtil.permute(values.getCluster().getTypeFactory(), rowType,
mapping);
final LogicalValues newValues =
- new LogicalValues(values.getCluster(), newRowType, newTuples.build());
+ LogicalValues.create(values.getCluster(), newRowType,
+ newTuples.build());
return new TrimResult(newValues, mapping);
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java b/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
index aa8e548..8fa93a1 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
@@ -70,7 +70,6 @@ import org.apache.calcite.util.Util;
import org.apache.calcite.util.mapping.Mappings;
import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.SortedSetMultimap;
@@ -342,14 +341,9 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
public void rewriteRel(LogicalTableModify rel) {
LogicalTableModify newRel =
- new LogicalTableModify(
- rel.getCluster(),
- rel.getTable(),
- rel.getCatalogReader(),
- getNewForOldRel(rel.getInput()),
- rel.getOperation(),
- rel.getUpdateColumnList(),
- true);
+ LogicalTableModify.create(rel.getTable(), rel.getCatalogReader(),
+ getNewForOldRel(rel.getInput()), rel.getOperation(),
+ rel.getUpdateColumnList(), true);
setNewForOldRel(rel, newRel);
}
@@ -398,8 +392,7 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
public void rewriteRel(LogicalJoin rel) {
LogicalJoin newRel =
- new LogicalJoin(
- rel.getCluster(),
+ LogicalJoin.create(
getNewForOldRel(rel.getLeft()),
getNewForOldRel(rel.getRight()),
rel.getCondition().accept(new RewriteRexShuttle()),
@@ -420,9 +413,7 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
newPos.set(getNewForOldInput(pos));
}
LogicalCorrelate newRel =
- new LogicalCorrelate(
- rel.getCluster(),
- getNewForOldRel(rel.getLeft()),
+ LogicalCorrelate.create(getNewForOldRel(rel.getLeft()),
getNewForOldRel(rel.getRight()),
rel.getCorrelationId(),
newPos.build(),
@@ -483,12 +474,12 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
public void rewriteRel(LogicalCalc rel) {
// Translate the child.
- final RelNode newChild = getNewForOldRel(rel.getInput());
+ final RelNode newInput = getNewForOldRel(rel.getInput());
final RelOptCluster cluster = rel.getCluster();
RexProgramBuilder programBuilder =
new RexProgramBuilder(
- newChild.getRowType(),
+ newInput.getRowType(),
cluster.getRexBuilder());
// Convert the common expressions.
@@ -524,13 +515,7 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
RexProgram newProgram = programBuilder.getProgram();
// Create a new calc relational expression.
- LogicalCalc newRel =
- new LogicalCalc(
- cluster,
- rel.getTraitSet(),
- newChild,
- newProgram,
- ImmutableList.<RelCollation>of());
+ LogicalCalc newRel = LogicalCalc.create(newInput, newProgram);
setNewForOldRel(rel, newRel);
}
@@ -640,10 +625,7 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
RelDataType type,
List<Pair<RexNode, String>> flattenedExps) {
RelDataType flattenedType =
- SqlTypeUtil.flattenRecordType(
- rexBuilder.getTypeFactory(),
- type,
- null);
+ SqlTypeUtil.flattenRecordType(rexBuilder.getTypeFactory(), type, null);
for (RelDataTypeField field : flattenedType.getFieldList()) {
flattenedExps.add(
Pair.of(
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/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 2eb7d2c..0ace1e9 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -27,7 +27,7 @@ import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.prepare.Prepare;
import org.apache.calcite.prepare.RelOptTableImpl;
import org.apache.calcite.rel.RelCollation;
-import org.apache.calcite.rel.RelCollationImpl;
+import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelShuttle;
@@ -602,7 +602,7 @@ public class SqlToRelConverter {
orderExprList,
collationList);
final RelCollation collation =
- cluster.traitSetOf().canonize(RelCollationImpl.of(collationList));
+ cluster.traitSet().canonize(RelCollations.of(collationList));
if (validator.isAggregate(select)) {
convertAgg(
@@ -674,12 +674,8 @@ public class SqlToRelConverter {
}
}
rel =
- new LogicalProject(
- cluster,
- rel,
- Pair.left(newProjects),
+ LogicalProject.create(rel, Pair.left(newProjects),
Pair.right(newProjects));
-
bb.root = rel;
distinctify(bb, false);
rel = bb.root;
@@ -698,12 +694,8 @@ public class SqlToRelConverter {
}
rel =
- new LogicalProject(
- cluster,
- rel,
- Pair.left(undoProjects),
+ LogicalProject.create(rel, Pair.left(undoProjects),
Pair.right(undoProjects));
-
bb.setRoot(
rel,
false);
@@ -780,7 +772,7 @@ public class SqlToRelConverter {
bb.setRoot(
new LogicalProject(
cluster,
- cluster.traitSetOf(RelCollationImpl.PRESERVE),
+ cluster.traitSetOf(RelCollations.PRESERVE),
bb.root,
exprs,
cluster.getTypeFactory().createStructType(
@@ -1030,16 +1022,17 @@ public class SqlToRelConverter {
final int keyCount = leftKeys.size();
final List<Integer> args = ImmutableIntList.range(0, keyCount);
LogicalAggregate aggregate =
- new LogicalAggregate(cluster, seek, false, ImmutableBitSet.of(),
- null,
+ LogicalAggregate.create(seek, false, ImmutableBitSet.of(), null,
ImmutableList.of(
new AggregateCall(SqlStdOperatorTable.COUNT, false,
ImmutableList.<Integer>of(), longType, null),
new AggregateCall(SqlStdOperatorTable.COUNT, false,
args, longType, null)));
LogicalJoin join =
- new LogicalJoin(cluster, bb.root, aggregate,
- rexBuilder.makeLiteral(true), JoinRelType.INNER,
+ LogicalJoin.create(bb.root,
+ aggregate,
+ rexBuilder.makeLiteral(true),
+ JoinRelType.INNER,
ImmutableSet.<String>of());
bb.setRoot(join, false);
}
@@ -1487,10 +1480,7 @@ public class SqlToRelConverter {
unionInputs.add(convertRowConstructor(bb, call));
}
LogicalValues values =
- new LogicalValues(
- cluster,
- rowType,
- tupleList.build());
+ LogicalValues.create(cluster, rowType, tupleList.build());
RelNode resultRel;
if (unionInputs.isEmpty()) {
resultRel = values;
@@ -1498,12 +1488,7 @@ public class SqlToRelConverter {
if (!values.getTuples().isEmpty()) {
unionInputs.add(values);
}
- LogicalUnion union =
- new LogicalUnion(
- cluster,
- unionInputs,
- true);
- resultRel = union;
+ resultRel = LogicalUnion.create(unionInputs, true);
}
leaves.add(resultRel);
return resultRel;
@@ -1862,7 +1847,7 @@ public class SqlToRelConverter {
if (shouldConvertTableAccess) {
tableRel = toRel(table);
} else {
- tableRel = new LogicalTableScan(cluster, table);
+ tableRel = LogicalTableScan.create(cluster, table);
}
bb.setRoot(tableRel, true);
if (usedDataset[0]) {
@@ -2004,8 +1989,7 @@ public class SqlToRelConverter {
Set<RelColumnMapping> columnMappings =
getColumnMappings(operator);
LogicalTableFunctionScan callRel =
- new LogicalTableFunctionScan(
- cluster,
+ LogicalTableFunctionScan.create(cluster,
inputs,
rexCall,
elementType,
@@ -2145,12 +2129,8 @@ public class SqlToRelConverter {
ImmutableSet.copyOf(Util.skip(correlNames)));
rightRel = rightRel.accept(dedup);
}
- LogicalCorrelate corr = new LogicalCorrelate(
- rightRel.getCluster(),
- leftRel,
- rightRel,
- new CorrelationId(correlNames.get(0)),
- requiredColumns.build(),
+ LogicalCorrelate corr = LogicalCorrelate.create(leftRel, rightRel,
+ new CorrelationId(correlNames.get(0)), requiredColumns.build(),
SemiJoinType.of(joinType));
if (!joinCond.isAlwaysTrue()) {
return RelOptUtil.createFilter(corr, joinCond);
@@ -2753,12 +2733,7 @@ public class SqlToRelConverter {
protected RelNode createAggregate(Blackboard bb, boolean indicator,
ImmutableBitSet groupSet, ImmutableList<ImmutableBitSet> groupSets,
List<AggregateCall> aggCalls) {
- return new LogicalAggregate(
- cluster,
- bb.root,
- indicator,
- groupSet,
- groupSets,
+ return LogicalAggregate.create(bb.root, indicator, groupSet, groupSets,
aggCalls);
}
@@ -2957,18 +2932,12 @@ public class SqlToRelConverter {
}
switch (call.getKind()) {
case UNION:
- return new LogicalUnion(
- cluster,
- ImmutableList.of(left, right),
- all);
+ return LogicalUnion.create(ImmutableList.of(left, right), all);
case INTERSECT:
// TODO: all
if (!all) {
- return new LogicalIntersect(
- cluster,
- ImmutableList.of(left, right),
- all);
+ return LogicalIntersect.create(ImmutableList.of(left, right), all);
} else {
throw Util.newInternal(
"set operator INTERSECT ALL not suported");
@@ -2977,10 +2946,7 @@ public class SqlToRelConverter {
case EXCEPT:
// TODO: all
if (!all) {
- return new LogicalMinus(
- cluster,
- ImmutableList.of(left, right),
- all);
+ return LogicalMinus.create(ImmutableList.of(left, right), all);
} else {
throw Util.newInternal(
"set operator EXCEPT ALL not suported");
@@ -3016,14 +2982,8 @@ public class SqlToRelConverter {
null,
false);
}
- return new LogicalTableModify(
- cluster,
- targetTable,
- catalogReader,
- massagedRel,
- LogicalTableModify.Operation.INSERT,
- null,
- false);
+ return LogicalTableModify.create(targetTable, catalogReader, massagedRel,
+ LogicalTableModify.Operation.INSERT, null, false);
}
private RelOptTable.ToRelContext createToRelContext() {
@@ -3164,14 +3124,8 @@ public class SqlToRelConverter {
private RelNode convertDelete(SqlDelete call) {
RelOptTable targetTable = getTargetTable(call);
RelNode sourceRel = convertSelect(call.getSourceSelect());
- return new LogicalTableModify(
- cluster,
- targetTable,
- catalogReader,
- sourceRel,
- LogicalTableModify.Operation.DELETE,
- null,
- false);
+ return LogicalTableModify.create(targetTable, catalogReader, sourceRel,
+ LogicalTableModify.Operation.DELETE, null, false);
}
private RelNode convertUpdate(SqlUpdate call) {
@@ -3187,14 +3141,8 @@ public class SqlToRelConverter {
RelNode sourceRel = convertSelect(call.getSourceSelect());
- return new LogicalTableModify(
- cluster,
- targetTable,
- catalogReader,
- sourceRel,
- LogicalTableModify.Operation.UPDATE,
- targetColumnNameList,
- false);
+ return LogicalTableModify.create(targetTable, catalogReader, sourceRel,
+ LogicalTableModify.Operation.UPDATE, targetColumnNameList, false);
}
private RelNode convertMerge(SqlMerge call) {
@@ -3270,14 +3218,8 @@ public class SqlToRelConverter {
RelNode massagedRel =
RelOptUtil.createProject(join, projects, null, true);
- return new LogicalTableModify(
- cluster,
- targetTable,
- catalogReader,
- massagedRel,
- LogicalTableModify.Operation.MERGE,
- targetColumnNameList,
- false);
+ return LogicalTableModify.create(targetTable, catalogReader, massagedRel,
+ LogicalTableModify.Operation.MERGE, targetColumnNameList, false);
}
/**
@@ -3507,12 +3449,7 @@ public class SqlToRelConverter {
RexNode condition,
JoinRelType joinType,
Set<String> variablesStopped) {
- return new LogicalJoin(
- cluster,
- left,
- right,
- condition,
- joinType,
+ return LogicalJoin.create(left, right, condition, joinType,
variablesStopped);
}
@@ -3692,10 +3629,7 @@ public class SqlToRelConverter {
true);
} else {
bb.setRoot(
- new LogicalUnion(
- cluster,
- unionRels,
- true),
+ LogicalUnion.create(unionRels, true),
true);
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/tools/Programs.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/tools/Programs.java b/core/src/main/java/org/apache/calcite/tools/Programs.java
index 115cbf1..154766f 100644
--- a/core/src/main/java/org/apache/calcite/tools/Programs.java
+++ b/core/src/main/java/org/apache/calcite/tools/Programs.java
@@ -101,6 +101,7 @@ public class Programs {
public static final ImmutableSet<RelOptRule> RULE_SET =
ImmutableSet.of(
EnumerableRules.ENUMERABLE_JOIN_RULE,
+ EnumerableRules.ENUMERABLE_MERGE_JOIN_RULE,
EnumerableRules.ENUMERABLE_SEMI_JOIN_RULE,
EnumerableRules.ENUMERABLE_CORRELATE_RULE,
EnumerableRules.ENUMERABLE_PROJECT_RULE,
@@ -261,7 +262,9 @@ public class Programs {
public RelNode run(RelOptPlanner planner, RelNode rel,
RelTraitSet requiredOutputTraits) {
final RelNode rootRel2 =
- planner.changeTraits(rel, requiredOutputTraits);
+ rel.getTraitSet().equals(requiredOutputTraits)
+ ? rel
+ : planner.changeTraits(rel, requiredOutputTraits);
assert rootRel2 != null;
planner.setRoot(rootRel2);
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/util/Bug.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/Bug.java b/core/src/main/java/org/apache/calcite/util/Bug.java
index c91cde4..46189c2 100644
--- a/core/src/main/java/org/apache/calcite/util/Bug.java
+++ b/core/src/main/java/org/apache/calcite/util/Bug.java
@@ -182,6 +182,10 @@ public abstract class Bug {
/**
* Use this method to flag code that should be re-visited after upgrading
* a component.
+ *
+ * <p>If the intended change is that a class or member be removed, flag
+ * instead using a {@link Deprecated} annotation followed by a comment such as
+ * "to be removed before 2.0".
*/
public static boolean upgrade(String remark) {
Util.discard(remark);
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
index 779196a..fac2ef1 100644
--- a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
+++ b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
@@ -81,6 +81,7 @@ import java.util.Map;
import java.util.TimeZone;
import javax.sql.DataSource;
+import static org.apache.calcite.rel.metadata.BuiltInMetadata.Collation;
import static org.apache.calcite.rel.metadata.BuiltInMetadata.ColumnOrigin;
import static org.apache.calcite.rel.metadata.BuiltInMetadata.ColumnUniqueness;
import static org.apache.calcite.rel.metadata.BuiltInMetadata.CumulativeCost;
@@ -124,6 +125,9 @@ public enum BuiltInMethod {
String.class, Function1.class),
JOIN(ExtendedEnumerable.class, "join", Enumerable.class, Function1.class,
Function1.class, Function2.class),
+ MERGE_JOIN(Enumerables.class, "mergeJoin", Enumerable.class, Enumerable.class,
+ Function1.class, Function1.class, Function2.class, boolean.class,
+ boolean.class),
SLICE0(Enumerables.class, "slice0", Enumerable.class),
SEMI_JOIN(Enumerables.class, "semiJoin", Enumerable.class, Enumerable.class,
Function1.class, Function1.class),
@@ -164,6 +168,7 @@ public enum BuiltInMethod {
LIST_N(FlatLists.class, "of", Object[].class),
LIST2(FlatLists.class, "of", Object.class, Object.class),
LIST3(FlatLists.class, "of", Object.class, Object.class, Object.class),
+ COMPARABLE_EMPTY_LIST(FlatLists.class, "COMPARABLE_EMPTY_LIST", true),
IDENTITY_COMPARER(Functions.class, "identityComparer"),
IDENTITY_SELECTOR(Functions.class, "identitySelector"),
AS_ENUMERABLE(Linq4j.class, "asEnumerable", Object[].class),
@@ -286,6 +291,7 @@ public enum BuiltInMethod {
UNIQUE_KEYS(UniqueKeys.class, "getUniqueKeys", boolean.class),
COLUMN_UNIQUENESS(ColumnUniqueness.class, "areColumnsUnique",
ImmutableBitSet.class, boolean.class),
+ COLLATIONS(Collation.class, "collations"),
ROW_COUNT(RowCount.class, "getRowCount"),
DISTINCT_ROW_COUNT(DistinctRowCount.class, "getDistinctRowCount",
ImmutableBitSet.class, RexNode.class),
@@ -323,22 +329,26 @@ public enum BuiltInMethod {
MAP = builder.build();
}
+ private BuiltInMethod(Method method, Constructor constructor, Field field) {
+ this.method = method;
+ this.constructor = constructor;
+ this.field = field;
+ }
+
+ /** Defines a method. */
BuiltInMethod(Class clazz, String methodName, Class... argumentTypes) {
- this.method = Types.lookupMethod(clazz, methodName, argumentTypes);
- this.constructor = null;
- this.field = null;
+ this(Types.lookupMethod(clazz, methodName, argumentTypes), null, null);
}
+ /** Defines a constructor. */
BuiltInMethod(Class clazz, Class... argumentTypes) {
- this.method = null;
- this.constructor = Types.lookupConstructor(clazz, argumentTypes);
- this.field = null;
+ this(null, Types.lookupConstructor(clazz, argumentTypes), null);
}
+ /** Defines a field. */
BuiltInMethod(Class clazz, String fieldName, boolean dummy) {
- this.method = null;
- this.constructor = null;
- this.field = Types.lookupField(clazz, fieldName);
+ this(null, null, Types.lookupField(clazz, fieldName));
+ assert dummy : "dummy value for method overloading must be true";
}
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java b/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java
index 43c3d37..670b10e 100644
--- a/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java
+++ b/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java
@@ -735,6 +735,11 @@ public class ImmutableBitSet
throw new IndexOutOfBoundsException("index out of range: " + n);
}
+ /** Returns a bit set the same as this but with a given bit set. */
+ public ImmutableBitSet set(int i) {
+ return union(ImmutableBitSet.of(i));
+ }
+
/** Returns a bit set the same as this but with a given bit cleared. */
public ImmutableBitSet clear(int i) {
return except(ImmutableBitSet.of(i));
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java b/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java
index ace0c95..e4d147d 100644
--- a/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java
+++ b/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java
@@ -131,7 +131,7 @@ public class ImmutableIntList extends FlatLists.AbstractFlatList<Integer> {
: (T[]) Array.newInstance(
a.getClass().getComponentType(), size);
}
- if (a.getClass() == Integer[].class) {
+ if ((Class) a.getClass() == Integer[].class) {
final Integer[] integers = (Integer[]) a;
for (int i = 0; i < integers.length; i++) {
integers[i] = ints[i];
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/main/java/org/apache/calcite/util/Util.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/Util.java b/core/src/main/java/org/apache/calcite/util/Util.java
index 4831a60..5aa8246 100644
--- a/core/src/main/java/org/apache/calcite/util/Util.java
+++ b/core/src/main/java/org/apache/calcite/util/Util.java
@@ -1153,6 +1153,11 @@ public class Util {
return buf.toString();
}
+ /** Converts a list of strings to a string separated by newlines. */
+ public static String lines(Iterable<String> strings) {
+ return toString(strings, "", "\n", "");
+ }
+
/**
* Converts a Java timezone to POSIX format, so that the boost C++ library
* can instantiate timezone objects.
@@ -1978,9 +1983,19 @@ public class Util {
/** Returns whether one list is a prefix of another. */
public static <E> boolean startsWith(List<E> list0, List<E> list1) {
- return list0.equals(list1)
- || list0.size() > list1.size()
- && list0.subList(0, list1.size()).equals(list1);
+ if (list0 == list1) {
+ return true;
+ }
+ final int size = list1.size();
+ if (list0.size() < size) {
+ return false;
+ }
+ for (int i = 0; i < size; i++) {
+ if (!Objects.equal(list0.get(i), list1.get(i))) {
+ return false;
+ }
+ }
+ return true;
}
/** Converts a number into human-readable form, with 3 digits and a "K", "M"
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
index 0410398..f5dd8a2 100644
--- a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
@@ -119,24 +119,24 @@ public class RelWriterTest {
RelOptSchema relOptSchema, SchemaPlus rootSchema) {
rootSchema.add("hr",
new ReflectiveSchema(new JdbcTest.HrSchema()));
- LogicalTableScan table =
- new LogicalTableScan(cluster,
+ LogicalTableScan scan =
+ LogicalTableScan.create(cluster,
relOptSchema.getTableForMember(
Arrays.asList("hr", "emps")));
final RexBuilder rexBuilder = cluster.getRexBuilder();
LogicalFilter filter =
- new LogicalFilter(cluster, table,
+ LogicalFilter.create(scan,
rexBuilder.makeCall(
SqlStdOperatorTable.EQUALS,
rexBuilder.makeFieldAccess(
- rexBuilder.makeRangeReference(table),
+ rexBuilder.makeRangeReference(scan),
"deptno", true),
rexBuilder.makeExactLiteral(BigDecimal.TEN)));
final RelJsonWriter writer = new RelJsonWriter();
final RelDataType bigIntType =
cluster.getTypeFactory().createSqlType(SqlTypeName.BIGINT);
LogicalAggregate aggregate =
- new LogicalAggregate(cluster, filter, false,
+ LogicalAggregate.create(filter, false,
ImmutableBitSet.of(0), null,
ImmutableList.of(
new AggregateCall(SqlStdOperatorTable.COUNT,
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTraitTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTraitTest.java b/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTraitTest.java
index aefed30..66654da 100644
--- a/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTraitTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTraitTest.java
@@ -121,9 +121,9 @@ public class VolcanoPlannerTraitTest {
new NoneSingleRel(cluster, noneLeafRel), ALT_TRAIT2);
RelNode convertedRel =
- planner.changeTraits(
- noneRel,
- cluster.traitSetOf(EnumerableConvention.INSTANCE, ALT_TRAIT2));
+ planner.changeTraits(noneRel,
+ cluster.traitSetOf(EnumerableConvention.INSTANCE)
+ .replace(ALT_TRAIT2));
planner.setRoot(convertedRel);
RelNode result = planner.chooseDelegate().findBestExp();
@@ -177,10 +177,9 @@ public class VolcanoPlannerTraitTest {
new NoneSingleRel(cluster, noneLeafRel), ALT_TRAIT2);
RelNode convertedRel =
- planner.changeTraits(
- noneRel,
- cluster.traitSetOf(
- EnumerableConvention.INSTANCE, ALT_TRAIT2));
+ planner.changeTraits(noneRel,
+ cluster.traitSetOf(EnumerableConvention.INSTANCE)
+ .replace(ALT_TRAIT2));
planner.setRoot(convertedRel);
RelNode result = planner.chooseDelegate().findBestExp();
@@ -251,7 +250,7 @@ public class VolcanoPlannerTraitTest {
return ordinal;
}
- public boolean subsumes(RelTrait trait) {
+ public boolean satisfies(RelTrait trait) {
return equals(trait);
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/rel/RelCollationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/rel/RelCollationTest.java b/core/src/test/java/org/apache/calcite/rel/RelCollationTest.java
new file mode 100644
index 0000000..5486e42
--- /dev/null
+++ b/core/src/test/java/org/apache/calcite/rel/RelCollationTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.rel;
+
+import com.google.common.collect.Lists;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Tests for {@link RelCollation} and {@link RelFieldCollation}.
+ */
+public class RelCollationTest {
+ /** Unit test for {@link RelCollations#contains}. */
+ @Test public void testCollationContains() {
+ final RelCollation collation =
+ RelCollations.of(
+ new RelFieldCollation(2, RelFieldCollation.Direction.ASCENDING),
+ new RelFieldCollation(1, RelFieldCollation.Direction.DESCENDING));
+ assertThat(RelCollations.contains(collation, Arrays.asList(2)), is(true));
+ assertThat(RelCollations.contains(collation, Arrays.asList(1)), is(false));
+ assertThat(RelCollations.contains(collation, Arrays.asList(0)), is(false));
+ assertThat(RelCollations.contains(collation, Arrays.asList(2, 1)),
+ is(true));
+ assertThat(RelCollations.contains(collation, Arrays.asList(2, 0)),
+ is(false));
+ assertThat(RelCollations.contains(collation, Arrays.asList(2, 1, 3)),
+ is(false));
+ assertThat(RelCollations.contains(collation, Arrays.<Integer>asList()),
+ is(true));
+ }
+
+ /** Unit test for
+ * {@link org.apache.calcite.rel.RelCollationImpl#compareTo}. */
+ @Test public void testCollationCompare() {
+ assertThat(collation(1, 2).compareTo(collation(1, 2)), equalTo(0));
+ assertThat(collation(1, 2).compareTo(collation(1)), equalTo(1));
+ assertThat(collation(1).compareTo(collation(1, 2)), equalTo(-1));
+ assertThat(collation(1, 3).compareTo(collation(1, 2)), equalTo(1));
+ assertThat(collation(0, 3).compareTo(collation(1, 2)), equalTo(-1));
+ assertThat(collation().compareTo(collation(0)), equalTo(-1));
+ assertThat(collation(1).compareTo(collation()), equalTo(1));
+ }
+
+ private static RelCollation collation(int... ordinals) {
+ final List<RelFieldCollation> list = Lists.newArrayList();
+ for (int ordinal : ordinals) {
+ list.add(new RelFieldCollation(ordinal));
+ }
+ return RelCollations.of(list);
+ }
+}
+
+// End RelCollationTest.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java b/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
index bec93d8..48eb1d5 100644
--- a/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
@@ -1062,6 +1062,22 @@ public class SqlParserTest {
+ "ORDER BY 1, 2 DESC");
}
+ @Test public void testOrderUnion() {
+ // ORDER BY inside UNION not allowed
+ sql("select a from t order by a\n"
+ + "^union^ all\n"
+ + "select b from t order by b")
+ .fails("(?s).*Encountered \"union\" at .*");
+ }
+
+ @Test public void testLimitUnion() {
+ // LIMIT inside UNION not allowed
+ sql("select a from t limit 10\n"
+ + "^union^ all\n"
+ + "select b from t order by b")
+ .fails("(?s).*Encountered \"union\" at .*");
+ }
+
@Test public void testUnionOfNonQueryFails() {
checkFails(
"select 1 from emp union ^2^ + 5",
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
index 25f249a..77faaf0 100644
--- a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
+++ b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
@@ -78,7 +78,6 @@ import javax.sql.DataSource;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
-import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
@@ -342,8 +341,10 @@ public class CalciteAssert {
CalciteAssert.toStringList(resultSet, actualList);
Collections.sort(actualList);
- // Use assertArrayEquals since it implements fine-grained comparison.
- assertArrayEquals(expectedList.toArray(), actualList.toArray());
+ if (!actualList.equals(expectedList)) {
+ assertThat(Util.lines(actualList),
+ equalTo(Util.lines(expectedList)));
+ }
return null;
} catch (SQLException e) {
throw new RuntimeException(e);
@@ -358,9 +359,7 @@ public class CalciteAssert {
public Void apply(ResultSet s) {
try {
final String actual = Util.toLinux(CalciteAssert.toString(s));
- if (!actual.contains(expected)) {
- assertEquals("contains", expected, actual);
- }
+ assertThat(actual, containsString(expected));
return null;
} catch (SQLException e) {
throw new RuntimeException(e);
@@ -377,9 +376,7 @@ public class CalciteAssert {
final String actual = Util.toLinux(CalciteAssert.toString(s));
final String maskedActual =
actual.replaceAll(", id = [0-9]+", "");
- if (!maskedActual.contains(expected)) {
- assertEquals("contains", expected, maskedActual);
- }
+ assertThat(maskedActual, containsString(expected));
return null;
} catch (SQLException e) {
throw new RuntimeException(e);
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/CalciteSuite.java b/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
index d36e3a5..d9ac400 100644
--- a/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
+++ b/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
@@ -22,6 +22,7 @@ import org.apache.calcite.plan.RelOptUtilTest;
import org.apache.calcite.plan.RelWriterTest;
import org.apache.calcite.plan.volcano.VolcanoPlannerTest;
import org.apache.calcite.plan.volcano.VolcanoPlannerTraitTest;
+import org.apache.calcite.rel.RelCollationTest;
import org.apache.calcite.rex.RexExecutorTest;
import org.apache.calcite.runtime.BinarySearchTest;
import org.apache.calcite.runtime.EnumerablesTest;
@@ -64,6 +65,7 @@ import org.junit.runners.Suite;
DirectedGraphTest.class,
ReflectVisitorTest.class,
RelOptUtilTest.class,
+ RelCollationTest.class,
UtilTest.class,
MappingTest.class,
CalciteResourceTest.class,
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/test/JdbcFrontJdbcBackLinqMiddleTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcFrontJdbcBackLinqMiddleTest.java b/core/src/test/java/org/apache/calcite/test/JdbcFrontJdbcBackLinqMiddleTest.java
index 540c6a8..3ef4dea 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcFrontJdbcBackLinqMiddleTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcFrontJdbcBackLinqMiddleTest.java
@@ -64,7 +64,7 @@ public class JdbcFrontJdbcBackLinqMiddleTest {
@Test public void testCase() {
that()
- .with(CalciteAssert.Config.JDBC_FOODMART)
+ .with(CalciteAssert.Config.FOODMART_CLONE)
.query("select \"day\",\n"
+ " \"week_day\",\n"
+ " case when \"day\" < 3 then upper(\"week_day\")\n"
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java b/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java
index c34becd..a6d23e0 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java
@@ -68,9 +68,9 @@ public class JdbcFrontLinqBackTest {
+ "from \"foodmart\".\"sales_fact_1997\" as s\n"
+ "join \"hr\".\"emps\" as e\n"
+ "on e.\"empid\" = s.\"cust_id\"")
- .returns(""
- + "cust_id=100; prod_id=10; empid=100; deptno=10; name=Bill; salary=10000.0; commission=1000\n"
- + "cust_id=150; prod_id=20; empid=150; deptno=10; name=Sebastian; salary=7000.0; commission=null\n");
+ .returnsUnordered(
+ "cust_id=100; prod_id=10; empid=100; deptno=10; name=Bill; salary=10000.0; commission=1000",
+ "cust_id=150; prod_id=20; empid=150; deptno=10; name=Sebastian; salary=7000.0; commission=null");
}
/**
@@ -93,6 +93,11 @@ public class JdbcFrontLinqBackTest {
.query("select upper(\"name\") as un, \"deptno\"\n"
+ "from \"hr\".\"emps\" as e\n"
+ "order by \"deptno\", \"name\" desc")
+ .explainContains(
+ "EnumerableCalc(expr#0..1=[{inputs}], expr#2=[UPPER($t1)], UN=[$t2], deptno=[$t0])\n"
+ + " EnumerableSort(sort0=[$0], sort1=[$1], dir0=[ASC], dir1=[DESC])\n"
+ + " EnumerableCalc(expr#0..4=[{inputs}], deptno=[$t1], name=[$t2])\n"
+ + " EnumerableTableScan(table=[[hr, emps]])")
.returns("UN=THEODORE; deptno=10\n"
+ "UN=SEBASTIAN; deptno=10\n"
+ "UN=BILL; deptno=10\n"
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/test/JdbcTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index 89c3b47..425cb6c 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -2542,6 +2542,26 @@ public class JdbcTest {
.returns("EMPNO=1; DESC=SameName\n");
}
+ /** Tests a merge-join. */
+ @Test public void testMergeJoin() {
+ CalciteAssert.that()
+ .with(CalciteAssert.Config.REGULAR)
+ .query("select \"emps\".\"empid\",\n"
+ + " \"depts\".\"deptno\", \"depts\".\"name\"\n"
+ + "from \"hr\".\"emps\"\n"
+ + " join \"hr\".\"depts\" using (\"deptno\")")
+ .explainContains(""
+ + "EnumerableCalc(expr#0..3=[{inputs}], empid=[$t2], deptno=[$t0], name=[$t1])\n"
+ + " EnumerableJoin(condition=[=($0, $3)], joinType=[inner])\n"
+ + " EnumerableCalc(expr#0..3=[{inputs}], proj#0..1=[{exprs}])\n"
+ + " EnumerableTableScan(table=[[hr, depts]])\n"
+ + " EnumerableCalc(expr#0..4=[{inputs}], proj#0..1=[{exprs}])\n"
+ + " EnumerableTableScan(table=[[hr, emps]])")
+ .returns("empid=100; deptno=10; name=Sales\n"
+ + "empid=150; deptno=10; name=Sales\n"
+ + "empid=110; deptno=10; name=Sales\n");
+ }
+
/** Tests a cartesian product aka cross join. */
@Test public void testCartesianJoin() {
CalciteAssert.hr()
@@ -2870,9 +2890,8 @@ public class JdbcTest {
+ "where \"store_id\" < 10\n"
+ "order by 1 fetch first 5 rows only")
.explainContains("PLAN=EnumerableLimit(fetch=[5])\n"
- + " EnumerableSort(sort0=[$0], dir0=[ASC])\n"
- + " EnumerableCalc(expr#0..23=[{inputs}], expr#24=[10], expr#25=[<($t0, $t24)], store_id=[$t0], grocery_sqft=[$t16], $condition=[$t25])\n"
- + " EnumerableTableScan(table=[[foodmart2, store]])\n")
+ + " EnumerableCalc(expr#0..23=[{inputs}], expr#24=[10], expr#25=[<($t0, $t24)], store_id=[$t0], grocery_sqft=[$t16], $condition=[$t25])\n"
+ + " EnumerableTableScan(table=[[foodmart2, store]])\n")
.returns("store_id=0; grocery_sqft=null\n"
+ "store_id=1; grocery_sqft=17475\n"
+ "store_id=2; grocery_sqft=22271\n"
@@ -3098,6 +3117,36 @@ public class JdbcTest {
.returnsCount(10);
}
+ /** ORDER BY on a sort-key does not require a sort. */
+ @Test public void testOrderOnSortedTable() throws IOException {
+ // The ArrayTable "store" is sorted by "store_id".
+ CalciteAssert.that()
+ .with(CalciteAssert.Config.FOODMART_CLONE)
+ .query("select \"day\"\n"
+ + "from \"days\"\n"
+ + "order by \"day\"")
+ .returns("day=1\n"
+ + "day=2\n"
+ + "day=3\n"
+ + "day=4\n"
+ + "day=5\n"
+ + "day=6\n"
+ + "day=7\n");
+ }
+
+ /** ORDER BY on a sort-key does not require a sort. */
+ @Test public void testOrderSorted() throws IOException {
+ // The ArrayTable "store" is sorted by "store_id".
+ CalciteAssert.that()
+ .with(CalciteAssert.Config.FOODMART_CLONE)
+ .query("select \"store_id\"\n"
+ + "from \"store\"\n"
+ + "order by \"store_id\" limit 3")
+ .returns("store_id=0\n"
+ + "store_id=1\n"
+ + "store_id=2\n");
+ }
+
@Test public void testWhereNot() throws IOException {
CalciteAssert.that()
.with(CalciteAssert.Config.FOODMART_CLONE)
@@ -3187,8 +3236,8 @@ public class JdbcTest {
.with(CalciteAssert.Config.FOODMART_CLONE)
.query("select * from \"time_by_day\"\n"
+ "order by \"time_id\"")
- .explainContains("PLAN=EnumerableSort(sort0=[$0], dir0=[ASC])\n"
- + " EnumerableTableScan(table=[[foodmart2, time_by_day]])\n\n");
+ .explainContains(
+ "PLAN=EnumerableTableScan(table=[[foodmart2, time_by_day]])\n");
}
/** Tests sorting by a column that is already sorted. */
@@ -4374,6 +4423,10 @@ public class JdbcTest {
checkRun("sql/sequence.oq");
}
+ @Test public void testRunSort() throws Exception {
+ checkRun("sql/sort.oq");
+ }
+
@Test public void testRunSubquery() throws Exception {
checkRun("sql/subquery.oq");
}
@@ -6256,8 +6309,7 @@ public class JdbcTest {
TableModify.Operation operation,
List<String> updateColumnList,
boolean flattened) {
- return new LogicalTableModify(
- cluster, table, catalogReader, child, operation,
+ return LogicalTableModify.create(table, catalogReader, child, operation,
updateColumnList, flattened);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/test/LatticeTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/LatticeTest.java b/core/src/test/java/org/apache/calcite/test/LatticeTest.java
index 86e8007..b51e51c 100644
--- a/core/src/test/java/org/apache/calcite/test/LatticeTest.java
+++ b/core/src/test/java/org/apache/calcite/test/LatticeTest.java
@@ -346,6 +346,32 @@ public class LatticeTest {
.returnsCount(4);
}
+ /** Tests a query that is created within {@link #testTileAlgorithm()}. */
+ @Test public void testJG() {
+ CalciteAssert.that().with(CalciteAssert.Config.JDBC_FOODMART)
+ .query(
+ "SELECT \"s\".\"unit_sales\", \"p\".\"recyclable_package\", \"t\".\"the_day\", \"t\".\"the_year\", \"t\".\"quarter\", \"pc\".\"product_family\", COUNT(*) AS \"m0\", SUM(\"s\".\"store_sales\") AS \"m1\", SUM(\"s\".\"unit_sales\") AS \"m2\"\n"
+ + "FROM \"foodmart\".\"sales_fact_1997\" AS \"s\"\n"
+ + "JOIN \"foodmart\".\"product\" AS \"p\" ON \"s\".\"product_id\" = \"p\".\"product_id\"\n"
+ + "JOIN \"foodmart\".\"time_by_day\" AS \"t\" ON \"s\".\"time_id\" = \"t\".\"time_id\"\n"
+ + "JOIN \"foodmart\".\"product_class\" AS \"pc\" ON \"p\".\"product_class_id\" = \"pc\".\"product_class_id\"\n"
+ + "GROUP BY \"s\".\"unit_sales\", \"p\".\"recyclable_package\", \"t\".\"the_day\", \"t\".\"the_year\", \"t\".\"quarter\", \"pc\".\"product_family\"")
+ .explainContains(
+ "EnumerableAggregate(group=[{0, 1, 2, 3, 4, 5}], m0=[COUNT()], m1=[SUM($6)], m2=[SUM($0)])\n"
+ + " EnumerableCalc(expr#0..37=[{inputs}], unit_sales=[$t17], recyclable_package=[$t26], the_day=[$t2], the_year=[$t4], quarter=[$t8], product_family=[$t37], store_sales=[$t15])\n"
+ + " EnumerableJoin(condition=[=($0, $11)], joinType=[inner])\n"
+ + " JdbcToEnumerableConverter\n"
+ + " JdbcTableScan(table=[[foodmart, time_by_day]])\n"
+ + " EnumerableJoin(condition=[=($8, $23)], joinType=[inner])\n"
+ + " EnumerableJoin(condition=[=($0, $9)], joinType=[inner])\n"
+ + " JdbcToEnumerableConverter\n"
+ + " JdbcTableScan(table=[[foodmart, sales_fact_1997]])\n"
+ + " JdbcToEnumerableConverter\n"
+ + " JdbcTableScan(table=[[foodmart, product]])\n"
+ + " JdbcToEnumerableConverter\n"
+ + " JdbcTableScan(table=[[foodmart, product_class]])");
+ }
+
/** Tests a query that uses no columns from the fact table. */
@Test public void testGroupByEmpty() {
foodmartModel()
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java b/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
index ed8e9a6..d5e94a9 100644
--- a/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
+++ b/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
@@ -22,7 +22,7 @@ import org.apache.calcite.plan.RelOptSchema;
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.prepare.Prepare;
import org.apache.calcite.rel.RelCollation;
-import org.apache.calcite.rel.RelCollationImpl;
+import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.logical.LogicalTableScan;
@@ -369,10 +369,8 @@ public class MockCatalogReader implements Prepare.CatalogReader {
? RelFieldCollation.Direction.DESCENDING
: RelFieldCollation.Direction.ASCENDING;
collationList.add(
- RelCollationImpl.of(
- new RelFieldCollation(
- i,
- direction,
+ RelCollations.of(
+ new RelFieldCollation(i, direction,
RelFieldCollation.NullDirection.UNSPECIFIED)));
}
}
@@ -442,7 +440,7 @@ public class MockCatalogReader implements Prepare.CatalogReader {
}
public RelNode toRel(ToRelContext context) {
- return new LogicalTableScan(context.getCluster(), this);
+ return LogicalTableScan.create(context.getCluster(), this);
}
public List<RelCollation> getCollationList() {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
index 3782957..0e60487 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -16,22 +16,49 @@
*/
package org.apache.calcite.test;
+import org.apache.calcite.adapter.enumerable.EnumerableMergeJoin;
+import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelOptSchema;
import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.rel.InvalidRelException;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
+import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Aggregate;
+import org.apache.calcite.rel.core.Join;
+import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rel.core.Project;
+import org.apache.calcite.rel.core.Sort;
import org.apache.calcite.rel.logical.LogicalAggregate;
import org.apache.calcite.rel.logical.LogicalFilter;
+import org.apache.calcite.rel.logical.LogicalProject;
+import org.apache.calcite.rel.logical.LogicalSort;
+import org.apache.calcite.rel.logical.LogicalTableScan;
+import org.apache.calcite.rel.logical.LogicalValues;
import org.apache.calcite.rel.metadata.CachingRelMetadataProvider;
import org.apache.calcite.rel.metadata.ChainedRelMetadataProvider;
import org.apache.calcite.rel.metadata.DefaultRelMetadataProvider;
import org.apache.calcite.rel.metadata.Metadata;
import org.apache.calcite.rel.metadata.ReflectiveRelMetadataProvider;
import org.apache.calcite.rel.metadata.RelColumnOrigin;
+import org.apache.calcite.rel.metadata.RelMdCollation;
import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.tools.Frameworks;
import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.ImmutableIntList;
+import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -41,6 +68,7 @@ import org.junit.Ignore;
import org.junit.Test;
import java.lang.reflect.Method;
+import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -635,6 +663,136 @@ public class RelMetadataTest extends SqlToRelTestBase {
assertThat(buf.size(), equalTo(7));
}
+ /** Unit test for
+ * {@link org.apache.calcite.rel.metadata.RelMdCollation#project}
+ * and other helper functions for deducing collations. */
+ @Test public void testCollation() {
+ final Project rel = (Project) convertSql("select * from emp, dept");
+ final Join join = (Join) rel.getInput();
+ final RelOptTable empTable = join.getInput(0).getTable();
+ final RelOptTable deptTable = join.getInput(1).getTable();
+ Frameworks.withPlanner(
+ new Frameworks.PlannerAction<Void>() {
+ public Void apply(RelOptCluster cluster,
+ RelOptSchema relOptSchema,
+ SchemaPlus rootSchema) {
+ checkCollation(cluster, empTable, deptTable);
+ return null;
+ }
+ });
+ }
+
+ private void checkCollation(RelOptCluster cluster, RelOptTable empTable,
+ RelOptTable deptTable) {
+ final RexBuilder rexBuilder = cluster.getRexBuilder();
+ final LogicalTableScan empScan = LogicalTableScan.create(cluster, empTable);
+
+ List<RelCollation> collations =
+ RelMdCollation.table(empScan.getTable());
+ assertThat(collations.size(), equalTo(0));
+
+ // ORDER BY field#0 ASC, field#1 ASC
+ final RelCollation collation =
+ RelCollations.of(new RelFieldCollation(0), new RelFieldCollation(1));
+ collations = RelMdCollation.sort(collation);
+ assertThat(collations.size(), equalTo(1));
+ assertThat(collations.get(0).getFieldCollations().size(), equalTo(2));
+
+ final Sort empSort = LogicalSort.create(empScan, collation, null, null);
+
+ final List<RexNode> projects =
+ ImmutableList.of(rexBuilder.makeInputRef(empSort, 1),
+ rexBuilder.makeLiteral("foo"),
+ rexBuilder.makeInputRef(empSort, 0),
+ rexBuilder.makeCall(SqlStdOperatorTable.MINUS,
+ rexBuilder.makeInputRef(empSort, 0),
+ rexBuilder.makeInputRef(empSort, 3)));
+
+ collations = RelMdCollation.project(empSort, projects);
+ assertThat(collations.size(), equalTo(1));
+ assertThat(collations.get(0).getFieldCollations().size(), equalTo(2));
+ assertThat(collations.get(0).getFieldCollations().get(0).getFieldIndex(),
+ equalTo(2));
+ assertThat(collations.get(0).getFieldCollations().get(1).getFieldIndex(),
+ equalTo(0));
+
+ final LogicalProject project = LogicalProject.create(empSort, projects,
+ ImmutableList.of("a", "b", "c", "d"));
+
+ final LogicalTableScan deptScan =
+ LogicalTableScan.create(cluster, deptTable);
+
+ final RelCollation deptCollation =
+ RelCollations.of(new RelFieldCollation(0), new RelFieldCollation(1));
+ final Sort deptSort =
+ LogicalSort.create(deptScan, deptCollation, null, null);
+
+ final ImmutableIntList leftKeys = ImmutableIntList.of(2);
+ final ImmutableIntList rightKeys = ImmutableIntList.of(0);
+ final EnumerableMergeJoin join;
+ try {
+ join = EnumerableMergeJoin.create(project, deptSort,
+ rexBuilder.makeLiteral(true), leftKeys, rightKeys, JoinRelType.INNER);
+ } catch (InvalidRelException e) {
+ throw Throwables.propagate(e);
+ }
+ collations =
+ RelMdCollation.mergeJoin(project, deptSort, leftKeys, rightKeys);
+ assertThat(collations,
+ equalTo(join.getTraitSet().getTraits(RelCollationTraitDef.INSTANCE)));
+
+ // Values (empty)
+ collations = RelMdCollation.values(empTable.getRowType(),
+ ImmutableList.<ImmutableList<RexLiteral>>of());
+ assertThat(collations.toString(),
+ equalTo("[[0, 1, 2, 3, 4, 5, 6, 7, 8], "
+ + "[1, 2, 3, 4, 5, 6, 7, 8], "
+ + "[2, 3, 4, 5, 6, 7, 8], "
+ + "[3, 4, 5, 6, 7, 8], "
+ + "[4, 5, 6, 7, 8], "
+ + "[5, 6, 7, 8], "
+ + "[6, 7, 8], "
+ + "[7, 8], "
+ + "[8]]"));
+
+ final LogicalValues emptyValues =
+ LogicalValues.createEmpty(cluster, empTable.getRowType());
+ assertThat(RelMetadataQuery.collations(emptyValues), equalTo(collations));
+
+ // Values (non-empty)
+ final RelDataType rowType = cluster.getTypeFactory().builder()
+ .add("a", SqlTypeName.INTEGER)
+ .add("b", SqlTypeName.INTEGER)
+ .add("c", SqlTypeName.INTEGER)
+ .add("d", SqlTypeName.INTEGER)
+ .build();
+ final ImmutableList.Builder<ImmutableList<RexLiteral>> tuples =
+ ImmutableList.builder();
+ // sort keys are [a], [a, b], [a, b, c], [a, b, c, d], [a, c], [b], [b, a],
+ // [b, d]
+ // algorithm deduces [a, b, c, d], [b, d] which is a useful sub-set
+ addRow(tuples, rexBuilder, 1, 1, 1, 1);
+ addRow(tuples, rexBuilder, 1, 2, 0, 3);
+ addRow(tuples, rexBuilder, 2, 3, 2, 2);
+ addRow(tuples, rexBuilder, 3, 3, 1, 4);
+ collations = RelMdCollation.values(rowType, tuples.build());
+ assertThat(collations.toString(),
+ equalTo("[[0, 1, 2, 3], [1, 3]]"));
+
+ final LogicalValues values =
+ LogicalValues.create(cluster, rowType, tuples.build());
+ assertThat(RelMetadataQuery.collations(values), equalTo(collations));
+ }
+
+ private void addRow(ImmutableList.Builder<ImmutableList<RexLiteral>> builder,
+ RexBuilder rexBuilder, Object... values) {
+ ImmutableList.Builder<RexLiteral> b = ImmutableList.builder();
+ for (Object value : values) {
+ b.add(rexBuilder.makeExactLiteral(BigDecimal.valueOf((Integer) value)));
+ }
+ builder.add(b.build());
+ }
+
/** Custom metadata interface. */
public interface ColType extends Metadata {
String getColType(int column);
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java b/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
index 1eb6b8c..4b51753 100644
--- a/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
+++ b/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
@@ -127,7 +127,7 @@ public class ScannableTableTest {
resultSet.close();
// Only 2 rows came out of the table. If the value is 4, it means that the
// planner did not pass the filter down.
- assertThat(buf.toString(), equalTo("returnCount=2"));
+ assertThat(buf.toString(), equalTo("returnCount=2, filter=4"));
buf.setLength(0);
// Now with an "uncooperative" filterable table that refuses to accept
@@ -161,7 +161,7 @@ public class ScannableTableTest {
resultSet.close();
// Only 2 rows came out of the table. If the value is 4, it means that the
// planner did not pass the filter down.
- assertThat(buf.toString(), equalTo("returnCount=2"));
+ assertThat(buf.toString(), equalTo("returnCount=2, filter=4"));
buf.setLength(0);
// Now with an "uncooperative" filterable table that refuses to accept
@@ -195,7 +195,8 @@ public class ScannableTableTest {
assertThat(CalciteAssert.toString(resultSet),
equalTo("k=1940; j=John\nk=1942; j=Paul\n"));
resultSet.close();
- assertThat(buf.toString(), equalTo("returnCount=2, projects=[2, 1]"));
+ assertThat(buf.toString(),
+ equalTo("returnCount=2, filter=4, projects=[2, 1]"));
buf.setLength(0);
// Filter on one of the projected columns.
@@ -467,6 +468,9 @@ public class ScannableTableTest {
public void close() {
current = null;
buf.append("returnCount=").append(returnCount);
+ if (filter != null) {
+ buf.append(", filter=").append(filter);
+ }
if (projects != null) {
buf.append(", projects=").append(Arrays.toString(projects));
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java b/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
index 32e2dbe..180f877 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
@@ -24,7 +24,7 @@ import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.prepare.Prepare;
import org.apache.calcite.rel.RelCollation;
-import org.apache.calcite.rel.RelCollationImpl;
+import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.logical.LogicalTableScan;
@@ -248,10 +248,8 @@ public abstract class SqlToRelTestBase {
? RelFieldCollation.Direction.DESCENDING
: RelFieldCollation.Direction.ASCENDING;
collationList.add(
- RelCollationImpl.of(
- new RelFieldCollation(
- i,
- direction,
+ RelCollations.of(
+ new RelFieldCollation(i, direction,
RelFieldCollation.NullDirection.UNSPECIFIED)));
}
}
@@ -344,9 +342,8 @@ public abstract class SqlToRelTestBase {
return MockRelOptSchema.this;
}
- public RelNode toRel(
- ToRelContext context) {
- return new LogicalTableScan(context.getCluster(), this);
+ public RelNode toRel(ToRelContext context) {
+ return LogicalTableScan.create(context.getCluster(), this);
}
public List<RelCollation> getCollationList() {
@@ -411,7 +408,7 @@ public abstract class SqlToRelTestBase {
}
public RelNode toRel(ToRelContext context) {
- return new LogicalTableScan(context.getCluster(), this);
+ return LogicalTableScan.create(context.getCluster(), this);
}
public List<RelCollation> getCollationList() {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java b/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java
index e882fc2..288adf3 100644
--- a/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java
+++ b/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java
@@ -93,13 +93,13 @@ public class FrameworksTest {
rexBuilder.makeRangeReference(tableRel), "i", true),
rexBuilder.makeExactLiteral(BigDecimal.ONE));
final LogicalFilter filter =
- new LogicalFilter(cluster, tableRel, condition);
+ LogicalFilter.create(tableRel, condition);
// Specify that the result should be in Enumerable convention.
final RelNode rootRel = filter;
final RelOptPlanner planner = cluster.getPlanner();
- RelTraitSet desiredTraits = rootRel.getTraitSet().replace(
- EnumerableConvention.INSTANCE);
+ RelTraitSet desiredTraits =
+ cluster.traitSet().replace(EnumerableConvention.INSTANCE);
final RelNode rootRel2 = planner.changeTraits(rootRel,
desiredTraits);
planner.setRoot(rootRel2);
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/tools/PlannerTest.java b/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
index 54bee88..701d66a 100644
--- a/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
+++ b/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
@@ -352,7 +352,7 @@ public class PlannerTest {
/** Unit test that parses, validates, converts and
* plans for query using two duplicate order by.
- * The duplicate order by should be removed by SortRemoveRule*/
+ * The duplicate order by should be removed by SortRemoveRule. */
@Test public void testDuplicateSortPlan() throws Exception {
RuleSet ruleSet =
RuleSets.ofList(
@@ -370,6 +370,10 @@ public class PlannerTest {
RelNode convert = planner.convert(validate);
RelTraitSet traitSet = planner.getEmptyTraitSet()
.replace(EnumerableConvention.INSTANCE);
+ if (traitSet.getTrait(RelCollationTraitDef.INSTANCE) == null) {
+ // SortRemoveRule can only work if collation trait is enabled.
+ return;
+ }
RelNode transform = planner.transform(0, traitSet, convert);
assertThat(toString(transform),
equalTo("EnumerableProject(empid=[$0])\n"
@@ -721,6 +725,7 @@ public class PlannerTest {
+ "cross join \"department\"",
"EnumerableProject(product_id=[$0], time_id=[$1], customer_id=[$2], promotion_id=[$3], store_id=[$4], store_sales=[$5], store_cost=[$6], unit_sales=[$7], customer_id0=[$8], account_num=[$9], lname=[$10], fname=[$11], mi=[$12], address1=[$13], address2=[$14], address3=[$15], address4=[$16], city=[$17], state_province=[$18], postal_code=[$19], country=[$20], customer_region_id=[$21], phone1=[$22], phone2=[$23], birthdate=[$24], marital_status=[$25], yearly_income=[$26], gender=[$27], total_children=[$28], num_children_at_home=[$29], education=[$30], date_accnt_opened=[$31], member_card=[$32], occupation=[$33], houseowner=[$34], num_cars_owned=[$35], fullname=[$36], department_id=[$37], department_description=[$38])\n"
+ " EnumerableProject($f0=[$31], $f1=[$32], $f2=[$33], $f3=[$34], $f4=[$35], $f5=[$36], $f6=[$37], $f7=[$38], $f8=[$2], $f9=[$3], $f10=[$4], $f11=[$5], $f12=[$6], $f13=[$7], $f14=[$8], $f15=[$9], $f16=[$10], $f17=[$11], $f18=[$12], $f19=[$13], $f20=[$14], $f21=[$15], $f22=[$16], $f23=[$17], $f24=[$18], $f25=[$19], $f26=[$20], $f27=[$21], $f28=[$22], $f29=[$23], $f30=[$24], $f31=[$25], $f32=[$26], $f33=[$27], $f34=[$28], $f35=[$29], $f36=[$30], $f37=[$0], $f38=[$1])\n"
+ //+ " EnumerableMergeJoin(condition=[true], joinType=[inner])\n"
+ " EnumerableJoin(condition=[true], joinType=[inner])\n"
+ " EnumerableTableScan(table=[[foodmart2, department]])\n"
+ " EnumerableJoin(condition=[=($0, $31)], joinType=[inner])\n"
@@ -737,6 +742,7 @@ public class PlannerTest {
+ "join \"employee\" using (\"department_id\")",
"EnumerableProject(product_id=[$0], time_id=[$1], customer_id=[$2], promotion_id=[$3], store_id=[$4], store_sales=[$5], store_cost=[$6], unit_sales=[$7], customer_id0=[$8], account_num=[$9], lname=[$10], fname=[$11], mi=[$12], address1=[$13], address2=[$14], address3=[$15], address4=[$16], city=[$17], state_province=[$18], postal_code=[$19], country=[$20], customer_region_id=[$21], phone1=[$22], phone2=[$23], birthdate=[$24], marital_status=[$25], yearly_income=[$26], gender=[$27], total_children=[$28], num_children_at_home=[$29], education=[$30], date_accnt_opened=[$31], member_card=[$32], occupation=[$33], houseowner=[$34], num_cars_owned=[$35], fullname=[$36], department_id=[$37], department_description=[$38], employee_id=[$39], full_name=[$40], first_name=[$41], last_name=[$42], position_id=[$43], position_title=[$44], store_id0=[$45], department_id0=[$46], birth_date=[$47], hire_date=[$48], end_date=[$49], salary=[$50], supervisor_id=[$51], education_level=[$52], marita
l_status0=[$53], gender0=[$54], management_role=[$55])\n"
+ " EnumerableProject($f0=[$48], $f1=[$49], $f2=[$50], $f3=[$51], $f4=[$52], $f5=[$53], $f6=[$54], $f7=[$55], $f8=[$19], $f9=[$20], $f10=[$21], $f11=[$22], $f12=[$23], $f13=[$24], $f14=[$25], $f15=[$26], $f16=[$27], $f17=[$28], $f18=[$29], $f19=[$30], $f20=[$31], $f21=[$32], $f22=[$33], $f23=[$34], $f24=[$35], $f25=[$36], $f26=[$37], $f27=[$38], $f28=[$39], $f29=[$40], $f30=[$41], $f31=[$42], $f32=[$43], $f33=[$44], $f34=[$45], $f35=[$46], $f36=[$47], $f37=[$0], $f38=[$1], $f39=[$2], $f40=[$3], $f41=[$4], $f42=[$5], $f43=[$6], $f44=[$7], $f45=[$8], $f46=[$9], $f47=[$10], $f48=[$11], $f49=[$12], $f50=[$13], $f51=[$14], $f52=[$15], $f53=[$16], $f54=[$17], $f55=[$18])\n"
+ // + " EnumerableMergeJoin(condition=[true], joinType=[inner])\n"
+ " EnumerableJoin(condition=[true], joinType=[inner])\n"
+ " EnumerableJoin(condition=[=($0, $9)], joinType=[inner])\n"
+ " EnumerableTableScan(table=[[foodmart2, department]])\n"
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/java/org/apache/calcite/util/ImmutableBitSetTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/util/ImmutableBitSetTest.java b/core/src/test/java/org/apache/calcite/util/ImmutableBitSetTest.java
index 7f2b984..605817c 100644
--- a/core/src/test/java/org/apache/calcite/util/ImmutableBitSetTest.java
+++ b/core/src/test/java/org/apache/calcite/util/ImmutableBitSetTest.java
@@ -425,6 +425,22 @@ public class ImmutableBitSetTest {
assertThat(ImmutableBitSet.valueOf(LongBuffer.wrap(bitSet.toLongArray())),
equalTo(bitSet));
}
+
+ @Test public void testSet() {
+ final ImmutableBitSet bitSet = ImmutableBitSet.of(29, 4, 1969);
+ assertThat(bitSet.set(30),
+ equalTo(ImmutableBitSet.of(29, 4, 1969, 30)));
+ assertThat(bitSet.set(29),
+ equalTo(bitSet));
+ }
+
+ @Test public void testClear() {
+ final ImmutableBitSet bitSet = ImmutableBitSet.of(29, 4, 1969);
+ assertThat(bitSet.clear(29),
+ equalTo(ImmutableBitSet.of(4, 1969)));
+ assertThat(bitSet.clear(29).clear(4).clear(29).clear(1969),
+ equalTo(ImmutableBitSet.of()));
+ }
}
// End ImmutableBitSetTest.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/core/src/test/resources/sql/sort.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/sort.oq b/core/src/test/resources/sql/sort.oq
new file mode 100644
index 0000000..df6e385
--- /dev/null
+++ b/core/src/test/resources/sql/sort.oq
@@ -0,0 +1,71 @@
+# sort.oq - Sorting and collation
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+!use foodmart
+!set outputformat mysql
+
+# The ArrayTable "days" is sorted by "day", so plan must not contain sort
+select * from "days" order by "day";
++-----+-----------+
+| day | week_day |
++-----+-----------+
+| 1 | Sunday |
+| 2 | Monday |
+| 3 | Tuesday |
+| 4 | Wednesday |
+| 5 | Thursday |
+| 6 | Friday |
+| 7 | Saturday |
++-----+-----------+
+(7 rows)
+
+!ok
+EnumerableTableScan(table=[[foodmart2, days]])
+!plan
+
+# The ArrayTable "days" is sorted by "day", so the plan does not sort, only applies limit
+select * from "days" order by "day" limit 2;
++-----+----------+
+| day | week_day |
++-----+----------+
+| 1 | Sunday |
+| 2 | Monday |
++-----+----------+
+(2 rows)
+
+!ok
+EnumerableLimit(fetch=[2])
+ EnumerableTableScan(table=[[foodmart2, days]])
+!plan
+
+# The ArrayTable "days" is sorted by "day", so the plan must not contain Sort
+select * from "days" where "day" between 2 and 4 order by "day";
++-----+-----------+
+| day | week_day |
++-----+-----------+
+| 2 | Monday |
+| 3 | Tuesday |
+| 4 | Wednesday |
++-----+-----------+
+(3 rows)
+
+!ok
+EnumerableCalc(expr#0..1=[{inputs}], expr#2=[2], expr#3=[>=($t0, $t2)], expr#4=[4], expr#5=[<=($t0, $t4)], expr#6=[AND($t3, $t5)], proj#0..1=[{exprs}], $condition=[$t6])
+ EnumerableTableScan(table=[[foodmart2, days]])
+!plan
+
+# End sort.oq
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/linq4j/src/main/java/org/apache/calcite/linq4j/Ord.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/Ord.java b/linq4j/src/main/java/org/apache/calcite/linq4j/Ord.java
index 18aa812..c7eedf5 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/Ord.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/Ord.java
@@ -17,10 +17,10 @@
package org.apache.calcite.linq4j;
import java.util.AbstractList;
-import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.RandomAccess;
/**
* Pair of an element and an ordinal.
@@ -49,7 +49,7 @@ public class Ord<E> implements Map.Entry<Integer, E> {
/**
* Creates an iterable of {@code Ord}s over an iterable.
*/
- public static <E> Iterable<Ord<E>> zip(final Iterable<E> iterable) {
+ public static <E> Iterable<Ord<E>> zip(final Iterable<? extends E> iterable) {
return new Iterable<Ord<E>>() {
public Iterator<Ord<E>> iterator() {
return zip(iterable.iterator());
@@ -60,7 +60,7 @@ public class Ord<E> implements Map.Entry<Integer, E> {
/**
* Creates an iterator of {@code Ord}s over an iterator.
*/
- public static <E> Iterator<Ord<E>> zip(final Iterator<E> iterator) {
+ public static <E> Iterator<Ord<E>> zip(final Iterator<? extends E> iterator) {
return new Iterator<Ord<E>>() {
int n = 0;
@@ -82,22 +82,16 @@ public class Ord<E> implements Map.Entry<Integer, E> {
* Returns a numbered list based on an array.
*/
public static <E> List<Ord<E>> zip(final E[] elements) {
- return zip(Arrays.asList(elements));
+ return new OrdArrayList<E>(elements);
}
/**
* Returns a numbered list.
*/
- public static <E> List<Ord<E>> zip(final List<E> elements) {
- return new AbstractList<Ord<E>>() {
- public Ord<E> get(int index) {
- return of(index, elements.get(index));
- }
-
- public int size() {
- return elements.size();
- }
- };
+ public static <E> List<Ord<E>> zip(final List<? extends E> elements) {
+ return elements instanceof RandomAccess
+ ? new OrdRandomAccessList<E>(elements)
+ : new OrdList<E>(elements);
}
public Integer getKey() {
@@ -111,6 +105,49 @@ public class Ord<E> implements Map.Entry<Integer, E> {
public E setValue(E value) {
throw new UnsupportedOperationException();
}
+
+ /** List of {@link Ord} backed by a list of elements. */
+ private static class OrdList<E> extends AbstractList<Ord<E>> {
+ private final List<? extends E> elements;
+
+ public OrdList(List<? extends E> elements) {
+ this.elements = elements;
+ }
+
+ public Ord<E> get(int index) {
+ return of(index, elements.get(index));
+ }
+
+ public int size() {
+ return elements.size();
+ }
+ }
+
+ /** List of {@link Ord} backed by a random-access list of elements. */
+ private static class OrdRandomAccessList<E> extends OrdList<E>
+ implements RandomAccess {
+ public OrdRandomAccessList(List<? extends E> elements) {
+ super(elements);
+ }
+ }
+
+ /** List of {@link Ord} backed by an array of elements. */
+ private static class OrdArrayList<E> extends AbstractList<Ord<E>>
+ implements RandomAccess {
+ private final E[] elements;
+
+ public OrdArrayList(E[] elements) {
+ this.elements = elements;
+ }
+
+ @Override public Ord<E> get(int index) {
+ return Ord.of(index, elements[index]);
+ }
+
+ @Override public int size() {
+ return elements.length;
+ }
+ }
}
// End Ord.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoRules.java
----------------------------------------------------------------------
diff --git a/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoRules.java b/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoRules.java
index f67e0ee..0ccee35 100644
--- a/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoRules.java
+++ b/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoRules.java
@@ -24,7 +24,7 @@ import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelTrait;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.InvalidRelException;
-import org.apache.calcite.rel.RelCollationImpl;
+import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.convert.ConverterRule;
import org.apache.calcite.rel.core.Sort;
@@ -216,7 +216,7 @@ public class MongoRules {
sort.getTraitSet().replace(out)
.replace(sort.getCollation());
return new MongoSort(rel.getCluster(), traitSet,
- convert(sort.getInput(), traitSet.replace(RelCollationImpl.EMPTY)),
+ convert(sort.getInput(), traitSet.replace(RelCollations.EMPTY)),
sort.getCollation(), sort.offset, sort.fetch);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2709896e/splunk/src/main/java/org/apache/calcite/adapter/splunk/SplunkPushDownRule.java
----------------------------------------------------------------------
diff --git a/splunk/src/main/java/org/apache/calcite/adapter/splunk/SplunkPushDownRule.java b/splunk/src/main/java/org/apache/calcite/adapter/splunk/SplunkPushDownRule.java
index 2976f87..d432466 100644
--- a/splunk/src/main/java/org/apache/calcite/adapter/splunk/SplunkPushDownRule.java
+++ b/splunk/src/main/java/org/apache/calcite/adapter/splunk/SplunkPushDownRule.java
@@ -20,7 +20,6 @@ import org.apache.calcite.adapter.splunk.util.StringUtils;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelOptRuleOperand;
-import org.apache.calcite.rel.RelCollationImpl;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.logical.LogicalFilter;
import org.apache.calcite.rel.logical.LogicalProject;
@@ -279,13 +278,7 @@ public class SplunkPushDownRule
if (proj == null) {
return rel;
}
- return new LogicalProject(
- proj.getCluster(),
- proj.getCluster().traitSetOf(
- proj.getCollationList().isEmpty()
- ? RelCollationImpl.EMPTY
- : proj.getCollationList().get(0)),
- rel, proj.getProjects(), proj.getRowType());
+ return LogicalProject.create(rel, proj.getProjects(), proj.getRowType());
}
// TODO: use StringBuilder instead of String