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 2014/07/03 06:56:15 UTC
[1/2] git commit: [OPTIQ-327] Rules should use base class to find
rule match & use factory for object creation
Repository: incubator-optiq
Updated Branches:
refs/heads/master 0bf85206b -> c34c14487
[OPTIQ-327] Rules should use base class to find rule match & use factory for object creation
Project: http://git-wip-us.apache.org/repos/asf/incubator-optiq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-optiq/commit/e5188ec8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-optiq/tree/e5188ec8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-optiq/diff/e5188ec8
Branch: refs/heads/master
Commit: e5188ec851e2513f7cd915b7917d605071567426
Parents: 0bf8520
Author: Julian Hyde <ju...@gmail.com>
Authored: Wed Jul 2 16:36:38 2014 -0700
Committer: Julian Hyde <ju...@gmail.com>
Committed: Wed Jul 2 21:30:07 2014 -0700
----------------------------------------------------------------------
.../hydromatic/optiq/impl/jdbc/JdbcRules.java | 3 +-
.../hydromatic/optiq/rules/java/JavaRules.java | 3 +-
.../java/org/eigenbase/rel/CorrelatorRel.java | 2 +-
.../main/java/org/eigenbase/rel/JoinRel.java | 26 ++-----
.../java/org/eigenbase/rel/JoinRelBase.java | 19 ++++-
.../java/org/eigenbase/rel/RelFactories.java | 53 ++++++++++++-
.../org/eigenbase/rel/RelImplementorImpl.java | 2 +-
.../rel/rules/AddRedundantSemiJoinRule.java | 23 +++---
.../rel/rules/ConvertMultiJoinRule.java | 59 +++++++-------
.../rel/rules/ExtractJoinFilterRule.java | 38 +++++----
.../org/eigenbase/rel/rules/LoptJoinTree.java | 8 +-
.../rel/rules/LoptOptimizeJoinRule.java | 28 +++----
.../rel/rules/PullUpProjectsAboveJoinRule.java | 6 +-
.../rel/rules/PushFilterPastJoinRule.java | 22 +++---
.../rel/rules/PushJoinThroughJoinRule.java | 33 ++++----
.../rel/rules/PushJoinThroughUnionRule.java | 38 ++++-----
.../rel/rules/PushProjectPastJoinRule.java | 37 ++++-----
.../rel/rules/PushSemiJoinPastJoinRule.java | 58 +++++++-------
.../rel/rules/ReduceExpressionsRule.java | 12 +--
.../rel/rules/RemoveDistinctAggregateRule.java | 82 ++++++++++----------
.../org/eigenbase/rel/rules/SemiJoinRel.java | 2 +-
.../org/eigenbase/rel/rules/SwapJoinRule.java | 2 +-
.../org/eigenbase/sql2rel/RelFieldTrimmer.java | 2 +-
23 files changed, 303 insertions(+), 255 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/net/hydromatic/optiq/impl/jdbc/JdbcRules.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/net/hydromatic/optiq/impl/jdbc/JdbcRules.java b/core/src/main/java/net/hydromatic/optiq/impl/jdbc/JdbcRules.java
index a98d427..9009dad 100644
--- a/core/src/main/java/net/hydromatic/optiq/impl/jdbc/JdbcRules.java
+++ b/core/src/main/java/net/hydromatic/optiq/impl/jdbc/JdbcRules.java
@@ -200,7 +200,8 @@ public class JdbcRules {
@Override
public JdbcJoinRel copy(RelTraitSet traitSet, RexNode conditionExpr,
- RelNode left, RelNode right, JoinRelType joinType) {
+ RelNode left, RelNode right, JoinRelType joinType,
+ boolean semiJoinDone) {
try {
return new JdbcJoinRel(getCluster(), traitSet, left, right,
conditionExpr, this.joinType, variablesStopped);
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/net/hydromatic/optiq/rules/java/JavaRules.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/net/hydromatic/optiq/rules/java/JavaRules.java b/core/src/main/java/net/hydromatic/optiq/rules/java/JavaRules.java
index 3b17701..2e4a69b 100644
--- a/core/src/main/java/net/hydromatic/optiq/rules/java/JavaRules.java
+++ b/core/src/main/java/net/hydromatic/optiq/rules/java/JavaRules.java
@@ -157,7 +157,8 @@ public class JavaRules {
@Override
public EnumerableJoinRel copy(RelTraitSet traitSet, RexNode conditionExpr,
- RelNode left, RelNode right, JoinRelType joinType) {
+ RelNode left, RelNode right, JoinRelType joinType,
+ boolean semiJoinDone) {
try {
return new EnumerableJoinRel(getCluster(), traitSet, left, right,
conditionExpr, joinType, variablesStopped);
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/CorrelatorRel.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/CorrelatorRel.java b/core/src/main/java/org/eigenbase/rel/CorrelatorRel.java
index 100f1f6..20999c9 100644
--- a/core/src/main/java/org/eigenbase/rel/CorrelatorRel.java
+++ b/core/src/main/java/org/eigenbase/rel/CorrelatorRel.java
@@ -124,7 +124,7 @@ public final class CorrelatorRel extends JoinRelBase {
@Override
public CorrelatorRel copy(RelTraitSet traitSet, RexNode conditionExpr,
- RelNode left, RelNode right, JoinRelType joinType) {
+ RelNode left, RelNode right, JoinRelType joinType, boolean semiJoinDone) {
assert traitSet.containsIfApplicable(Convention.NONE);
return new CorrelatorRel(
getCluster(),
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/JoinRel.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/JoinRel.java b/core/src/main/java/org/eigenbase/rel/JoinRel.java
index e062d62..fe20153 100644
--- a/core/src/main/java/org/eigenbase/rel/JoinRel.java
+++ b/core/src/main/java/org/eigenbase/rel/JoinRel.java
@@ -137,17 +137,17 @@ public final class JoinRel extends JoinRelBase {
@Override
public JoinRel copy(RelTraitSet traitSet, RexNode conditionExpr, RelNode left,
- RelNode right, JoinRelType joinType) {
+ RelNode right, JoinRelType joinType, boolean semiJoinDone) {
assert traitSet.containsIfApplicable(Convention.NONE);
return new JoinRel(
getCluster(),
left,
right,
conditionExpr,
- this.joinType,
+ joinType,
this.variablesStopped,
- this.semiJoinDone,
- systemFieldList);
+ semiJoinDone,
+ this.systemFieldList);
}
@Override
@@ -156,23 +156,13 @@ public final class JoinRel extends JoinRelBase {
}
public RelWriter explainTerms(RelWriter pw) {
- // NOTE jvs 14-Mar-2006: Do it this way so that semijoin state
- // don't clutter things up in optimizers that don't use semijoins
- if (!semiJoinDone) {
- return super.explainTerms(pw);
- }
+ // Don't ever print semiJoinDone=false. This way, we
+ // don't clutter things up in optimizers that don't use semi-joins.
return super.explainTerms(pw)
- .item("semiJoinDone", semiJoinDone);
+ .itemIf("semiJoinDone", semiJoinDone, semiJoinDone);
}
- /**
- * Returns whether this JoinRel has already spawned a {@link
- * org.eigenbase.rel.rules.SemiJoinRel} via {@link
- * org.eigenbase.rel.rules.AddRedundantSemiJoinRule}.
- *
- * @return whether this join has already spawned a semi join
- */
- public boolean isSemiJoinDone() {
+ @Override public boolean isSemiJoinDone() {
return semiJoinDone;
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/JoinRelBase.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/JoinRelBase.java b/core/src/main/java/org/eigenbase/rel/JoinRelBase.java
index 2aff371..799b2e1 100644
--- a/core/src/main/java/org/eigenbase/rel/JoinRelBase.java
+++ b/core/src/main/java/org/eigenbase/rel/JoinRelBase.java
@@ -220,6 +220,19 @@ public abstract class JoinRelBase extends AbstractRelNode {
}
/**
+ * Returns whether this JoinRel has already spawned a
+ * {@link org.eigenbase.rel.rules.SemiJoinRel} via
+ * {@link org.eigenbase.rel.rules.AddRedundantSemiJoinRule}.
+ *
+ * <p>The base implementation returns false.</p>
+ *
+ * @return whether this join has already spawned a semi join
+ */
+ public boolean isSemiJoinDone() {
+ return false;
+ }
+
+ /**
* Returns a list of system fields that will be prefixed to
* output row type.
*
@@ -348,7 +361,7 @@ public abstract class JoinRelBase extends AbstractRelNode {
public final JoinRelBase copy(RelTraitSet traitSet, List<RelNode> inputs) {
assert inputs.size() == 2;
return copy(traitSet, getCondition(), inputs.get(0), inputs.get(1),
- joinType);
+ joinType, isSemiJoinDone());
}
/**
@@ -361,10 +374,12 @@ public abstract class JoinRelBase extends AbstractRelNode {
* @param left Left input
* @param right Right input
* @param joinType Join type
+ * @param semiJoinDone Whether this join has been translated to a
+ * semi-join
* @return Copy of this join
*/
public abstract JoinRelBase copy(RelTraitSet traitSet, RexNode conditionExpr,
- RelNode left, RelNode right, JoinRelType joinType);
+ RelNode left, RelNode right, JoinRelType joinType, boolean semiJoinDone);
}
// End JoinRelBase.java
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/RelFactories.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/RelFactories.java b/core/src/main/java/org/eigenbase/rel/RelFactories.java
index d664d46..155fd5d 100644
--- a/core/src/main/java/org/eigenbase/rel/RelFactories.java
+++ b/core/src/main/java/org/eigenbase/rel/RelFactories.java
@@ -20,18 +20,24 @@ package org.eigenbase.rel;
import java.util.AbstractList;
import java.util.List;
+import java.util.Set;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.reltype.RelDataTypeField;
import org.eigenbase.rex.RexNode;
+import com.google.common.collect.ImmutableList;
+
/**
* Contains factory interface and default implementation for creating various
* rel nodes.
*/
public class RelFactories {
-
public static final ProjectFactory DEFAULT_PROJECT_FACTORY =
new ProjectFactoryImpl();
+ public static final JoinFactory DEFAULT_JOIN_FACTORY = new JoinFactoryImpl();
+
private RelFactories() {
}
@@ -60,11 +66,48 @@ public class RelFactories {
}
/**
+ * Can create a {@link org.eigenbase.rel.JoinRelBase} of the appropriate type
+ * for this rule's calling convention.
+ */
+ public interface JoinFactory {
+ /**
+ * Creates a join.
+ *
+ * @param left Left input
+ * @param right Right input
+ * @param condition Join condition
+ * @param joinType Join type
+ * @param variablesStopped Set of names of variables which are set by the
+ * LHS and used by the RHS and are not available to
+ * nodes above this JoinRel in the tree
+ * @param semiJoinDone Whether this join has been translated to a
+ * semi-join
+ */
+ RelNode createJoin(RelNode left, RelNode right, RexNode condition,
+ JoinRelType joinType, Set<String> variablesStopped,
+ boolean semiJoinDone);
+ }
+
+ /**
+ * Implementation of {@link JoinFactory} that returns vanilla
+ * {@link JoinRel}.
+ */
+ private static class JoinFactoryImpl implements JoinFactory {
+ public RelNode createJoin(RelNode left, RelNode right, RexNode condition,
+ JoinRelType joinType, Set<String> variablesStopped,
+ boolean semiJoinDone) {
+ final RelOptCluster cluster = left.getCluster();
+ return new JoinRel(cluster, left, right, condition, joinType,
+ variablesStopped, semiJoinDone, ImmutableList.<RelDataTypeField>of());
+ }
+ }
+
+ /**
* Creates a relational expression that projects the given fields of the
* input.
- * <p>
- * Optimizes if the fields are the identity projection.
- * </p>
+ *
+ * <p>Optimizes if the fields are the identity projection.
+ *
* @param factory
* ProjectFactory
* @param child
@@ -104,3 +147,5 @@ public class RelFactories {
}
}
+
+// End RelFactories.java
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/RelImplementorImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/RelImplementorImpl.java b/core/src/main/java/org/eigenbase/rel/RelImplementorImpl.java
index a854c51..ac40c90 100644
--- a/core/src/main/java/org/eigenbase/rel/RelImplementorImpl.java
+++ b/core/src/main/java/org/eigenbase/rel/RelImplementorImpl.java
@@ -106,7 +106,7 @@ public class RelImplementorImpl implements RelImplementor {
RelNode rel,
int offset,
int[] offsets) {
- if (rel instanceof JoinRel) {
+ if (rel instanceof JoinRelBase) {
// no variable here -- go deeper
List<RelNode> inputs = rel.getInputs();
for (RelNode input : inputs) {
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/AddRedundantSemiJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/AddRedundantSemiJoinRule.java b/core/src/main/java/org/eigenbase/rel/rules/AddRedundantSemiJoinRule.java
index 10cf24e..b3c7a0a 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/AddRedundantSemiJoinRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/AddRedundantSemiJoinRule.java
@@ -23,27 +23,30 @@ import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
/**
- * Rule to add a semijoin into a joinrel. Transformation is as follows:
+ * Rule to add a semi-join into a join. Transformation is as follows:
*
* <p>JoinRel(X, Y) → JoinRel(SemiJoinRel(X, Y), Y)
+ *
+ * <p>The constructor is parameterized to allow any sub-class of
+ * {@link JoinRelBase}, not just {@link JoinRel}.</p>
*/
public class AddRedundantSemiJoinRule extends RelOptRule {
public static final AddRedundantSemiJoinRule INSTANCE =
- new AddRedundantSemiJoinRule();
+ new AddRedundantSemiJoinRule(JoinRel.class);
//~ Constructors -----------------------------------------------------------
/**
* Creates an AddRedundantSemiJoinRule.
*/
- private AddRedundantSemiJoinRule() {
- super(operand(JoinRel.class, any()));
+ private AddRedundantSemiJoinRule(Class<? extends JoinRelBase> clazz) {
+ super(operand(clazz, any()));
}
//~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
- JoinRel origJoinRel = call.rel(0);
+ JoinRelBase origJoinRel = call.rel(0);
if (origJoinRel.isSemiJoinDone()) {
return;
}
@@ -76,15 +79,13 @@ public class AddRedundantSemiJoinRule extends RelOptRule {
rightKeys);
RelNode newJoinRel =
- new JoinRel(
- origJoinRel.getCluster(),
+ origJoinRel.copy(
+ origJoinRel.getTraitSet(),
+ origJoinRel.getCondition(),
semiJoin,
origJoinRel.getRight(),
- origJoinRel.getCondition(),
JoinRelType.INNER,
- Collections.<String>emptySet(),
- true,
- origJoinRel.getSystemFieldList());
+ true);
call.transformTo(newJoinRel);
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/ConvertMultiJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/ConvertMultiJoinRule.java b/core/src/main/java/org/eigenbase/rel/rules/ConvertMultiJoinRule.java
index f43dc1e..d661851 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/ConvertMultiJoinRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/ConvertMultiJoinRule.java
@@ -31,9 +31,9 @@ import org.eigenbase.util.Pair;
* input in an outer join, i.e., either input in a full outer join, the right
* hand side of a left outer join, or the left hand side of a right outer join.
*
- * <p>Join conditions are also pulled up from the inputs into the topmost {@link
- * MultiJoinRel}, unless the input corresponds to a null generating input in an
- * outer join,
+ * <p>Join conditions are also pulled up from the inputs into the topmost
+ * {@link MultiJoinRel},
+ * unless the input corresponds to a null generating input in an outer join,
*
* <p>Outer join information is also stored in the {@link MultiJoinRel}. A
* boolean flag indicates if the join is a full outer join, and in the case of
@@ -62,20 +62,22 @@ import org.eigenbase.util.Pair;
* inner MultiJoinRel and right outer join on input#0 in the second inner
* MultiJoinRel
* </pre>
+ *
+ * <p>The constructor is parameterized to allow any sub-class of
+ * {@link JoinRelBase}, not just {@link JoinRel}.</p>
*/
public class ConvertMultiJoinRule extends RelOptRule {
public static final ConvertMultiJoinRule INSTANCE =
- new ConvertMultiJoinRule();
+ new ConvertMultiJoinRule(JoinRel.class);
//~ Constructors -----------------------------------------------------------
/**
* Creates a ConvertMultiJoinRule.
*/
- private ConvertMultiJoinRule() {
+ public ConvertMultiJoinRule(Class<? extends JoinRelBase> clazz) {
super(
- operand(
- JoinRel.class,
+ operand(clazz,
operand(RelNode.class, any()),
operand(RelNode.class, any())));
}
@@ -83,10 +85,10 @@ public class ConvertMultiJoinRule extends RelOptRule {
//~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
- JoinRel origJoinRel = call.rel(0);
+ final JoinRelBase origJoin = call.rel(0);
- RelNode left = call.rel(1);
- RelNode right = call.rel(2);
+ final RelNode left = call.rel(1);
+ final RelNode right = call.rel(2);
// combine the children MultiJoinRel inputs into an array of inputs
// for the new MultiJoinRel
@@ -94,7 +96,7 @@ public class ConvertMultiJoinRule extends RelOptRule {
List<int[]> joinFieldRefCountsList = new ArrayList<int[]>();
List<RelNode> newInputs =
combineInputs(
- origJoinRel,
+ origJoin,
left,
right,
projFieldsList,
@@ -106,7 +108,7 @@ public class ConvertMultiJoinRule extends RelOptRule {
final List<Pair<JoinRelType, RexNode>> joinSpecs =
new ArrayList<Pair<JoinRelType, RexNode>>();
combineOuterJoins(
- origJoinRel,
+ origJoin,
newInputs,
left,
right,
@@ -118,29 +120,28 @@ public class ConvertMultiJoinRule extends RelOptRule {
// pull up the join filters from the children MultiJoinRels and
// combine them with the join filter associated with this JoinRel to
// form the join filter for the new MultiJoinRel
- RexNode newJoinFilter = combineJoinFilters(origJoinRel, left, right);
+ RexNode newJoinFilter = combineJoinFilters(origJoin, left, right);
// add on the join field reference counts for the join condition
// associated with this JoinRel
Map<Integer, int[]> newJoinFieldRefCountsMap =
new HashMap<Integer, int[]>();
- addOnJoinFieldRefCounts(
- newInputs,
- origJoinRel.getRowType().getFieldCount(),
- origJoinRel.getCondition(),
+ addOnJoinFieldRefCounts(newInputs,
+ origJoin.getRowType().getFieldCount(),
+ origJoin.getCondition(),
joinFieldRefCountsList,
newJoinFieldRefCountsMap);
RexNode newPostJoinFilter =
- combinePostJoinFilters(origJoinRel, left, right);
+ combinePostJoinFilters(origJoin, left, right);
RelNode multiJoin =
new MultiJoinRel(
- origJoinRel.getCluster(),
+ origJoin.getCluster(),
newInputs,
newJoinFilter,
- origJoinRel.getRowType(),
- origJoinRel.getJoinType() == JoinRelType.FULL,
+ origJoin.getRowType(),
+ origJoin.getJoinType() == JoinRelType.FULL,
newOuterJoinConds,
joinTypes,
projFieldsList,
@@ -163,7 +164,7 @@ public class ConvertMultiJoinRule extends RelOptRule {
* @return combined left and right inputs in an array
*/
private List<RelNode> combineInputs(
- JoinRel join,
+ JoinRelBase join,
RelNode left,
RelNode right,
List<BitSet> projFieldsList,
@@ -245,7 +246,7 @@ public class ConvertMultiJoinRule extends RelOptRule {
* copied
*/
private void combineOuterJoins(
- JoinRel joinRel,
+ JoinRelBase joinRel,
List<RelNode> combinedInputs,
RelNode left,
RelNode right,
@@ -361,12 +362,12 @@ public class ConvertMultiJoinRule extends RelOptRule {
* outer join
*
* @param joinRel join rel
- * @param left left child of the joinrel
- * @param right right child of the joinrel
- * @return combined join filters AND'd together
+ * @param left left child of the join
+ * @param right right child of the join
+ * @return combined join filters AND-ed together
*/
private RexNode combineJoinFilters(
- JoinRel joinRel,
+ JoinRelBase joinRel,
RelNode left,
RelNode right) {
RexBuilder rexBuilder = joinRel.getCluster().getRexBuilder();
@@ -432,7 +433,7 @@ public class ConvertMultiJoinRule extends RelOptRule {
* @return the adjusted right filter
*/
private RexNode shiftRightFilter(
- JoinRel joinRel,
+ JoinRelBase joinRel,
RelNode left,
MultiJoinRel right,
RexNode rightFilter) {
@@ -517,7 +518,7 @@ public class ConvertMultiJoinRule extends RelOptRule {
* @return combined post-join filters AND'd together
*/
private RexNode combinePostJoinFilters(
- JoinRel joinRel,
+ JoinRelBase joinRel,
RelNode left,
RelNode right) {
RexNode rightPostJoinFilter = null;
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/ExtractJoinFilterRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/ExtractJoinFilterRule.java b/core/src/main/java/org/eigenbase/rel/rules/ExtractJoinFilterRule.java
index 5653a76..478f1b7 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/ExtractJoinFilterRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/ExtractJoinFilterRule.java
@@ -17,11 +17,8 @@
*/
package org.eigenbase.rel.rules;
-import java.util.*;
-
import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
-import org.eigenbase.reltype.RelDataTypeField;
/**
* Rule to convert an {@link JoinRel inner join} to a {@link FilterRel filter}
@@ -30,37 +27,40 @@ import org.eigenbase.reltype.RelDataTypeField;
* <p>One benefit of this transformation is that after it, the join condition
* can be combined with conditions and expressions above the join. It also makes
* the <code>FennelCartesianJoinRule</code> applicable.
+ *
+ * <p>The constructor is parameterized to allow any sub-class of
+ * {@link JoinRelBase}, not just {@link JoinRel}.</p>
*/
public final class ExtractJoinFilterRule extends RelOptRule {
//~ Static fields/initializers ---------------------------------------------
/** The singleton. */
public static final ExtractJoinFilterRule INSTANCE =
- new ExtractJoinFilterRule();
+ new ExtractJoinFilterRule(JoinRel.class);
//~ Constructors -----------------------------------------------------------
/**
* Creates an ExtractJoinFilterRule.
*/
- private ExtractJoinFilterRule() {
- super(operand(JoinRel.class, any()));
+ public ExtractJoinFilterRule(Class<? extends JoinRelBase> clazz) {
+ super(operand(clazz, any()));
}
//~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
- JoinRel joinRel = call.rel(0);
+ final JoinRelBase join = call.rel(0);
- if (joinRel.getJoinType() != JoinRelType.INNER) {
+ if (join.getJoinType() != JoinRelType.INNER) {
return;
}
- if (joinRel.getCondition().isAlwaysTrue()) {
+ if (join.getCondition().isAlwaysTrue()) {
return;
}
- if (!joinRel.getSystemFieldList().isEmpty()) {
+ if (!join.getSystemFieldList().isEmpty()) {
// FIXME Enable this rule for joins with system fields
return;
}
@@ -69,20 +69,18 @@ public final class ExtractJoinFilterRule extends RelOptRule {
// preserve attribute semiJoinDone here.
RelNode cartesianJoinRel =
- new JoinRel(
- joinRel.getCluster(),
- joinRel.getLeft(),
- joinRel.getRight(),
- joinRel.getCluster().getRexBuilder().makeLiteral(true),
- joinRel.getJoinType(),
- Collections.<String>emptySet(),
- joinRel.isSemiJoinDone(),
- Collections.<RelDataTypeField>emptyList());
+ join.copy(
+ join.getTraitSet(),
+ join.getCluster().getRexBuilder().makeLiteral(true),
+ join.getLeft(),
+ join.getRight(),
+ join.getJoinType(),
+ join.isSemiJoinDone());
RelNode filterRel =
CalcRel.createFilter(
cartesianJoinRel,
- joinRel.getCondition());
+ join.getCondition());
call.transformTo(filterRel);
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/LoptJoinTree.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/LoptJoinTree.java b/core/src/main/java/org/eigenbase/rel/rules/LoptJoinTree.java
index fffe59e..a274ab9 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/LoptJoinTree.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/LoptJoinTree.java
@@ -22,8 +22,8 @@ import java.util.*;
import org.eigenbase.rel.*;
/**
- * Utility class used to store a {@link JoinRel} tree and the factors that make
- * up the tree.
+ * Utility class used to store a {@link JoinRelBase} tree and the factors that
+ * make up the tree.
*
* <p>Because {@link RelNode}s can be duplicated in a query
* when you have a self-join, factor ids are needed to distinguish between the
@@ -112,14 +112,14 @@ public class LoptJoinTree {
public LoptJoinTree getLeft() {
return new LoptJoinTree(
- ((JoinRel) joinTree).getLeft(),
+ ((JoinRelBase) joinTree).getLeft(),
factorTree.getLeft(),
factorTree.getLeft().getParent().isRemovableSelfJoin());
}
public LoptJoinTree getRight() {
return new LoptJoinTree(
- ((JoinRel) joinTree).getRight(),
+ ((JoinRelBase) joinTree).getRight(),
factorTree.getRight(),
factorTree.getRight().getParent().isRemovableSelfJoin());
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/LoptOptimizeJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/LoptOptimizeJoinRule.java b/core/src/main/java/org/eigenbase/rel/rules/LoptOptimizeJoinRule.java
index 46115cb..77437c1 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/LoptOptimizeJoinRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/LoptOptimizeJoinRule.java
@@ -30,6 +30,7 @@ import org.eigenbase.util.mapping.IntPair;
import net.hydromatic.optiq.util.BitSets;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
/**
@@ -40,11 +41,14 @@ import com.google.common.collect.Lists;
*/
public class LoptOptimizeJoinRule extends RelOptRule {
public static final LoptOptimizeJoinRule INSTANCE =
- new LoptOptimizeJoinRule();
+ new LoptOptimizeJoinRule(RelFactories.DEFAULT_JOIN_FACTORY);
+
+ private final RelFactories.JoinFactory joinFactory;
/** Creates a LoptOptimizeJoinRule. */
- private LoptOptimizeJoinRule() {
+ public LoptOptimizeJoinRule(RelFactories.JoinFactory joinFactory) {
super(operand(MultiJoinRel.class, any()));
+ this.joinFactory = joinFactory;
}
//~ Methods ----------------------------------------------------------------
@@ -802,8 +806,8 @@ public class LoptOptimizeJoinRule extends RelOptRule {
// full outer joins were already optimized in a prior instantiation
// of this rule; therefore we should never see a join input that's
// a full outer join
- if (rel instanceof JoinRel) {
- assert ((JoinRel) rel).getJoinType() != JoinRelType.FULL;
+ if (rel instanceof JoinRelBase) {
+ assert ((JoinRelBase) rel).getJoinType() != JoinRelType.FULL;
return true;
} else {
return false;
@@ -949,7 +953,7 @@ public class LoptOptimizeJoinRule extends RelOptRule {
// the cost of each JoinRel that appears above that RelNode.
int width = tree.getRowType().getFieldCount();
if (isJoinTree(tree)) {
- JoinRel joinRel = (JoinRel) tree;
+ JoinRelBase joinRel = (JoinRelBase) tree;
width +=
rowWidthCost(joinRel.getLeft())
+ rowWidthCost(joinRel.getRight());
@@ -990,7 +994,7 @@ public class LoptOptimizeJoinRule extends RelOptRule {
int childNo = -1;
LoptJoinTree left = joinTree.getLeft();
LoptJoinTree right = joinTree.getRight();
- JoinRel joinRel = (JoinRel) joinTree.getJoinTree();
+ JoinRelBase joinRel = (JoinRelBase) joinTree.getJoinTree();
JoinRelType joinType = joinRel.getJoinType();
// can't push factors pass self-joins because in order to later remove
@@ -1063,7 +1067,7 @@ public class LoptOptimizeJoinRule extends RelOptRule {
// pushdown of the new factor as well as any swapping that may have
// been done during the pushdown
RexNode newCondition =
- ((JoinRel) joinTree.getJoinTree()).getCondition();
+ ((JoinRelBase) joinTree.getJoinTree()).getCondition();
newCondition =
adjustFilter(
multiJoin,
@@ -1734,15 +1738,13 @@ public class LoptOptimizeJoinRule extends RelOptRule {
}
RelNode joinTree =
- new JoinRel(
- multiJoin.getMultiJoinRel().getCluster(),
+ joinFactory.createJoin(
left.getJoinTree(),
right.getJoinTree(),
condition,
joinType,
- Collections.<String>emptySet(),
- true,
- Collections.<RelDataTypeField>emptyList());
+ ImmutableSet.<String>of(),
+ true);
// if this is a left or right outer join, and additional filters can
// be applied to the resulting join, then they need to be applied
@@ -1964,7 +1966,7 @@ public class LoptOptimizeJoinRule extends RelOptRule {
*
* @return true if the join is removable
*/
- public static boolean isRemovableSelfJoin(JoinRel joinRel) {
+ public static boolean isRemovableSelfJoin(JoinRelBase joinRel) {
final RelNode left = joinRel.getLeft();
final RelNode right = joinRel.getRight();
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/PullUpProjectsAboveJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/PullUpProjectsAboveJoinRule.java b/core/src/main/java/org/eigenbase/rel/rules/PullUpProjectsAboveJoinRule.java
index 67f979b..792598a 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/PullUpProjectsAboveJoinRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/PullUpProjectsAboveJoinRule.java
@@ -189,8 +189,10 @@ public class PullUpProjectsAboveJoinRule extends RelOptRule {
RexNode newCondition =
mergedProgram.expandLocalRef(
mergedProgram.getCondition());
- JoinRelBase newJoinRel = joinRel.copy(joinRel.getTraitSet(), newCondition,
- leftJoinChild, rightJoinChild, joinRel.getJoinType());
+ JoinRelBase newJoinRel =
+ joinRel.copy(joinRel.getTraitSet(), newCondition,
+ leftJoinChild, rightJoinChild, joinRel.getJoinType(),
+ joinRel.isSemiJoinDone());
// expand out the new projection expressions; if the join is an
// outer join, modify the expressions to reference the join output
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/PushFilterPastJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/PushFilterPastJoinRule.java b/core/src/main/java/org/eigenbase/rel/rules/PushFilterPastJoinRule.java
index 4b91552..f9b6f06 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/PushFilterPastJoinRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/PushFilterPastJoinRule.java
@@ -34,23 +34,23 @@ public abstract class PushFilterPastJoinRule extends RelOptRule {
new PushFilterPastJoinRule(
operand(
FilterRel.class,
- operand(JoinRel.class, any())),
+ operand(JoinRelBase.class, any())),
"PushFilterPastJoinRule:filter") {
@Override
public void onMatch(RelOptRuleCall call) {
FilterRel filter = call.rel(0);
- JoinRel join = call.rel(1);
+ JoinRelBase join = call.rel(1);
perform(call, filter, join);
}
};
public static final PushFilterPastJoinRule JOIN =
new PushFilterPastJoinRule(
- operand(JoinRel.class, any()),
+ operand(JoinRelBase.class, any()),
"PushFilterPastJoinRule:no-filter") {
@Override
public void onMatch(RelOptRuleCall call) {
- JoinRel join = call.rel(0);
+ JoinRelBase join = call.rel(0);
perform(call, null, join);
}
};
@@ -169,12 +169,14 @@ public abstract class PushFilterPastJoinRule extends RelOptRule {
joinFilter =
RexUtil.composeConjunction(rexBuilder, joinFilters, true);
}
- RelNode newJoinRel = join.copy(
- join.getCluster().traitSetOf(Convention.NONE),
- joinFilter,
- leftRel,
- rightRel,
- join.getJoinType());
+ RelNode newJoinRel =
+ join.copy(
+ join.getCluster().traitSetOf(Convention.NONE),
+ joinFilter,
+ leftRel,
+ rightRel,
+ join.getJoinType(),
+ join.isSemiJoinDone());
call.getPlanner().onCopy(join, newJoinRel);
// create a FilterRel on top of the join if needed
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/PushJoinThroughJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/PushJoinThroughJoinRule.java b/core/src/main/java/org/eigenbase/rel/rules/PushJoinThroughJoinRule.java
index b29a1b6..17f4fab 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/PushJoinThroughJoinRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/PushJoinThroughJoinRule.java
@@ -51,13 +51,19 @@ import net.hydromatic.optiq.util.BitSets;
* ({@code ON TRUE}). After the rule, each join has one condition.</p>
*/
public class PushJoinThroughJoinRule extends RelOptRule {
-
+ /** Instance of the rule that works on logical joins only, and pushes to the
+ * right. */
public static final RelOptRule RIGHT =
new PushJoinThroughJoinRule(
- "PushJoinThroughJoinRule:right", true, JoinRel.class);
+ "PushJoinThroughJoinRule:right", true, JoinRel.class,
+ RelFactories.DEFAULT_PROJECT_FACTORY);
+
+ /** Instance of the rule that works on logical joins only, and pushes to the
+ * left. */
public static final RelOptRule LEFT =
new PushJoinThroughJoinRule(
- "PushJoinThroughJoinRule:left", false, JoinRel.class);
+ "PushJoinThroughJoinRule:left", false, JoinRel.class,
+ RelFactories.DEFAULT_PROJECT_FACTORY);
private final boolean right;
@@ -66,15 +72,8 @@ public class PushJoinThroughJoinRule extends RelOptRule {
/**
* Creates a PushJoinThroughJoinRule.
*/
- private PushJoinThroughJoinRule(String description, boolean right,
- Class<? extends JoinRelBase> clazz) {
- this(description, right, clazz, RelFactories.DEFAULT_PROJECT_FACTORY);
- }
-
- public PushJoinThroughJoinRule(
- String description,
- boolean right,
- Class<? extends JoinRelBase> clazz, ProjectFactory pFactory) {
+ public PushJoinThroughJoinRule(String description, boolean right,
+ Class<? extends JoinRelBase> clazz, ProjectFactory projectFactory) {
super(
operand(
clazz,
@@ -82,7 +81,7 @@ public class PushJoinThroughJoinRule extends RelOptRule {
operand(RelNode.class, any())),
description);
this.right = right;
- projectFactory = pFactory;
+ this.projectFactory = projectFactory;
}
@Override
@@ -168,7 +167,7 @@ public class PushJoinThroughJoinRule extends RelOptRule {
RexUtil.composeConjunction(rexBuilder, newBottomList, false);
final JoinRelBase newBottomJoin =
bottomJoin.copy(bottomJoin.getTraitSet(), newBottomCondition, relA,
- relC, bottomJoin.getJoinType());
+ relC, bottomJoin.getJoinType(), bottomJoin.isSemiJoinDone());
// target: | A | C | B |
// source: | A | B | C |
@@ -188,7 +187,7 @@ public class PushJoinThroughJoinRule extends RelOptRule {
@SuppressWarnings("SuspiciousNameCombination")
final JoinRelBase newTopJoin =
topJoin.copy(topJoin.getTraitSet(), newTopCondition, newBottomJoin,
- relB, topJoin.getJoinType());
+ relB, topJoin.getJoinType(), topJoin.isSemiJoinDone());
assert !Mappings.isIdentity(topMapping);
final RelNode newProject = RelFactories.createProject(projectFactory,
@@ -276,7 +275,7 @@ public class PushJoinThroughJoinRule extends RelOptRule {
RexUtil.composeConjunction(rexBuilder, newBottomList, false);
final JoinRelBase newBottomJoin =
bottomJoin.copy(bottomJoin.getTraitSet(), newBottomCondition, relC,
- relB, bottomJoin.getJoinType());
+ relB, bottomJoin.getJoinType(), bottomJoin.isSemiJoinDone());
// target: | C | B | A |
// source: | A | B | C |
@@ -296,7 +295,7 @@ public class PushJoinThroughJoinRule extends RelOptRule {
@SuppressWarnings("SuspiciousNameCombination")
final JoinRelBase newTopJoin =
topJoin.copy(topJoin.getTraitSet(), newTopCondition, newBottomJoin,
- relA, topJoin.getJoinType());
+ relA, topJoin.getJoinType(), topJoin.isSemiJoinDone());
final RelNode newProject = RelFactories.createProject(projectFactory,
newTopJoin, Mappings.asList(topMapping));
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/PushJoinThroughUnionRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/PushJoinThroughUnionRule.java b/core/src/main/java/org/eigenbase/rel/rules/PushJoinThroughUnionRule.java
index fdf2ba4..f056197 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/PushJoinThroughUnionRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/PushJoinThroughUnionRule.java
@@ -22,8 +22,6 @@ import java.util.*;
import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
-import com.google.common.collect.ImmutableSet;
-
/**
* PushJoinThroughUnionRule implements the rule for pushing a
* {@link JoinRel} past a non-distinct {@link UnionRel}.
@@ -31,27 +29,25 @@ import com.google.common.collect.ImmutableSet;
public class PushJoinThroughUnionRule extends RelOptRule {
public static final PushJoinThroughUnionRule LEFT_UNION =
new PushJoinThroughUnionRule(
- operand(JoinRel.class,
- operand(UnionRel.class, any()),
+ operand(JoinRelBase.class,
+ operand(UnionRelBase.class, any()),
operand(RelNode.class, any())),
"union on left");
public static final PushJoinThroughUnionRule RIGHT_UNION =
new PushJoinThroughUnionRule(
- operand(JoinRel.class,
+ operand(JoinRelBase.class,
operand(RelNode.class, any()),
- operand(UnionRel.class, any())),
+ operand(UnionRelBase.class, any())),
"union on right");
private PushJoinThroughUnionRule(RelOptRuleOperand operand, String id) {
- super(
- operand,
- "PushJoinThroughUnionRule: " + id);
+ super(operand, "PushJoinThroughUnionRule: " + id);
}
public void onMatch(RelOptRuleCall call) {
- JoinRel joinRel = call.rel(0);
- UnionRel unionRel;
+ final JoinRelBase join = call.rel(0);
+ final UnionRelBase unionRel;
RelNode otherInput;
boolean unionOnLeft;
if (call.rel(1) instanceof UnionRel) {
@@ -66,7 +62,7 @@ public class PushJoinThroughUnionRule extends RelOptRule {
if (!unionRel.all) {
return;
}
- if (!joinRel.getVariablesStopped().isEmpty()) {
+ if (!join.getVariablesStopped().isEmpty()) {
return;
}
// The UNION ALL cannot be on the null generating side
@@ -74,16 +70,15 @@ public class PushJoinThroughUnionRule extends RelOptRule {
// rows for the other side for join keys which lack a match
// in one or both branches of the union)
if (unionOnLeft) {
- if (joinRel.getJoinType().generatesNullsOnLeft()) {
+ if (join.getJoinType().generatesNullsOnLeft()) {
return;
}
} else {
- if (joinRel.getJoinType().generatesNullsOnRight()) {
+ if (join.getJoinType().generatesNullsOnRight()) {
return;
}
}
List<RelNode> newUnionInputs = new ArrayList<RelNode>();
- RelOptCluster cluster = unionRel.getCluster();
for (RelNode input : unionRel.getInputs()) {
RelNode joinLeft;
RelNode joinRight;
@@ -95,15 +90,16 @@ public class PushJoinThroughUnionRule extends RelOptRule {
joinRight = input;
}
newUnionInputs.add(
- new JoinRel(
- cluster,
+ join.copy(
+ join.getTraitSet(),
+ join.getCondition(),
joinLeft,
joinRight,
- joinRel.getCondition(),
- joinRel.getJoinType(),
- ImmutableSet.<String>of()));
+ join.getJoinType(),
+ join.isSemiJoinDone()));
}
- UnionRel newUnionRel = new UnionRel(cluster, newUnionInputs, true);
+ final SetOpRel newUnionRel =
+ unionRel.copy(unionRel.getTraitSet(), newUnionInputs, true);
call.transformTo(newUnionRel);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/PushProjectPastJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/PushProjectPastJoinRule.java b/core/src/main/java/org/eigenbase/rel/rules/PushProjectPastJoinRule.java
index 2cfceca..54181a5 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/PushProjectPastJoinRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/PushProjectPastJoinRule.java
@@ -51,9 +51,8 @@ public class PushProjectPastJoinRule extends RelOptRule {
private PushProjectPastJoinRule(
PushProjector.ExprCondition preserveExprCondition) {
super(
- operand(
- ProjectRel.class,
- operand(JoinRel.class, any())));
+ operand(ProjectRel.class,
+ operand(JoinRelBase.class, any())));
this.preserveExprCondition = preserveExprCondition;
}
@@ -62,7 +61,7 @@ public class PushProjectPastJoinRule extends RelOptRule {
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
ProjectRel origProj = call.rel(0);
- JoinRel joinRel = call.rel(1);
+ final JoinRelBase join = call.rel(1);
// locate all fields referenced in the projection and join condition;
// determine which inputs are referenced in the projection and
@@ -71,8 +70,8 @@ public class PushProjectPastJoinRule extends RelOptRule {
PushProjector pushProject =
new PushProjector(
origProj,
- joinRel.getCondition(),
- joinRel,
+ join.getCondition(),
+ join,
preserveExprCondition);
if (pushProject.locateAllRefs()) {
return;
@@ -82,45 +81,43 @@ public class PushProjectPastJoinRule extends RelOptRule {
// fields referenced on each side
RelNode leftProjRel =
pushProject.createProjectRefsAndExprs(
- joinRel.getLeft(),
+ join.getLeft(),
true,
false);
RelNode rightProjRel =
pushProject.createProjectRefsAndExprs(
- joinRel.getRight(),
+ join.getRight(),
true,
true);
// convert the join condition to reference the projected columns
RexNode newJoinFilter = null;
int[] adjustments = pushProject.getAdjustments();
- if (joinRel.getCondition() != null) {
+ if (join.getCondition() != null) {
List<RelDataTypeField> projJoinFieldList =
new ArrayList<RelDataTypeField>();
projJoinFieldList.addAll(
- joinRel.getSystemFieldList());
+ join.getSystemFieldList());
projJoinFieldList.addAll(
leftProjRel.getRowType().getFieldList());
projJoinFieldList.addAll(
rightProjRel.getRowType().getFieldList());
newJoinFilter =
pushProject.convertRefsAndExprs(
- joinRel.getCondition(),
+ join.getCondition(),
projJoinFieldList,
adjustments);
}
- // create a new joinrel with the projected children
- JoinRel newJoinRel =
- new JoinRel(
- joinRel.getCluster(),
+ // create a new join with the projected children
+ JoinRelBase newJoinRel =
+ join.copy(
+ join.getTraitSet(),
+ newJoinFilter,
leftProjRel,
rightProjRel,
- newJoinFilter,
- joinRel.getJoinType(),
- Collections.<String>emptySet(),
- joinRel.isSemiJoinDone(),
- joinRel.getSystemFieldList());
+ join.getJoinType(),
+ join.isSemiJoinDone());
// put the original project on top of the join, converting it to
// reference the modified projection list
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/PushSemiJoinPastJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/PushSemiJoinPastJoinRule.java b/core/src/main/java/org/eigenbase/rel/rules/PushSemiJoinPastJoinRule.java
index 2457599..26c8e8f 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/PushSemiJoinPastJoinRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/PushSemiJoinPastJoinRule.java
@@ -25,8 +25,9 @@ import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;
/**
- * PushSemiJoinPastJoinRule implements the rule for pushing semijoins down in a
- * tree past a join in order to trigger other rules that will convert semijoins.
+ * PushSemiJoinPastJoinRule implements the rule for pushing semi-joins down in a
+ * tree past a join in order to trigger other rules that will convert
+ * semi-joins.
*
* <ul>
* <li>SemiJoinRel(JoinRel(X, Y), Z) → JoinRel(SemiJoinRel(X, Z), Y)
@@ -35,7 +36,7 @@ import org.eigenbase.rex.*;
*
* <p>Whether this
* first or second conversion is applied depends on which operands actually
- * participate in the semijoin.</p>
+ * participate in the semi-join.</p>
*/
public class PushSemiJoinPastJoinRule extends RelOptRule {
public static final PushSemiJoinPastJoinRule INSTANCE =
@@ -50,7 +51,7 @@ public class PushSemiJoinPastJoinRule extends RelOptRule {
super(
operand(
SemiJoinRel.class,
- some(operand(JoinRel.class, any()))));
+ some(operand(JoinRelBase.class, any()))));
}
//~ Methods ----------------------------------------------------------------
@@ -58,22 +59,25 @@ public class PushSemiJoinPastJoinRule extends RelOptRule {
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
SemiJoinRel semiJoin = call.rel(0);
- JoinRel joinRel = call.rel(1);
+ final JoinRelBase join = call.rel(1);
+ if (join instanceof SemiJoinRel) {
+ return;
+ }
List<Integer> leftKeys = semiJoin.getLeftKeys();
List<Integer> rightKeys = semiJoin.getRightKeys();
- // X is the left child of the join below the semijoin
- // Y is the right child of the join below the semijoin
- // Z is the right child of the semijoin
- int nFieldsX = joinRel.getLeft().getRowType().getFieldList().size();
- int nFieldsY = joinRel.getRight().getRowType().getFieldList().size();
+ // X is the left child of the join below the semi-join
+ // Y is the right child of the join below the semi-join
+ // Z is the right child of the semi-join
+ int nFieldsX = join.getLeft().getRowType().getFieldList().size();
+ int nFieldsY = join.getRight().getRowType().getFieldList().size();
int nFieldsZ = semiJoin.getRight().getRowType().getFieldList().size();
int nTotalFields = nFieldsX + nFieldsY + nFieldsZ;
List<RelDataTypeField> fields = new ArrayList<RelDataTypeField>();
// create a list of fields for the full join result; note that
- // we can't simply use the fields from the semijoin because the
- // rowtype of a semijoin only includes the left hand side fields
+ // we can't simply use the fields from the semi-join because the
+ // row-type of a semi-join only includes the left hand side fields
List<RelDataTypeField> joinFields =
semiJoin.getRowType().getFieldList();
for (int i = 0; i < (nFieldsX + nFieldsY); i++) {
@@ -84,8 +88,8 @@ public class PushSemiJoinPastJoinRule extends RelOptRule {
fields.add(joinFields.get(i));
}
- // determine which operands below the semijoin are the actual
- // Rels that participate in the semijoin
+ // determine which operands below the semi-join are the actual
+ // Rels that participate in the semi-join
int nKeysFromX = 0;
for (int leftKey : leftKeys) {
if (leftKey < nFieldsX) {
@@ -94,10 +98,10 @@ public class PushSemiJoinPastJoinRule extends RelOptRule {
}
// the keys must all originate from either the left or right;
- // otherwise, a semijoin wouldn't have been created
+ // otherwise, a semi-join wouldn't have been created
assert (nKeysFromX == 0) || (nKeysFromX == leftKeys.size());
- // need to convert the semijoin condition and possibly the keys
+ // need to convert the semi-join condition and possibly the keys
RexNode newSemiJoinFilter;
List<Integer> newLeftKeys;
int[] adjustments = new int[nTotalFields];
@@ -105,7 +109,7 @@ public class PushSemiJoinPastJoinRule extends RelOptRule {
// (X, Y, Z) --> (X, Z, Y)
// semiJoin(X, Z)
// pass 0 as Y's adjustment because there shouldn't be any
- // references to Y in the semijoin filter
+ // references to Y in the semi-join filter
setJoinAdjustments(
adjustments,
nFieldsX,
@@ -142,9 +146,9 @@ public class PushSemiJoinPastJoinRule extends RelOptRule {
// create the new join
RelNode leftSemiJoinOp;
if (nKeysFromX > 0) {
- leftSemiJoinOp = joinRel.getLeft();
+ leftSemiJoinOp = join.getLeft();
} else {
- leftSemiJoinOp = joinRel.getRight();
+ leftSemiJoinOp = join.getRight();
}
SemiJoinRel newSemiJoin =
new SemiJoinRel(
@@ -159,22 +163,20 @@ public class PushSemiJoinPastJoinRule extends RelOptRule {
RelNode rightJoinRel;
if (nKeysFromX > 0) {
leftJoinRel = newSemiJoin;
- rightJoinRel = joinRel.getRight();
+ rightJoinRel = join.getRight();
} else {
- leftJoinRel = joinRel.getLeft();
+ leftJoinRel = join.getLeft();
rightJoinRel = newSemiJoin;
}
RelNode newJoinRel =
- new JoinRel(
- joinRel.getCluster(),
+ join.copy(
+ join.getTraitSet(),
+ join.getCondition(),
leftJoinRel,
rightJoinRel,
- joinRel.getCondition(),
- joinRel.getJoinType(),
- Collections.<String>emptySet(),
- joinRel.isSemiJoinDone(),
- joinRel.getSystemFieldList());
+ join.getJoinType(),
+ join.isSemiJoinDone());
call.transformTo(newJoinRel);
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/ReduceExpressionsRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/ReduceExpressionsRule.java b/core/src/main/java/org/eigenbase/rel/rules/ReduceExpressionsRule.java
index 4b3a393..73a2223 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/ReduceExpressionsRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/ReduceExpressionsRule.java
@@ -174,20 +174,20 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
};
public static final ReduceExpressionsRule JOIN_INSTANCE =
- new ReduceExpressionsRule(JoinRel.class,
+ new ReduceExpressionsRule(JoinRelBase.class,
"ReduceExpressionsRule[Join]") {
public void onMatch(RelOptRuleCall call) {
- JoinRel join = call.rel(0);
+ final JoinRelBase join = call.rel(0);
List<RexNode> expList = new ArrayList<RexNode>(join.getChildExps());
if (reduceExpressions(join, expList)) {
call.transformTo(
- new JoinRel(
- join.getCluster(),
+ join.copy(
+ join.getTraitSet(),
+ expList.get(0),
join.getLeft(),
join.getRight(),
- expList.get(0),
join.getJoinType(),
- join.getVariablesStopped()));
+ join.isSemiJoinDone()));
// New plan is absolutely better than old plan.
call.getPlanner().setImportance(join, 0.0);
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/RemoveDistinctAggregateRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/RemoveDistinctAggregateRule.java b/core/src/main/java/org/eigenbase/rel/rules/RemoveDistinctAggregateRule.java
index 576dc02..673a453 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/RemoveDistinctAggregateRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/RemoveDistinctAggregateRule.java
@@ -37,23 +37,25 @@ import com.google.common.collect.ImmutableSet;
public final class RemoveDistinctAggregateRule extends RelOptRule {
//~ Static fields/initializers ---------------------------------------------
- /** The singleton. */
+ /** The default instance of the rule; operates only on logical expressions. */
public static final RemoveDistinctAggregateRule INSTANCE =
- new RemoveDistinctAggregateRule();
+ new RemoveDistinctAggregateRule(AggregateRel.class,
+ RelFactories.DEFAULT_JOIN_FACTORY);
+
+ private final RelFactories.JoinFactory joinFactory;
//~ Constructors -----------------------------------------------------------
- /**
- * Private constructor.
- */
- private RemoveDistinctAggregateRule() {
- super(operand(AggregateRel.class, any()));
+ public RemoveDistinctAggregateRule(Class<? extends AggregateRel> clazz,
+ RelFactories.JoinFactory joinFactory) {
+ super(operand(clazz, any()));
+ this.joinFactory = joinFactory;
}
//~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
- AggregateRel aggregate = call.rel(0);
+ final AggregateRelBase aggregate = call.rel(0);
if (!aggregate.containsDistinctCall()) {
return;
}
@@ -143,12 +145,12 @@ public final class RemoveDistinctAggregateRule extends RelOptRule {
}
/**
- * Converts an aggregrate relational expression which contains just one
+ * Converts an aggregate relational expression that contains just one
* distinct aggregate function (or perhaps several over the same arguments)
* and no non-distinct aggregate functions.
*/
private RelNode convertMonopole(
- AggregateRel aggregate,
+ AggregateRelBase aggregate,
List<Integer> argList) {
// For example,
// SELECT deptno, COUNT(DISTINCT sal), SUM(DISTINCT sal)
@@ -166,21 +168,18 @@ public final class RemoveDistinctAggregateRule extends RelOptRule {
// Project the columns of the GROUP BY plus the arguments
// to the agg function.
Map<Integer, Integer> sourceOf = new HashMap<Integer, Integer>();
- final AggregateRel distinct =
+ final AggregateRelBase distinct =
createSelectDistinct(aggregate, argList, sourceOf);
// Create an aggregate on top, with the new aggregate list.
final List<AggregateCall> newAggCalls =
new ArrayList<AggregateCall>(aggregate.getAggCallList());
rewriteAggCalls(newAggCalls, argList, sourceOf);
- AggregateRel newAggregate =
- new AggregateRel(
- aggregate.getCluster(),
- distinct,
- aggregate.getGroupSet(),
- newAggCalls);
-
- return newAggregate;
+ return aggregate.copy(
+ aggregate.getTraitSet(),
+ distinct,
+ aggregate.getGroupSet(),
+ newAggCalls);
}
/**
@@ -203,7 +202,7 @@ public final class RemoveDistinctAggregateRule extends RelOptRule {
* @return Relational expression
*/
private RelNode doRewrite(
- AggregateRel aggregate,
+ AggregateRelBase aggregate,
RelNode left,
List<Integer> argList,
List<RexInputRef> refs) {
@@ -253,13 +252,13 @@ public final class RemoveDistinctAggregateRule extends RelOptRule {
//
// Note that if a query contains no non-distinct aggregates, then the
// very first join/group by is omitted. In the example above, if
- // MAX(age) is removed, then the subselect of "e" is not needed, and
+ // MAX(age) is removed, then the sub-select of "e" is not needed, and
// instead the two other group by's are joined to one another.
// Project the columns of the GROUP BY plus the arguments
// to the agg function.
Map<Integer, Integer> sourceOf = new HashMap<Integer, Integer>();
- final AggregateRel distinct =
+ final AggregateRelBase distinct =
createSelectDistinct(aggregate, argList, sourceOf);
// Now compute the aggregate functions on top of the distinct dataset.
@@ -318,9 +317,9 @@ public final class RemoveDistinctAggregateRule extends RelOptRule {
aggCallList.add(newAggCall);
}
- AggregateRel distinctAgg =
- new AggregateRel(
- aggregate.getCluster(),
+ AggregateRelBase distinctAgg =
+ aggregate.copy(
+ aggregate.getTraitSet(),
distinct,
aggregate.getGroupSet(),
aggCallList);
@@ -362,14 +361,13 @@ public final class RemoveDistinctAggregateRule extends RelOptRule {
}
// Join in the new 'select distinct' relation.
- return
- new JoinRel(
- aggregate.getCluster(),
- left,
- distinctAgg,
- condition,
- JoinRelType.INNER,
- ImmutableSet.<String>of());
+ return joinFactory.createJoin(
+ left,
+ distinctAgg,
+ condition,
+ JoinRelType.INNER,
+ ImmutableSet.<String>of(),
+ false);
}
private static void rewriteAggCalls(
@@ -440,14 +438,14 @@ public final class RemoveDistinctAggregateRule extends RelOptRule {
* column; in this case sourceOf.get(0) = 0, and sourceOf.get(1) = 2.</p>
*
* @param aggregate Aggregate relational expression
- * @param argList Ordinals of columns to distinctify
+ * @param argList Ordinals of columns to make distinct
* @param sourceOf Out parameter, is populated with a map of where each
* output field came from
* @return Aggregate relational expression which projects the required
* columns
*/
- private static AggregateRel createSelectDistinct(
- AggregateRel aggregate,
+ private static AggregateRelBase createSelectDistinct(
+ AggregateRelBase aggregate,
List<Integer> argList,
Map<Integer, Integer> sourceOf) {
final List<Pair<RexNode, String>> projects =
@@ -471,13 +469,11 @@ public final class RemoveDistinctAggregateRule extends RelOptRule {
// Get the distinct values of the GROUP BY fields and the arguments
// to the agg functions.
- final AggregateRel distinct =
- new AggregateRel(
- aggregate.getCluster(),
- project,
- BitSets.range(projects.size()),
- ImmutableList.<AggregateCall>of());
- return distinct;
+ return aggregate.copy(
+ aggregate.getTraitSet(),
+ project,
+ BitSets.range(projects.size()),
+ ImmutableList.<AggregateCall>of());
}
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/SemiJoinRel.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/SemiJoinRel.java b/core/src/main/java/org/eigenbase/rel/rules/SemiJoinRel.java
index 1c714b6..8dfa4fa 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/SemiJoinRel.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/SemiJoinRel.java
@@ -72,7 +72,7 @@ public final class SemiJoinRel extends JoinRelBase {
@Override
public SemiJoinRel copy(RelTraitSet traitSet, RexNode conditionExpr,
- RelNode left, RelNode right, JoinRelType joinType) {
+ RelNode left, RelNode right, JoinRelType joinType, boolean semiJoinDone) {
assert joinType == JoinRelType.INNER;
return new SemiJoinRel(
getCluster(),
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/rel/rules/SwapJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/SwapJoinRule.java b/core/src/main/java/org/eigenbase/rel/rules/SwapJoinRule.java
index 0f1bb42..54e693d 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/SwapJoinRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/SwapJoinRule.java
@@ -91,7 +91,7 @@ public class SwapJoinRule extends RelOptRule {
// that the planner tries the desired order (semijoins after swaps).
JoinRelBase newJoin =
join.copy(join.getTraitSet(), condition, join.getRight(),
- join.getLeft(), joinType.swap());
+ join.getLeft(), joinType.swap(), join.isSemiJoinDone());
final List<RexNode> exps =
RelOptUtil.createSwappedJoinExprs(newJoin, join, true);
return CalcRel.createProject(
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/e5188ec8/core/src/main/java/org/eigenbase/sql2rel/RelFieldTrimmer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/sql2rel/RelFieldTrimmer.java b/core/src/main/java/org/eigenbase/sql2rel/RelFieldTrimmer.java
index 22ef225..131cc97 100644
--- a/core/src/main/java/org/eigenbase/sql2rel/RelFieldTrimmer.java
+++ b/core/src/main/java/org/eigenbase/sql2rel/RelFieldTrimmer.java
@@ -575,7 +575,7 @@ public class RelFieldTrimmer implements ReflectiveVisitor {
final JoinRel newJoin =
join.copy(join.getTraitSet(), newConditionExpr, newInputs.get(0),
- newInputs.get(1), join.getJoinType());
+ newInputs.get(1), join.getJoinType(), join.isSemiJoinDone());
return new TrimResult(newJoin, mapping);
}
[2/2] git commit: [OPTIQ-331] Precision/Scale compatibility checks
should always succeed for 'ANY' type
Posted by jh...@apache.org.
[OPTIQ-331] Precision/Scale compatibility checks should always succeed for 'ANY' type
Project: http://git-wip-us.apache.org/repos/asf/incubator-optiq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-optiq/commit/c34c1448
Tree: http://git-wip-us.apache.org/repos/asf/incubator-optiq/tree/c34c1448
Diff: http://git-wip-us.apache.org/repos/asf/incubator-optiq/diff/c34c1448
Branch: refs/heads/master
Commit: c34c144874cb9acbbafa8ff51f35a4f31cadee98
Parents: e5188ec
Author: Mehant Baid <me...@gmail.com>
Authored: Wed Jul 2 20:05:12 2014 -0700
Committer: Julian Hyde <ju...@gmail.com>
Committed: Wed Jul 2 21:38:44 2014 -0700
----------------------------------------------------------------------
core/src/main/java/org/eigenbase/sql/type/SqlTypeName.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/c34c1448/core/src/main/java/org/eigenbase/sql/type/SqlTypeName.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/sql/type/SqlTypeName.java b/core/src/main/java/org/eigenbase/sql/type/SqlTypeName.java
index ae98a59..efff330 100644
--- a/core/src/main/java/org/eigenbase/sql/type/SqlTypeName.java
+++ b/core/src/main/java/org/eigenbase/sql/type/SqlTypeName.java
@@ -72,7 +72,8 @@ public enum SqlTypeName {
VARBINARY(PrecScale.NO_NO | PrecScale.YES_NO, false, Types.VARBINARY,
SqlTypeFamily.BINARY),
NULL(PrecScale.NO_NO, true, Types.NULL, SqlTypeFamily.NULL),
- ANY(PrecScale.NO_NO, true, Types.JAVA_OBJECT, SqlTypeFamily.ANY),
+ ANY(PrecScale.NO_NO | PrecScale.YES_NO | PrecScale.YES_YES, true,
+ Types.JAVA_OBJECT, SqlTypeFamily.ANY),
SYMBOL(PrecScale.NO_NO, true, Types.OTHER, null),
MULTISET(PrecScale.NO_NO, false, Types.ARRAY, SqlTypeFamily.MULTISET),
ARRAY(PrecScale.NO_NO, false, Types.ARRAY, SqlTypeFamily.ARRAY),