Skip to content

Commit

Permalink
Complete [CALCITE-783] by fixing some planner rules
Browse files Browse the repository at this point in the history
  • Loading branch information
julianhyde committed Jul 21, 2015
1 parent c711fed commit 9177063
Show file tree
Hide file tree
Showing 13 changed files with 79 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public RelNode convert(RelNode rel) {
return new EnumerableAggregate(
rel.getCluster(),
traitSet,
convert(agg.getInput(), traitSet),
convert(agg.getInput(), EnumerableConvention.INSTANCE),
agg.indicator,
agg.getGroupSet(),
agg.getGroupSets(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import org.apache.calcite.plan.Convention;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.convert.ConverterRule;
import org.apache.calcite.rel.logical.LogicalProject;
Expand All @@ -34,6 +36,16 @@ class EnumerableProjectRule extends ConverterRule {

public RelNode convert(RelNode rel) {
final LogicalProject project = (LogicalProject) rel;
if (rel.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE)
!= RelCollations.PRESERVE) {
return EnumerableProject.create(
convert(project.getInput(),
project.getInput().getTraitSet()
.replace(EnumerableConvention.INSTANCE)),
project.getProjects(),
project.getRowType());
}
// Special case for PRESERVE, to hand-create collation.
return new EnumerableProject(rel.getCluster(),
rel.getTraitSet().replace(EnumerableConvention.INSTANCE),
convert(project.getInput(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ public RelNode convert(RelNode rel) {
agg.getTraitSet().replace(out);
try {
return new JdbcAggregate(rel.getCluster(), traitSet,
convert(agg.getInput(), traitSet), agg.indicator, agg.getGroupSet(),
convert(agg.getInput(), out), agg.indicator, agg.getGroupSet(),
agg.getGroupSets(), agg.getAggCallList());
} catch (InvalidRelException e) {
LOGGER.fine(e.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,33 +290,13 @@ public SqlMonotonicity getMonotonicity(String columnName) {
final RelFieldCollation fieldCollation =
collation.getFieldCollations().get(0);
if (fieldCollation.getFieldIndex() == i) {
return monotonicity(fieldCollation.direction);
return fieldCollation.direction.monotonicity();
}
}
}
return SqlMonotonicity.NOT_MONOTONIC;
}

/** Converts a {@link org.apache.calcite.rel.RelFieldCollation.Direction}
* value to a {@link org.apache.calcite.sql.validate.SqlMonotonicity}. */
private static SqlMonotonicity
monotonicity(RelFieldCollation.Direction direction) {
switch (direction) {
case ASCENDING:
return SqlMonotonicity.INCREASING;
case STRICTLY_ASCENDING:
return SqlMonotonicity.STRICTLY_INCREASING;
case DESCENDING:
return SqlMonotonicity.DECREASING;
case STRICTLY_DESCENDING:
return SqlMonotonicity.STRICTLY_DECREASING;
case CLUSTERED:
return SqlMonotonicity.MONOTONIC;
default:
throw new AssertionError("unknown: " + direction);
}
}

public SqlAccessType getAllowedAccess() {
return SqlAccessType.ALL;
}
Expand Down
39 changes: 39 additions & 0 deletions core/src/main/java/org/apache/calcite/rel/RelFieldCollation.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.apache.calcite.rel;

import org.apache.calcite.sql.validate.SqlMonotonicity;

/**
* Definition of the ordering of one field of a {@link RelNode} whose
* output is to be sorted.
Expand Down Expand Up @@ -81,6 +83,43 @@ public enum Direction {
Direction(String shortString) {
this.shortString = shortString;
}

/** Converts thie direction to a
* {@link org.apache.calcite.sql.validate.SqlMonotonicity}. */
public SqlMonotonicity monotonicity() {
switch (this) {
case ASCENDING:
return SqlMonotonicity.INCREASING;
case STRICTLY_ASCENDING:
return SqlMonotonicity.STRICTLY_INCREASING;
case DESCENDING:
return SqlMonotonicity.DECREASING;
case STRICTLY_DESCENDING:
return SqlMonotonicity.STRICTLY_DECREASING;
case CLUSTERED:
return SqlMonotonicity.MONOTONIC;
default:
throw new AssertionError("unknown: " + this);
}
}

/** Converts a {@link SqlMonotonicity} to a direction. */
public static Direction of(SqlMonotonicity monotonicity) {
switch (monotonicity) {
case INCREASING:
return ASCENDING;
case DECREASING:
return DESCENDING;
case STRICTLY_INCREASING:
return STRICTLY_ASCENDING;
case STRICTLY_DECREASING:
return STRICTLY_DESCENDING;
case MONOTONIC:
return CLUSTERED;
default:
throw new AssertionError("unknown: " + monotonicity);
}
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -219,13 +220,20 @@ public static List<RelCollation> project(RelNode input,
collations.add(RelCollations.of(fieldCollations));
}

final List<RelFieldCollation> fieldCollationsForRexCalls = Lists.newArrayList();
for (Map.Entry<Integer, SqlMonotonicity> targetMonotonicity
final List<RelFieldCollation> fieldCollationsForRexCalls =
new ArrayList<>();
for (Map.Entry<Integer, SqlMonotonicity> entry
: targetsWithMonotonicity.entrySet()) {
if (targetMonotonicity.getValue() != SqlMonotonicity.NOT_MONOTONIC
&& targetMonotonicity.getValue() != SqlMonotonicity.CONSTANT) {
fieldCollationsForRexCalls.add(new RelFieldCollation(targetMonotonicity.getKey(),
monotonicityToDirection(targetMonotonicity.getValue())));
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;
}
}

Expand All @@ -236,24 +244,6 @@ public static List<RelCollation> project(RelNode input,
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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ private RexNode reduceSum(
argType, argType.isNullable());
final AggregateCall sumZeroCall =
AggregateCall.create(SqlStdOperatorTable.SUM0, oldCall.isDistinct(),
oldCall.getArgList(), oldCall.filterArg, sumType, null);
oldCall.getArgList(), oldCall.filterArg, sumType, oldCall.name);
final AggregateCall countCall =
AggregateCall.create(
SqlStdOperatorTable.COUNT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void onMatch(RelOptRuleCall call) {
// Distinct is "GROUP BY c1, c2" (where c1, c2 are a set of columns on
// which the input is unique, i.e. contain a key) and has no aggregate
// functions. It can be removed.
final RelNode newInput = convert(input, aggregate.getTraitSet());
final RelNode newInput = convert(input, aggregate.getTraitSet().simplify());

// If aggregate was projecting a subset of columns, add a project for the
// same effect.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ protected TrimResult trimChild(
fieldsUsed = ImmutableBitSet.range(input.getRowType().getFieldCount());
}
final ImmutableList<RelCollation> collations =
RelMetadataQuery.collations(rel);
RelMetadataQuery.collations(input);
for (RelCollation collation : collations) {
for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
fieldsUsed = fieldsUsed.set(fieldCollation.getFieldIndex());
Expand Down
2 changes: 1 addition & 1 deletion core/src/test/java/org/apache/calcite/test/JdbcTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3332,7 +3332,7 @@ private void checkNullableTimestamp(CalciteAssert.Config config) {
+ "where \"deptno\" < 0")
.explainContains(""
+ "PLAN=EnumerableCalc(expr#0..1=[{inputs}], expr#2=[0], expr#3=[=($t0, $t2)], expr#4=[null], expr#5=[CASE($t3, $t4, $t1)], expr#6=[/($t5, $t0)], expr#7=[CAST($t6):JavaType(class java.lang.Integer)], CS=[$t0], C=[$t0], S=[$t5], A=[$t7])\n"
+ " EnumerableAggregate(group=[{}], CS=[COUNT()], agg#1=[$SUM0($1)])\n"
+ " EnumerableAggregate(group=[{}], CS=[COUNT()], S=[$SUM0($1)])\n"
+ " EnumerableCalc(expr#0..4=[{inputs}], expr#5=[0], expr#6=[<($t1, $t5)], proj#0..4=[{exprs}], $condition=[$t6])\n"
+ " EnumerableTableScan(table=[[hr, emps]])\n")
.returns("CS=0; C=0; S=null; A=null\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ private void checkTileAlgorithm(String statisticProvider,
+ "GROUP BY \"s\".\"unit_sales\", \"p\".\"recyclable_package\", \"t\".\"the_day\", \"t\".\"the_year\", \"t\".\"quarter\", \"pc\".\"product_family\"")
.explainContains(
"JdbcToEnumerableConverter\n"
+ " JdbcAggregate(group=[{7, 16, 25, 27, 31, 37}], m0=[COUNT()], m1=[SUM($5)], m2=[SUM($7)])\n"
+ " JdbcAggregate(group=[{7, 16, 25, 27, 31, 37}], m0=[COUNT()], m1=[$SUM0($5)], m2=[$SUM0($7)])\n"
+ " JdbcJoin(condition=[=($8, $33)], joinType=[inner])\n"
+ " JdbcJoin(condition=[=($1, $23)], joinType=[inner])\n"
+ " JdbcJoin(condition=[=($0, $9)], joinType=[inner])\n"
Expand Down
10 changes: 5 additions & 5 deletions core/src/test/resources/sql/join.oq
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@ from "scott".emp join "scott".dept using (deptno);

!ok
EnumerableAggregate(group=[{0}])
EnumerableJoin(condition=[=($0, $1)], joinType=[inner])
EnumerableJoin(condition=[=($0, $2)], joinType=[inner])
EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
EnumerableTableScan(table=[[scott, DEPT]])
EnumerableCalc(expr#0..7=[{inputs}], DEPTNO=[$t7])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], DEPTNO=[$t7])
EnumerableTableScan(table=[[scott, EMP]])
!plan

Expand Down Expand Up @@ -227,11 +227,11 @@ where e.deptno + 10 = d.deptno * 2;
(9 rows)

!ok
EnumerableCalc(expr#0..3=[{inputs}], DEPTNO=[$t2], DEPTNO0=[$t0])
EnumerableJoin(condition=[=($1, $3)], joinType=[inner])
EnumerableCalc(expr#0..4=[{inputs}], DEPTNO=[$t3], DEPTNO0=[$t0])
EnumerableJoin(condition=[=($1, $4)], joinType=[inner])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[2], expr#4=[*($t0, $t3)], DEPTNO=[$t0], $f1=[$t4])
EnumerableTableScan(table=[[scott, DEPT]])
EnumerableCalc(expr#0..7=[{inputs}], expr#8=[10], expr#9=[+($t7, $t8)], DEPTNO=[$t7], $f1=[$t9])
EnumerableCalc(expr#0..7=[{inputs}], expr#8=[10], expr#9=[+($t7, $t8)], EMPNO=[$t0], DEPTNO=[$t7], $f2=[$t9])
EnumerableTableScan(table=[[scott, EMP]])
!plan

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ public RelNode convert(RelNode rel) {
return new MongoAggregate(
rel.getCluster(),
traitSet,
convert(agg.getInput(), traitSet),
convert(agg.getInput(), traitSet.simplify()),
agg.indicator,
agg.getGroupSet(),
agg.getGroupSets(),
Expand Down

0 comments on commit 9177063

Please sign in to comment.