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 2016/01/21 23:39:03 UTC
[26/50] [abbrv] calcite git commit: [CALCITE-816] Represent sub-query
as a RexNode
[CALCITE-816] Represent sub-query as a RexNode
Reduce 3-value logic to 1- or 2-value logic.
Optimize certain IN and EXISTS to an inner join.
Represent correlation variables using CorrelationId wherever possible.
In Join, replace field "ImmutableSet<String> variablesStopped" with
"ImmutableSet<CorrelationId> variablesSet". RelNode.getVariablesSet
is now preferred to RelNode.getVariablesStopped.
Make Join.joinType final.
Verify in builder that there are no correlation variables where there
shouldn't be.
Refactor decorrelator.
Logged [CALCITE-1045] for remaining work.
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/505a9064
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/505a9064
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/505a9064
Branch: refs/heads/branch-release
Commit: 505a9064b96a6c8399735fc2fa4d0ac9d5f3ed87
Parents: cd92b77
Author: Julian Hyde <jh...@apache.org>
Authored: Sat Jul 25 14:44:20 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Sun Jan 10 00:51:25 2016 -0800
----------------------------------------------------------------------
.../adapter/enumerable/EnumerableJoin.java | 42 +-
.../adapter/enumerable/EnumerableJoinRule.java | 9 +-
.../adapter/enumerable/EnumerableMergeJoin.java | 22 +-
.../enumerable/EnumerableMergeJoinRule.java | 4 +-
.../adapter/enumerable/EnumerableThetaJoin.java | 16 +-
.../calcite/adapter/enumerable/RexImpTable.java | 14 +-
.../apache/calcite/adapter/jdbc/JdbcRules.java | 20 +-
.../apache/calcite/interpreter/Bindables.java | 17 +-
.../org/apache/calcite/materialize/Lattice.java | 3 +-
.../org/apache/calcite/plan/RelOptCluster.java | 5 +-
.../org/apache/calcite/plan/RelOptQuery.java | 3 +-
.../org/apache/calcite/plan/RelOptUtil.java | 127 +-
.../calcite/plan/SubstitutionVisitor.java | 19 +-
.../org/apache/calcite/plan/volcano/RelSet.java | 24 +-
.../apache/calcite/plan/volcano/RelSubset.java | 29 +-
.../calcite/plan/volcano/VolcanoPlanner.java | 2 +-
.../org/apache/calcite/prepare/Prepare.java | 10 +-
.../org/apache/calcite/rel/AbstractRelNode.java | 16 +-
.../java/org/apache/calcite/rel/RelNode.java | 31 +-
.../org/apache/calcite/rel/core/Correlate.java | 15 +-
.../apache/calcite/rel/core/CorrelationId.java | 54 +-
.../org/apache/calcite/rel/core/EquiJoin.java | 15 +-
.../java/org/apache/calcite/rel/core/Join.java | 53 +-
.../apache/calcite/rel/core/RelFactories.java | 63 +-
.../org/apache/calcite/rel/core/SemiJoin.java | 4 +-
.../apache/calcite/rel/externalize/RelJson.java | 2 +-
.../apache/calcite/rel/logical/LogicalCalc.java | 5 +-
.../calcite/rel/logical/LogicalCorrelate.java | 3 +
.../calcite/rel/logical/LogicalFilter.java | 46 +-
.../apache/calcite/rel/logical/LogicalJoin.java | 73 +-
.../calcite/rel/metadata/RelMdUniqueKeys.java | 11 +-
.../org/apache/calcite/rel/rules/EquiJoin.java | 3 +-
.../calcite/rel/rules/JoinToCorrelateRule.java | 5 +-
.../rel/rules/JoinUnionTransposeRule.java | 2 +-
.../calcite/rel/rules/SubQueryRemoveRule.java | 365 ++++
.../apache/calcite/rel/stream/StreamRules.java | 10 +-
.../org/apache/calcite/rex/LogicVisitor.java | 158 ++
.../org/apache/calcite/rex/RexBiVisitor.java | 52 +
.../java/org/apache/calcite/rex/RexBuilder.java | 7 +-
.../java/org/apache/calcite/rex/RexCall.java | 8 +-
.../apache/calcite/rex/RexCorrelVariable.java | 12 +-
.../org/apache/calcite/rex/RexDynamicParam.java | 4 +
.../org/apache/calcite/rex/RexFieldAccess.java | 4 +
.../org/apache/calcite/rex/RexInputRef.java | 4 +
.../java/org/apache/calcite/rex/RexLiteral.java | 10 +-
.../org/apache/calcite/rex/RexLocalRef.java | 4 +
.../java/org/apache/calcite/rex/RexNode.java | 6 +
.../java/org/apache/calcite/rex/RexOver.java | 4 +
.../java/org/apache/calcite/rex/RexProgram.java | 4 +
.../org/apache/calcite/rex/RexRangeRef.java | 4 +
.../java/org/apache/calcite/rex/RexShuttle.java | 12 +-
.../org/apache/calcite/rex/RexSubQuery.java | 115 ++
.../java/org/apache/calcite/rex/RexUtil.java | 103 +-
.../java/org/apache/calcite/rex/RexVisitor.java | 2 +
.../org/apache/calcite/rex/RexVisitorImpl.java | 12 +
.../org/apache/calcite/schema/SchemaPlus.java | 2 +-
.../java/org/apache/calcite/sql/SqlKind.java | 8 +-
.../calcite/sql/validate/SqlValidatorImpl.java | 1 +
.../sql2rel/DeduplicateCorrelateVariables.java | 65 +-
.../apache/calcite/sql2rel/RelDecorrelator.java | 1646 ++++++++----------
.../apache/calcite/sql2rel/RelFieldTrimmer.java | 12 +-
.../sql2rel/RelStructuredTypeFlattener.java | 7 +-
.../calcite/sql2rel/SqlToRelConverter.java | 390 +++--
.../java/org/apache/calcite/tools/Programs.java | 54 +-
.../org/apache/calcite/tools/RelBuilder.java | 47 +-
.../main/java/org/apache/calcite/util/Bug.java | 5 +
.../org/apache/calcite/test/CalciteAssert.java | 10 +-
.../apache/calcite/test/JdbcAdapterTest.java | 122 +-
.../java/org/apache/calcite/test/JdbcTest.java | 214 ++-
.../org/apache/calcite/test/LatticeTest.java | 47 +-
.../calcite/test/ReflectiveSchemaTest.java | 21 +-
.../org/apache/calcite/test/RelBuilderTest.java | 22 +
.../apache/calcite/test/RelMetadataTest.java | 3 +-
.../apache/calcite/test/RelOptRulesTest.java | 159 +-
.../org/apache/calcite/test/RelOptTestBase.java | 30 +
.../apache/calcite/test/RexTransformerTest.java | 210 +--
.../calcite/test/SqlToRelConverterTest.java | 421 ++++-
.../apache/calcite/test/SqlToRelTestBase.java | 36 +-
.../apache/calcite/test/SqlValidatorTest.java | 37 +
.../enumerable/EnumerableCorrelateTest.java | 29 +-
.../org/apache/calcite/test/RelOptRulesTest.xml | 706 ++++++++
.../calcite/test/SqlToRelConverterTest.xml | 582 ++++++-
core/src/test/resources/sql/join.iq | 18 +-
core/src/test/resources/sql/misc.iq | 121 +-
core/src/test/resources/sql/subquery.iq | 70 +-
site/_docs/reference.md | 17 +-
86 files changed, 5027 insertions(+), 1752 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java
index 14fcf3b..0b86771 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java
@@ -26,6 +26,7 @@ import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.InvalidRelException;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelNodes;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.EquiJoin;
import org.apache.calcite.rel.core.JoinInfo;
import org.apache.calcite.rel.core.JoinRelType;
@@ -53,8 +54,8 @@ public class EnumerableJoin extends EquiJoin implements EnumerableRel {
RexNode condition,
ImmutableIntList leftKeys,
ImmutableIntList rightKeys,
- JoinRelType joinType,
- Set<String> variablesStopped)
+ Set<CorrelationId> variablesSet,
+ JoinRelType joinType)
throws InvalidRelException {
super(
cluster,
@@ -64,8 +65,17 @@ public class EnumerableJoin extends EquiJoin implements EnumerableRel {
condition,
leftKeys,
rightKeys,
- joinType,
- variablesStopped);
+ variablesSet,
+ joinType);
+ }
+
+ @Deprecated // to be removed before 2.0
+ protected EnumerableJoin(RelOptCluster cluster, RelTraitSet traits,
+ RelNode left, RelNode right, RexNode condition, ImmutableIntList leftKeys,
+ ImmutableIntList rightKeys, JoinRelType joinType,
+ Set<String> variablesStopped) throws InvalidRelException {
+ this(cluster, traits, left, right, condition, leftKeys, rightKeys,
+ CorrelationId.setOf(variablesStopped), joinType);
}
/** Creates an EnumerableJoin. */
@@ -75,14 +85,28 @@ public class EnumerableJoin extends EquiJoin implements EnumerableRel {
RexNode condition,
ImmutableIntList leftKeys,
ImmutableIntList rightKeys,
- JoinRelType joinType,
- Set<String> variablesStopped)
+ Set<CorrelationId> variablesSet,
+ JoinRelType joinType)
throws InvalidRelException {
final RelOptCluster cluster = left.getCluster();
final RelTraitSet traitSet =
cluster.traitSetOf(EnumerableConvention.INSTANCE);
return new EnumerableJoin(cluster, traitSet, left, right, condition,
- leftKeys, rightKeys, joinType, variablesStopped);
+ leftKeys, rightKeys, variablesSet, joinType);
+ }
+
+ @Deprecated // to be removed before 2.0
+ public static EnumerableJoin create(
+ RelNode left,
+ RelNode right,
+ RexNode condition,
+ ImmutableIntList leftKeys,
+ ImmutableIntList rightKeys,
+ JoinRelType joinType,
+ Set<String> variablesStopped)
+ throws InvalidRelException {
+ return create(left, right, condition, leftKeys, rightKeys,
+ CorrelationId.setOf(variablesStopped), joinType);
}
@Override public EnumerableJoin copy(RelTraitSet traitSet, RexNode condition,
@@ -92,8 +116,8 @@ public class EnumerableJoin extends EquiJoin implements EnumerableRel {
assert joinInfo.isEqui();
try {
return new EnumerableJoin(getCluster(), traitSet, left, right,
- condition, joinInfo.leftKeys, joinInfo.rightKeys, joinType,
- variablesStopped);
+ condition, joinInfo.leftKeys, joinInfo.rightKeys, variablesSet,
+ joinType);
} catch (InvalidRelException e) {
// Semantic error not possible. Must be a bug. Convert to
// internal error.
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java
index 6ffc912..88655ba 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java
@@ -43,7 +43,7 @@ class EnumerableJoinRule extends ConverterRule {
@Override public RelNode convert(RelNode rel) {
LogicalJoin join = (LogicalJoin) rel;
- List<RelNode> newInputs = new ArrayList<RelNode>();
+ List<RelNode> newInputs = new ArrayList<>();
for (RelNode input : join.getInputs()) {
if (!(input.getConvention() instanceof EnumerableConvention)) {
input =
@@ -65,8 +65,7 @@ class EnumerableJoinRule extends ConverterRule {
// if it is an inner join.
try {
return new EnumerableThetaJoin(cluster, traitSet, left, right,
- join.getCondition(), join.getJoinType(),
- join.getVariablesStopped());
+ join.getCondition(), join.getVariablesSet(), join.getJoinType());
} catch (InvalidRelException e) {
EnumerableRules.LOGGER.fine(e.toString());
return null;
@@ -82,8 +81,8 @@ class EnumerableJoinRule extends ConverterRule {
info.getEquiCondition(left, right, cluster.getRexBuilder()),
info.leftKeys,
info.rightKeys,
- join.getJoinType(),
- join.getVariablesStopped());
+ join.getVariablesSet(),
+ join.getJoinType());
} catch (InvalidRelException e) {
EnumerableRules.LOGGER.fine(e.toString());
return null;
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java
index be0d821..18419e3 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java
@@ -28,6 +28,7 @@ import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelCollations;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.EquiJoin;
import org.apache.calcite.rel.core.JoinInfo;
import org.apache.calcite.rel.core.JoinRelType;
@@ -56,16 +57,25 @@ public class EnumerableMergeJoin extends EquiJoin implements EnumerableRel {
RexNode condition,
ImmutableIntList leftKeys,
ImmutableIntList rightKeys,
- JoinRelType joinType,
- Set<String> variablesStopped)
+ Set<CorrelationId> variablesSet,
+ JoinRelType joinType)
throws InvalidRelException {
super(cluster, traits, left, right, condition, leftKeys, rightKeys,
- joinType, variablesStopped);
+ variablesSet, joinType);
final List<RelCollation> collations =
traits.getTraits(RelCollationTraitDef.INSTANCE);
assert collations == null || RelCollations.contains(collations, leftKeys);
}
+ @Deprecated // to be removed before 2.0
+ EnumerableMergeJoin(RelOptCluster cluster, RelTraitSet traits, RelNode left,
+ RelNode right, RexNode condition, ImmutableIntList leftKeys,
+ ImmutableIntList rightKeys, JoinRelType joinType,
+ Set<String> variablesStopped) throws InvalidRelException {
+ this(cluster, traits, left, right, condition, leftKeys, rightKeys,
+ CorrelationId.setOf(variablesStopped), joinType);
+ }
+
public static EnumerableMergeJoin create(RelNode left, RelNode right,
RexLiteral condition, ImmutableIntList leftKeys,
ImmutableIntList rightKeys, JoinRelType joinType)
@@ -78,7 +88,7 @@ public class EnumerableMergeJoin extends EquiJoin implements EnumerableRel {
traitSet = traitSet.replace(collations);
}
return new EnumerableMergeJoin(cluster, traitSet, left, right, condition,
- leftKeys, rightKeys, joinType, ImmutableSet.<String>of());
+ leftKeys, rightKeys, ImmutableSet.<CorrelationId>of(), joinType);
}
@Override public EnumerableMergeJoin copy(RelTraitSet traitSet,
@@ -88,8 +98,8 @@ public class EnumerableMergeJoin extends EquiJoin implements EnumerableRel {
assert joinInfo.isEqui();
try {
return new EnumerableMergeJoin(getCluster(), traitSet, left, right,
- condition, joinInfo.leftKeys, joinInfo.rightKeys, joinType,
- variablesStopped);
+ condition, joinInfo.leftKeys, joinInfo.rightKeys, variablesSet,
+ joinType);
} catch (InvalidRelException e) {
// Semantic error not possible. Must be a bug. Convert to
// internal error.
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java
index 51f09f4..9dd0ce1 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoinRule.java
@@ -99,8 +99,8 @@ class EnumerableMergeJoinRule extends ConverterRule {
info.getEquiCondition(left, right, cluster.getRexBuilder()),
info.leftKeys,
info.rightKeys,
- join.getJoinType(),
- join.getVariablesStopped());
+ join.getVariablesSet(),
+ join.getJoinType());
} catch (InvalidRelException e) {
EnumerableRules.LOGGER.fine(e.toString());
return null;
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableThetaJoin.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableThetaJoin.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableThetaJoin.java
index bf4516a..e28ddfc 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableThetaJoin.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableThetaJoin.java
@@ -27,6 +27,7 @@ import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.InvalidRelException;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.Join;
import org.apache.calcite.rel.core.JoinRelType;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
@@ -43,11 +44,20 @@ import java.util.Set;
* {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}
* that allows conditions that are not just {@code =} (equals). */
public class EnumerableThetaJoin extends Join implements EnumerableRel {
+ /** Creates an EnumerableThetaJoin. */
+ protected EnumerableThetaJoin(RelOptCluster cluster, RelTraitSet traits,
+ RelNode left, RelNode right, RexNode condition,
+ Set<CorrelationId> variablesSet, JoinRelType joinType)
+ throws InvalidRelException {
+ super(cluster, traits, left, right, condition, variablesSet, joinType);
+ }
+
+ @Deprecated // to be removed before 2.0
protected EnumerableThetaJoin(RelOptCluster cluster, RelTraitSet traits,
RelNode left, RelNode right, RexNode condition, JoinRelType joinType,
Set<String> variablesStopped) throws InvalidRelException {
- super(cluster, traits, left, right, condition, joinType,
- variablesStopped);
+ this(cluster, traits, left, right, condition,
+ CorrelationId.setOf(variablesStopped), joinType);
}
@Override public EnumerableThetaJoin copy(RelTraitSet traitSet,
@@ -55,7 +65,7 @@ public class EnumerableThetaJoin extends Join implements EnumerableRel {
boolean semiJoinDone) {
try {
return new EnumerableThetaJoin(getCluster(), traitSet, left, right,
- condition, joinType, variablesStopped);
+ condition, variablesSet, joinType);
} catch (InvalidRelException e) {
// Semantic error not possible. Must be a bug. Convert to
// internal error.
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index 511584b..2633490 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -359,10 +359,8 @@ public class RexImpTable {
public T get() {
try {
return constructor.newInstance();
- } catch (InstantiationException e) {
- throw new IllegalStateException(
- "Unable to instantiate aggregate implementor " + constructor, e);
- } catch (IllegalAccessException | InvocationTargetException e) {
+ } catch (InstantiationException | IllegalAccessException
+ | InvocationTargetException e) {
throw new IllegalStateException(
"Error while creating aggregate implementor " + constructor, e);
}
@@ -1883,11 +1881,9 @@ public class RexImpTable {
return translator.translate(operands.get(0),
negate ? NullAs.IS_NOT_NULL : NullAs.IS_NULL);
} else {
- return maybeNegate(
- negate == seek,
- translator.translate(
- operands.get(0),
- negate == seek ? NullAs.TRUE : NullAs.FALSE));
+ return maybeNegate(negate == seek,
+ translator.translate(operands.get(0),
+ seek ? NullAs.FALSE : NullAs.TRUE));
}
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
index 5fbb08f..ca80d29 100644
--- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
+++ b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
@@ -35,6 +35,7 @@ import org.apache.calcite.rel.SingleRel;
import org.apache.calcite.rel.convert.ConverterRule;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.AggregateCall;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.core.Intersect;
import org.apache.calcite.rel.core.Join;
@@ -159,8 +160,8 @@ public class JdbcRules {
newInputs.get(0),
newInputs.get(1),
join.getCondition(),
- join.getJoinType(),
- join.getVariablesStopped());
+ join.getVariablesSet(),
+ join.getJoinType());
} catch (InvalidRelException e) {
LOGGER.fine(e.toString());
return null;
@@ -211,6 +212,15 @@ public class JdbcRules {
/** Join operator implemented in JDBC convention. */
public static class JdbcJoin extends Join implements JdbcRel {
+ /** Creates a JdbcJoin. */
+ protected JdbcJoin(RelOptCluster cluster, RelTraitSet traitSet,
+ RelNode left, RelNode right, RexNode condition,
+ Set<CorrelationId> variablesSet, JoinRelType joinType)
+ throws InvalidRelException {
+ super(cluster, traitSet, left, right, condition, variablesSet, joinType);
+ }
+
+ @Deprecated // to be removed before 2.0
protected JdbcJoin(
RelOptCluster cluster,
RelTraitSet traitSet,
@@ -220,8 +230,8 @@ public class JdbcRules {
JoinRelType joinType,
Set<String> variablesStopped)
throws InvalidRelException {
- super(cluster, traitSet, left, right, condition,
- joinType, variablesStopped);
+ this(cluster, traitSet, left, right, condition,
+ CorrelationId.setOf(variablesStopped), joinType);
}
@Override public JdbcJoin copy(RelTraitSet traitSet, RexNode condition,
@@ -229,7 +239,7 @@ public class JdbcRules {
boolean semiJoinDone) {
try {
return new JdbcJoin(getCluster(), traitSet, left, right,
- condition, joinType, variablesStopped);
+ condition, variablesSet, joinType);
} catch (InvalidRelException e) {
// Semantic error not possible. Must be a bug. Convert to
// internal error.
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/interpreter/Bindables.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/interpreter/Bindables.java b/core/src/main/java/org/apache/calcite/interpreter/Bindables.java
index a4474b4..9d4b250 100644
--- a/core/src/main/java/org/apache/calcite/interpreter/Bindables.java
+++ b/core/src/main/java/org/apache/calcite/interpreter/Bindables.java
@@ -37,6 +37,7 @@ import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.convert.ConverterRule;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.AggregateCall;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.core.Join;
import org.apache.calcite.rel.core.JoinRelType;
@@ -417,25 +418,33 @@ public class Bindables {
convert(join.getRight(),
join.getRight().getTraitSet()
.replace(BindableConvention.INSTANCE)),
- join.getCondition(), join.getJoinType(), join.getVariablesStopped());
+ join.getCondition(), join.getVariablesSet(), join.getJoinType());
}
}
/** Implementation of {@link org.apache.calcite.rel.core.Join} in
* bindable calling convention. */
public static class BindableJoin extends Join implements BindableRel {
+ /** Creates a BindableJoin. */
+ protected BindableJoin(RelOptCluster cluster, RelTraitSet traitSet,
+ RelNode left, RelNode right, RexNode condition,
+ Set<CorrelationId> variablesSet, JoinRelType joinType) {
+ super(cluster, traitSet, left, right, condition, variablesSet, joinType);
+ }
+
+ @Deprecated // to be removed before 2.0
protected BindableJoin(RelOptCluster cluster, RelTraitSet traitSet,
RelNode left, RelNode right, RexNode condition, JoinRelType joinType,
Set<String> variablesStopped) {
- super(cluster, traitSet, left, right, condition, joinType,
- variablesStopped);
+ this(cluster, traitSet, left, right, condition,
+ CorrelationId.setOf(variablesStopped), joinType);
}
public BindableJoin copy(RelTraitSet traitSet, RexNode conditionExpr,
RelNode left, RelNode right, JoinRelType joinType,
boolean semiJoinDone) {
return new BindableJoin(getCluster(), traitSet, left, right,
- conditionExpr, joinType, variablesStopped);
+ conditionExpr, variablesSet, joinType);
}
public Class<Object[]> getElementType() {
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/materialize/Lattice.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/materialize/Lattice.java b/core/src/main/java/org/apache/calcite/materialize/Lattice.java
index 62ab07f..244a245 100644
--- a/core/src/main/java/org/apache/calcite/materialize/Lattice.java
+++ b/core/src/main/java/org/apache/calcite/materialize/Lattice.java
@@ -44,7 +44,6 @@ import org.apache.calcite.sql.SqlSelect;
import org.apache.calcite.sql.SqlUtil;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.validate.SqlValidatorUtil;
-import org.apache.calcite.util.BitSets;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.graph.DefaultDirectedGraph;
import org.apache.calcite.util.graph.DefaultEdge;
@@ -260,7 +259,7 @@ public class Lattice {
final StringBuilder groupBuf = new StringBuilder("\nGROUP BY ");
int k = 0;
final Set<String> columnNames = Sets.newHashSet();
- for (int i : BitSets.toIter(groupSet)) {
+ for (int i : groupSet) {
if (k++ > 0) {
buf.append(", ");
groupBuf.append(", ");
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/plan/RelOptCluster.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptCluster.java b/core/src/main/java/org/apache/calcite/plan/RelOptCluster.java
index c4592db..241f4e0 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptCluster.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptCluster.java
@@ -17,6 +17,7 @@
package org.apache.calcite.plan;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.metadata.DefaultRelMetadataProvider;
import org.apache.calcite.rel.metadata.MetadataFactory;
import org.apache.calcite.rel.metadata.MetadataFactoryImpl;
@@ -143,8 +144,8 @@ public class RelOptCluster {
* Constructs a new id for a correlating variable. It is unique within the
* whole query.
*/
- public int createCorrel() {
- return nextCorrel.getAndIncrement();
+ public CorrelationId createCorrel() {
+ return new CorrelationId(nextCorrel.getAndIncrement());
}
/** Returns the default trait set for this cluster. */
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/plan/RelOptQuery.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptQuery.java b/core/src/main/java/org/apache/calcite/plan/RelOptQuery.java
index 2c2703d..34f5c5f 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptQuery.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptQuery.java
@@ -17,6 +17,7 @@
package org.apache.calcite.plan;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rex.RexBuilder;
@@ -35,7 +36,7 @@ public class RelOptQuery {
/**
* Prefix to the name of correlating variables.
*/
- public static final String CORREL_PREFIX = "$cor";
+ public static final String CORREL_PREFIX = CorrelationId.CORREL_PREFIX;
//~ Instance fields --------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
index b932cef..eeaea21 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -26,6 +26,7 @@ import org.apache.calcite.rel.RelVisitor;
import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.core.Calc;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.core.Join;
import org.apache.calcite.rel.core.JoinRelType;
@@ -60,6 +61,7 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexOver;
import org.apache.calcite.rex.RexProgram;
import org.apache.calcite.rex.RexShuttle;
+import org.apache.calcite.rex.RexSubQuery;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.rex.RexVisitorImpl;
import org.apache.calcite.sql.SqlExplainLevel;
@@ -83,7 +85,9 @@ import org.apache.calcite.util.mapping.Mappings;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -155,7 +159,7 @@ public abstract class RelOptUtil {
* Returns a list of variables set by a relational expression or its
* descendants.
*/
- public static Set<String> getVariablesSet(RelNode rel) {
+ public static Set<CorrelationId> getVariablesSet(RelNode rel) {
VariableSetVisitor visitor = new VariableSetVisitor();
go(visitor, rel);
return visitor.variables;
@@ -165,19 +169,18 @@ public abstract class RelOptUtil {
* Returns a set of distinct variables set by <code>rel0</code> and used by
* <code>rel1</code>.
*/
- public static List<String> getVariablesSetAndUsed(
- RelNode rel0,
+ public static List<CorrelationId> getVariablesSetAndUsed(RelNode rel0,
RelNode rel1) {
- Set<String> set = getVariablesSet(rel0);
+ Set<CorrelationId> set = getVariablesSet(rel0);
if (set.size() == 0) {
return ImmutableList.of();
}
- Set<String> used = getVariablesUsed(rel1);
+ Set<CorrelationId> used = getVariablesUsed(rel1);
if (used.size() == 0) {
return ImmutableList.of();
}
- final List<String> result = new ArrayList<>();
- for (String s : set) {
+ final List<CorrelationId> result = new ArrayList<>();
+ for (CorrelationId s : set) {
if (used.contains(s) && !result.contains(s)) {
result.add(s);
}
@@ -187,24 +190,45 @@ public abstract class RelOptUtil {
/**
* Returns a set of variables used by a relational expression or its
- * descendants. The set may contain duplicates. The item type is the same as
- * {@link org.apache.calcite.rex.RexVariable#getName}
- */
- public static Set<String> getVariablesUsed(RelNode rel) {
- final VariableUsedVisitor vuv = new VariableUsedVisitor();
- RelShuttle visitor = new RelHomogeneousShuttle() {
- @Override public RelNode visit(RelNode other) {
- other.collectVariablesUsed(vuv.variables);
- other.accept(vuv);
- RelNode result = super.visit(other);
- // Important! Remove stopped variables AFTER we visit
- // children. (which what super.visit() does)
- vuv.variables.removeAll(other.getVariablesStopped());
- return result;
- }
- };
+ * descendants.
+ *
+ * <p>The set may contain "duplicates" (variables with different ids that,
+ * when resolved, will reference the same source relational expression).
+ *
+ * <p>The item type is the same as
+ * {@link org.apache.calcite.rex.RexCorrelVariable#id}.
+ */
+ public static Set<CorrelationId> getVariablesUsed(RelNode rel) {
+ CorrelationCollector visitor = new CorrelationCollector();
rel.accept(visitor);
- return vuv.variables;
+ return visitor.vuv.variables;
+ }
+
+ /** Finds which columns of a correlation variable are used within a
+ * relational expression. */
+ public static ImmutableBitSet correlationColumns(CorrelationId id,
+ RelNode rel) {
+ final CorrelationCollector collector = new CorrelationCollector();
+ rel.accept(collector);
+ final ImmutableBitSet.Builder builder = ImmutableBitSet.builder();
+ for (int field : collector.vuv.variableFields.get(id)) {
+ if (field >= 0) {
+ builder.set(field);
+ }
+ }
+ return builder.build();
+ }
+
+ /** Returns true, and calls {@link Litmus#succeed()} if a given relational
+ * expression does not contain a given correlation. */
+ public static boolean notContainsCorrelation(RelNode r,
+ CorrelationId correlationId, Litmus litmus) {
+ final Set<CorrelationId> set = getVariablesUsed(r);
+ if (!set.contains(correlationId)) {
+ return litmus.succeed();
+ } else {
+ return litmus.fail("contains " + correlationId);
+ }
}
/**
@@ -2946,6 +2970,7 @@ public abstract class RelOptUtil {
public Logic negate() {
switch (this) {
case UNKNOWN_AS_FALSE:
+ case TRUE:
return UNKNOWN_AS_TRUE;
case UNKNOWN_AS_TRUE:
return UNKNOWN_AS_FALSE;
@@ -2982,7 +3007,8 @@ public abstract class RelOptUtil {
// Pushing sub-queries is OK in principle (if they don't reference both
// sides of the join via correlating variables) but we'd rather not do it
// yet.
- if (!containsGet(joinCond)) {
+ if (!containsGet(joinCond)
+ && RexUtil.SubQueryFinder.find(joinCond) == null) {
joinCond = pushDownEqualJoinConditions(
joinCond, leftCount, rightCount, extraLeftExprs, extraRightExprs);
}
@@ -3177,7 +3203,7 @@ public abstract class RelOptUtil {
/** Visitor that finds all variables used but not stopped in an expression. */
private static class VariableSetVisitor extends RelVisitor {
- final Set<String> variables = new HashSet<>();
+ final Set<CorrelationId> variables = new HashSet<>();
// implement RelVisitor
public void visit(
@@ -3189,18 +3215,42 @@ public abstract class RelOptUtil {
// Important! Remove stopped variables AFTER we visit children
// (which what super.visit() does)
- variables.removeAll(p.getVariablesStopped());
+ variables.removeAll(p.getVariablesSet());
}
}
/** Visitor that finds all variables used in an expression. */
public static class VariableUsedVisitor extends RexShuttle {
- public final Set<String> variables = new LinkedHashSet<>();
+ public final Set<CorrelationId> variables = new LinkedHashSet<>();
+ public final Multimap<CorrelationId, Integer> variableFields =
+ LinkedHashMultimap.create();
+ private final RelShuttle relShuttle;
+
+ public VariableUsedVisitor(RelShuttle relShuttle) {
+ this.relShuttle = relShuttle;
+ }
- public RexNode visitCorrelVariable(RexCorrelVariable p) {
- variables.add(p.getName());
+ @Override public RexNode visitCorrelVariable(RexCorrelVariable p) {
+ variables.add(p.id);
+ variableFields.put(p.id, -1);
return p;
}
+
+ @Override public RexNode visitFieldAccess(RexFieldAccess fieldAccess) {
+ if (fieldAccess.getReferenceExpr() instanceof RexCorrelVariable) {
+ final RexCorrelVariable v =
+ (RexCorrelVariable) fieldAccess.getReferenceExpr();
+ variableFields.put(v.id, fieldAccess.getField().getIndex());
+ }
+ return super.visitFieldAccess(fieldAccess);
+ }
+
+ @Override public RexNode visitSubQuery(RexSubQuery subQuery) {
+ if (relShuttle != null) {
+ subQuery.rel.accept(relShuttle); // look inside sub-queries
+ }
+ return super.visitSubQuery(subQuery);
+ }
}
/** Shuttle that finds the set of inputs that are used. */
@@ -3462,6 +3512,23 @@ public abstract class RelOptUtil {
return BOTH;
}
}
+
+ /** Shuttle that finds correlation variables inside a given relational
+ * expression, including those that are inside
+ * {@link RexSubQuery sub-queries}. */
+ private static class CorrelationCollector extends RelHomogeneousShuttle {
+ private final VariableUsedVisitor vuv = new VariableUsedVisitor(this);
+
+ @Override public RelNode visit(RelNode other) {
+ other.collectVariablesUsed(vuv.variables);
+ other.accept(vuv);
+ RelNode result = super.visit(other);
+ // Important! Remove stopped variables AFTER we visit
+ // children. (which what super.visit() does)
+ vuv.variables.removeAll(other.getVariablesSet());
+ return result;
+ }
+ }
}
// End RelOptUtil.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
index 8dd0d01..ccbe2c2 100644
--- a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
+++ b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
@@ -24,6 +24,7 @@ import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.SingleRel;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.AggregateCall;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.core.Join;
import org.apache.calcite.rel.core.JoinRelType;
@@ -249,7 +250,7 @@ public class SubstitutionVisitor {
final MutableRel left = toMutable(join.getLeft());
final MutableRel right = toMutable(join.getRight());
return MutableJoin.of(join.getCluster(), left, right,
- join.getCondition(), join.getJoinType(), join.getVariablesStopped());
+ join.getCondition(), join.getJoinType(), join.getVariablesSet());
}
if (rel instanceof Sort) {
final Sort sort = (Sort) rel;
@@ -646,7 +647,7 @@ public class SubstitutionVisitor {
case JOIN:
final MutableJoin join = (MutableJoin) node;
return LogicalJoin.create(fromMutable(join.getLeft()), fromMutable(join.getRight()),
- join.getCondition(), join.getJoinType(), join.getVariablesStopped());
+ join.getCondition(), join.getVariablesSet(), join.getJoinType());
default:
throw new AssertionError(node.deep());
}
@@ -690,7 +691,7 @@ public class SubstitutionVisitor {
final MutableJoin join = (MutableJoin) node;
return MutableJoin.of(join.cluster, copyMutable(join.getLeft()),
copyMutable(join.getRight()), join.getCondition(), join.getJoinType(),
- join.getVariablesStopped());
+ join.getVariablesSet());
default:
throw new AssertionError(node.deep());
}
@@ -1980,7 +1981,7 @@ public class SubstitutionVisitor {
//~ Instance fields --------------------------------------------------------
protected final RexNode condition;
- protected final ImmutableSet<String> variablesStopped;
+ protected final ImmutableSet<CorrelationId> variablesSet;
/**
* Values must be of enumeration {@link JoinRelType}, except that
@@ -1994,10 +1995,10 @@ public class SubstitutionVisitor {
MutableRel right,
RexNode condition,
JoinRelType joinType,
- Set<String> variablesStopped) {
+ Set<CorrelationId> variablesSet) {
super(MutableRelType.JOIN, left.cluster, rowType, left, right);
this.condition = Preconditions.checkNotNull(condition);
- this.variablesStopped = ImmutableSet.copyOf(variablesStopped);
+ this.variablesSet = ImmutableSet.copyOf(variablesSet);
this.joinType = Preconditions.checkNotNull(joinType);
}
@@ -2009,13 +2010,13 @@ public class SubstitutionVisitor {
return joinType;
}
- public ImmutableSet getVariablesStopped() {
- return variablesStopped;
+ public ImmutableSet<CorrelationId> getVariablesSet() {
+ return variablesSet;
}
static MutableJoin of(RelOptCluster cluster, MutableRel left,
MutableRel right, RexNode condition, JoinRelType joinType,
- Set<String> variablesStopped) {
+ Set<CorrelationId> variablesStopped) {
List<RelDataTypeField> fieldList = Collections.emptyList();
RelDataType rowType =
Join.deriveJoinRowType(left.getRowType(), right.getRowType(),
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/plan/volcano/RelSet.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/RelSet.java b/core/src/main/java/org/apache/calcite/plan/volcano/RelSet.java
index 93d8509..cf78dff 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/RelSet.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/RelSet.java
@@ -22,6 +22,7 @@ import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.plan.RelTrait;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.util.trace.CalciteTrace;
import com.google.common.collect.ImmutableList;
@@ -47,21 +48,20 @@ class RelSet {
//~ Instance fields --------------------------------------------------------
- final List<RelNode> rels = new ArrayList<RelNode>();
+ final List<RelNode> rels = new ArrayList<>();
/**
* Relational expressions that have a subset in this set as a child. This
* is a multi-set. If multiple relational expressions in this set have the
* same parent, there will be multiple entries.
*/
- final List<RelNode> parents = new ArrayList<RelNode>();
- final List<RelSubset> subsets = new ArrayList<RelSubset>();
+ final List<RelNode> parents = new ArrayList<>();
+ final List<RelSubset> subsets = new ArrayList<>();
/**
* List of {@link AbstractConverter} objects which have not yet been
* satisfied.
*/
- final List<AbstractConverter> abstractConverters =
- new ArrayList<AbstractConverter>();
+ final List<AbstractConverter> abstractConverters = new ArrayList<>();
/**
* Set to the superseding set when this is found to be equivalent to another
@@ -71,15 +71,15 @@ class RelSet {
RelNode rel;
/**
- * Names of variables which are set by relational expressions in this set
+ * Variables that are set by relational expressions in this set
* and available for use by parent and child expressions.
*/
- final Set<String> variablesPropagated;
+ final Set<CorrelationId> variablesPropagated;
/**
- * Names of variables which are used by relational expressions in this set.
+ * Variables that are used by relational expressions in this set.
*/
- final Set<String> variablesUsed;
+ final Set<CorrelationId> variablesUsed;
final int id;
/**
@@ -91,8 +91,8 @@ class RelSet {
RelSet(
int id,
- Set<String> variablesPropagated,
- Set<String> variablesUsed) {
+ Set<CorrelationId> variablesPropagated,
+ Set<CorrelationId> variablesUsed) {
this.id = id;
this.variablesPropagated = variablesPropagated;
this.variablesUsed = variablesUsed;
@@ -275,7 +275,7 @@ class RelSet {
}
// Make sure the cost changes as a result of merging are propagated.
- Set<RelSubset> activeSet = new HashSet<RelSubset>();
+ Set<RelSubset> activeSet = new HashSet<>();
for (RelNode parentRel : getParentRels()) {
final RelSubset parentSubset = planner.getSubset(parentRel);
parentSubset.propagateCostImprovements(
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java b/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
index bb42218..3fede02 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
@@ -28,6 +28,7 @@ import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.AbstractRelNode;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelWriter;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.util.Litmus;
@@ -136,14 +137,6 @@ public class RelSubset extends AbstractRelNode {
}
}
- public Set<String> getVariablesSet() {
- return set.variablesPropagated;
- }
-
- public Set<String> getVariablesUsed() {
- return set.variablesUsed;
- }
-
public RelNode getBest() {
return best;
}
@@ -164,7 +157,7 @@ public class RelSubset extends AbstractRelNode {
}
}
- public void explain(RelWriter pw) {
+ @Override public void explain(RelWriter pw) {
// Not a typical implementation of "explain". We don't gather terms &
// values to be printed later. We actually do the work.
String s = getDescription();
@@ -178,7 +171,7 @@ public class RelSubset extends AbstractRelNode {
pw.done(input);
}
- protected String computeDigest() {
+ @Override protected String computeDigest() {
StringBuilder digest = new StringBuilder("Subset#");
digest.append(set.id);
for (RelTrait trait : traitSet) {
@@ -276,13 +269,13 @@ public class RelSubset extends AbstractRelNode {
"rowtype of set", getRowType(), Litmus.THROW);
}
set.addInternal(rel);
- Set<String> variablesSet = RelOptUtil.getVariablesSet(rel);
- Set<String> variablesStopped = rel.getVariablesStopped();
+ Set<CorrelationId> variablesSet = RelOptUtil.getVariablesSet(rel);
+ Set<CorrelationId> variablesStopped = rel.getVariablesSet();
if (false) {
- Set<String> variablesPropagated =
+ Set<CorrelationId> variablesPropagated =
Util.minus(variablesSet, variablesStopped);
assert set.variablesPropagated.containsAll(variablesPropagated);
- Set<String> variablesUsed = RelOptUtil.getVariablesUsed(rel);
+ Set<CorrelationId> variablesUsed = RelOptUtil.getVariablesUsed(rel);
assert set.variablesUsed.containsAll(variablesUsed);
}
}
@@ -375,12 +368,12 @@ public class RelSubset extends AbstractRelNode {
}
}
- public void collectVariablesUsed(Set<String> variableSet) {
- variableSet.addAll(getVariablesUsed());
+ @Override public void collectVariablesUsed(Set<CorrelationId> variableSet) {
+ variableSet.addAll(set.variablesUsed);
}
- public void collectVariablesSet(Set<String> variableSet) {
- variableSet.addAll(getVariablesSet());
+ @Override public void collectVariablesSet(Set<CorrelationId> variableSet) {
+ variableSet.addAll(set.variablesPropagated);
}
/**
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
index 4186232..425ebec 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
@@ -1759,7 +1759,7 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
nextSetId++,
Util.minus(
RelOptUtil.getVariablesSet(rel),
- rel.getVariablesStopped()),
+ rel.getVariablesSet()),
RelOptUtil.getVariablesUsed(rel));
this.allSets.add(set);
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/prepare/Prepare.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/Prepare.java b/core/src/main/java/org/apache/calcite/prepare/Prepare.java
index 3530e93..e624d1d 100644
--- a/core/src/main/java/org/apache/calcite/prepare/Prepare.java
+++ b/core/src/main/java/org/apache/calcite/prepare/Prepare.java
@@ -87,9 +87,13 @@ public abstract class Prepare {
public static final TryThreadLocal<Boolean> THREAD_TRIM =
TryThreadLocal.of(false);
- /** Temporary, while CALCITE-816 is under development.
+ /** Temporary, until
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-1045">[CALCITE-1045]
+ * Decorrelate sub-queries in Project and Join</a> is fixed.
*
- * @see org.apache.calcite.util.Util#deprecated(Object, boolean) */
+ * <p>The default is false, meaning do not expand queries during sql-to-rel,
+ * but a few tests override and set it to true. After CALCITE-1045
+ * is fixed, remove those overrides and use false everywhere. */
public static final TryThreadLocal<Boolean> THREAD_EXPAND =
TryThreadLocal.of(false);
@@ -209,6 +213,7 @@ public abstract class Prepare {
SqlToRelConverter sqlToRelConverter =
getSqlToRelConverter(validator, catalogReader);
+ sqlToRelConverter.setExpand(THREAD_EXPAND.get());
SqlExplain sqlExplain = null;
if (sqlQuery.getKind() == SqlKind.EXPLAIN) {
@@ -344,6 +349,7 @@ public abstract class Prepare {
getSqlToRelConverter(
getSqlValidator(), catalogReader);
converter.setTrimUnusedFields(shouldTrim(root.rel));
+ converter.setExpand(THREAD_EXPAND.get());
final boolean ordered = !root.collation.getFieldCollations().isEmpty();
final boolean dml = SqlKind.DML.contains(root.kind);
return root.withRel(converter.trimUnusedFields(dml || ordered, root.rel));
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java b/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
index 1938447..75a546c 100644
--- a/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
+++ b/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
@@ -26,6 +26,7 @@ import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.plan.RelTrait;
import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.externalize.RelWriterImpl;
import org.apache.calcite.rel.metadata.Metadata;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
@@ -40,6 +41,7 @@ import org.apache.calcite.util.Util;
import org.apache.calcite.util.trace.CalciteTrace;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -237,15 +239,19 @@ public abstract class AbstractRelNode implements RelNode {
return 1.0;
}
- public Set<String> getVariablesStopped() {
- return Collections.emptySet();
+ public final Set<String> getVariablesStopped() {
+ return CorrelationId.names(getVariablesSet());
}
- public void collectVariablesUsed(Set<String> variableSet) {
+ public Set<CorrelationId> getVariablesSet() {
+ return ImmutableSet.of();
+ }
+
+ public void collectVariablesUsed(Set<CorrelationId> variableSet) {
// for default case, nothing to do
}
- public void collectVariablesSet(Set<String> variableSet) {
+ public void collectVariablesSet(Set<CorrelationId> variableSet) {
}
public void childrenAccept(RelVisitor visitor) {
@@ -305,7 +311,7 @@ public abstract class AbstractRelNode implements RelNode {
public RelNode onRegister(RelOptPlanner planner) {
List<RelNode> oldInputs = getInputs();
- List<RelNode> inputs = new ArrayList<RelNode>(oldInputs.size());
+ List<RelNode> inputs = new ArrayList<>(oldInputs.size());
for (final RelNode input : oldInputs) {
RelNode e = planner.ensureRegistered(input, null);
if (e != input) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/rel/RelNode.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/RelNode.java b/core/src/main/java/org/apache/calcite/rel/RelNode.java
index 29dc023..973bc98 100644
--- a/core/src/main/java/org/apache/calcite/rel/RelNode.java
+++ b/core/src/main/java/org/apache/calcite/rel/RelNode.java
@@ -23,6 +23,7 @@ import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptQuery;
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.metadata.Metadata;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.type.RelDataType;
@@ -175,18 +176,40 @@ public interface RelNode extends RelOptNode, Cloneable {
double getRows();
/**
- * Returns the names of variables which are set in this relational
+ * Returns the names of variables that are set in this relational
* expression but also used and therefore not available to parents of this
* relational expression.
+ *
* <p>Note: only {@link org.apache.calcite.rel.core.Correlate} should set
- * variables</p>
+ * variables.
+ *
+ * <p>Note: {@link #getVariablesSet()} is equivalent but returns
+ * {@link CorrelationId} rather than their names. It is preferable except for
+ * calling old methods that require a set of strings.
*
* @return Names of variables which are set in this relational
* expression
+ *
+ * @deprecated Use {@link #getVariablesSet()}
+ * and {@link CorrelationId#names(Set)}
*/
+ @Deprecated // to be removed before 2.0
Set<String> getVariablesStopped();
/**
+ * Returns the variables that are set in this relational
+ * expression but also used and therefore not available to parents of this
+ * relational expression.
+ *
+ * <p>Note: only {@link org.apache.calcite.rel.core.Correlate} should set
+ * variables.
+ *
+ * @return Names of variables which are set in this relational
+ * expression
+ */
+ Set<CorrelationId> getVariablesSet();
+
+ /**
* Collects variables known to be used by this expression or its
* descendants. By default, no such information is available and must be
* derived by analyzing sub-expressions, but some optimizer implementations
@@ -194,7 +217,7 @@ public interface RelNode extends RelOptNode, Cloneable {
*
* @param variableSet receives variables used
*/
- void collectVariablesUsed(Set<String> variableSet);
+ void collectVariablesUsed(Set<CorrelationId> variableSet);
/**
* Collects variables set by this expression.
@@ -202,7 +225,7 @@ public interface RelNode extends RelOptNode, Cloneable {
*
* @param variableSet receives variables known to be set by
*/
- void collectVariablesSet(Set<String> variableSet);
+ void collectVariablesSet(Set<CorrelationId> variableSet);
/**
* Interacts with the {@link RelVisitor} in a
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/rel/core/Correlate.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/Correlate.java b/core/src/main/java/org/apache/calcite/rel/core/Correlate.java
index b1c0e04..982a762 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/Correlate.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/Correlate.java
@@ -19,6 +19,7 @@ package org.apache.calcite.rel.core;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptCost;
import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.BiRel;
import org.apache.calcite.rel.RelInput;
@@ -29,6 +30,7 @@ import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.sql.SemiJoinType;
import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.Litmus;
import com.google.common.collect.ImmutableSet;
@@ -109,6 +111,11 @@ public abstract class Correlate extends BiRel {
//~ Methods ----------------------------------------------------------------
+ @Override public boolean isValid(Litmus litmus) {
+ return super.isValid(litmus)
+ && RelOptUtil.notContainsCorrelation(left, correlationId, litmus);
+ }
+
@Override public Correlate copy(RelTraitSet traitSet, List<RelNode> inputs) {
assert inputs.size() == 2;
return copy(traitSet,
@@ -133,8 +140,8 @@ public abstract class Correlate extends BiRel {
case INNER:
// LogicalJoin is used to share the code of column names deduplication
final LogicalJoin join = LogicalJoin.create(left, right,
- getCluster().getRexBuilder().makeLiteral(true), joinType.toJoinType(),
- ImmutableSet.<String>of());
+ getCluster().getRexBuilder().makeLiteral(true),
+ ImmutableSet.<CorrelationId>of(), joinType.toJoinType());
return join.deriveRowType();
case ANTI:
case SEMI:
@@ -174,8 +181,8 @@ public abstract class Correlate extends BiRel {
return requiredColumns;
}
- @Override public Set<String> getVariablesStopped() {
- return ImmutableSet.of(correlationId.getName());
+ @Override public Set<CorrelationId> getVariablesSet() {
+ return ImmutableSet.of(correlationId);
}
@Override public RelOptCost computeSelfCost(RelOptPlanner planner) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/rel/core/CorrelationId.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/CorrelationId.java b/core/src/main/java/org/apache/calcite/rel/core/CorrelationId.java
index 2b2558c..d5d74c9 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/CorrelationId.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/CorrelationId.java
@@ -16,39 +16,51 @@
*/
package org.apache.calcite.rel.core;
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Set;
+
/**
* Describes the necessary parameters for an implementation in order to
* identify and set dynamic variables
*/
public class CorrelationId implements Cloneable, Comparable<CorrelationId> {
- private static final String CORREL_PREFIX = "$cor";
+ /**
+ * Prefix to the name of correlating variables.
+ */
+ public static final String CORREL_PREFIX = "$cor";
private final int id;
private final String name;
/**
* Creates a correlation identifier.
+ */
+ private CorrelationId(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ /**
+ * Creates a correlation identifier.
* This is a type-safe wrapper over int.
*
* @param id Identifier
*/
public CorrelationId(int id) {
- this.id = id;
- this.name = CORREL_PREFIX + id;
+ this(id, CORREL_PREFIX + id);
}
/**
- * Creates a correlation identifier.
- * This is a type-safe wrapper over int.
+ * Creates a correlation identifier from a name.
*
* @param name variable name
*/
public CorrelationId(String name) {
- assert name != null && name.startsWith(CORREL_PREFIX)
+ this(Integer.parseInt(name.substring(CORREL_PREFIX.length())), name);
+ assert name.startsWith(CORREL_PREFIX)
: "Correlation name should start with " + CORREL_PREFIX
+ " actual name is " + name;
- this.id = Integer.parseInt(name.substring(CORREL_PREFIX.length()));
- this.name = name;
}
/**
@@ -61,7 +73,7 @@ public class CorrelationId implements Cloneable, Comparable<CorrelationId> {
}
/**
- * Returns the preffered name of the variable.
+ * Returns the preferred name of the variable.
*
* @return name
*/
@@ -86,6 +98,30 @@ public class CorrelationId implements Cloneable, Comparable<CorrelationId> {
|| obj instanceof CorrelationId
&& this.id == ((CorrelationId) obj).id;
}
+
+ /** Converts a set of correlation ids to a set of names. */
+ public static ImmutableSet<CorrelationId> setOf(Set<String> set) {
+ if (set.isEmpty()) {
+ return ImmutableSet.of();
+ }
+ final ImmutableSet.Builder<CorrelationId> builder = ImmutableSet.builder();
+ for (String s : set) {
+ builder.add(new CorrelationId(s));
+ }
+ return builder.build();
+ }
+
+ /** Converts a set of names to a set of correlation ids. */
+ public static Set<String> names(Set<CorrelationId> set) {
+ if (set.isEmpty()) {
+ return ImmutableSet.of();
+ }
+ final ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+ for (CorrelationId s : set) {
+ builder.add(s.name);
+ }
+ return builder.build();
+ }
}
// End CorrelationId.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/rel/core/EquiJoin.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/EquiJoin.java b/core/src/main/java/org/apache/calcite/rel/core/EquiJoin.java
index 3a06c86..a45a854 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/EquiJoin.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/EquiJoin.java
@@ -36,13 +36,22 @@ public abstract class EquiJoin extends Join {
/** Creates an EquiJoin. */
public EquiJoin(RelOptCluster cluster, RelTraitSet traits, RelNode left,
RelNode right, RexNode condition, ImmutableIntList leftKeys,
- ImmutableIntList rightKeys, JoinRelType joinType,
- Set<String> variablesStopped) {
- super(cluster, traits, left, right, condition, joinType, variablesStopped);
+ ImmutableIntList rightKeys, Set<CorrelationId> variablesSet,
+ JoinRelType joinType) {
+ super(cluster, traits, left, right, condition, variablesSet, joinType);
this.leftKeys = Preconditions.checkNotNull(leftKeys);
this.rightKeys = Preconditions.checkNotNull(rightKeys);
}
+ @Deprecated // to be removed before 2.0
+ public EquiJoin(RelOptCluster cluster, RelTraitSet traits, RelNode left,
+ RelNode right, RexNode condition, ImmutableIntList leftKeys,
+ ImmutableIntList rightKeys, JoinRelType joinType,
+ Set<String> variablesStopped) {
+ this(cluster, traits, left, right, condition, leftKeys, rightKeys,
+ CorrelationId.setOf(variablesStopped), joinType);
+ }
+
public ImmutableIntList getLeftKeys() {
return leftKeys;
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/rel/core/Join.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/Join.java b/core/src/main/java/org/apache/calcite/rel/core/Join.java
index bb460ff..3ac32d2 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/Join.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/Join.java
@@ -35,6 +35,7 @@ import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.util.Litmus;
import org.apache.calcite.util.Util;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -56,43 +57,67 @@ public abstract class Join extends BiRel {
//~ Instance fields --------------------------------------------------------
protected final RexNode condition;
- protected final ImmutableSet<String> variablesStopped;
+ protected final ImmutableSet<CorrelationId> variablesSet;
/**
* Values must be of enumeration {@link JoinRelType}, except that
* {@link JoinRelType#RIGHT} is disallowed.
*/
- protected JoinRelType joinType;
+ protected final JoinRelType joinType;
//~ Constructors -----------------------------------------------------------
+ // Next time we need to change the constructor of Join, let's change the
+ // "Set<String> variablesStopped" parameter to
+ // "Set<CorrelationId> variablesSet". At that point we would deprecate
+ // RelNode.getVariablesStopped().
+
/**
* Creates a Join.
*
+ * <p>Note: We plan to change the {@code variablesStopped} parameter to
+ * {@code Set<CorrelationId> variablesSet}
+ * {@link org.apache.calcite.util.Bug#upgrade(String) before version 2.0},
+ * because {@link #getVariablesSet()}
+ * is preferred over {@link #getVariablesStopped()}.
+ * This constructor is not deprecated, for now, because maintaining overloaded
+ * constructors in multiple sub-classes would be onerous.
+ *
* @param cluster Cluster
- * @param traits Traits
+ * @param traitSet Trait set
* @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
+ * @param variablesSet Set variables that are set by the
* LHS and used by the RHS and are not available to
- * nodes above this LogicalJoin in the tree
+ * nodes above this Join in the tree
*/
protected Join(
RelOptCluster cluster,
- RelTraitSet traits,
+ RelTraitSet traitSet,
+ RelNode left,
+ RelNode right,
+ RexNode condition,
+ Set<CorrelationId> variablesSet,
+ JoinRelType joinType) {
+ super(cluster, traitSet, left, right);
+ this.condition = Preconditions.checkNotNull(condition);
+ this.variablesSet = ImmutableSet.copyOf(variablesSet);
+ this.joinType = Preconditions.checkNotNull(joinType);
+ }
+
+ @Deprecated // to be removed before 2.0
+ protected Join(
+ RelOptCluster cluster,
+ RelTraitSet traitSet,
RelNode left,
RelNode right,
RexNode condition,
JoinRelType joinType,
Set<String> variablesStopped) {
- super(cluster, traits, left, right);
- this.condition = condition;
- this.variablesStopped = ImmutableSet.copyOf(variablesStopped);
- assert joinType != null;
- assert condition != null;
- this.joinType = joinType;
+ this(cluster, traitSet, left, right, condition,
+ CorrelationId.setOf(variablesStopped), joinType);
}
//~ Methods ----------------------------------------------------------------
@@ -172,8 +197,8 @@ public abstract class Join extends BiRel {
return Util.first(RelMdUtil.getJoinRowCount(this, condition), 1D);
}
- @Override public Set<String> getVariablesStopped() {
- return variablesStopped;
+ @Override public Set<CorrelationId> getVariablesSet() {
+ return variablesSet;
}
@Override public RelWriter explainTerms(RelWriter pw) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java b/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java
index d58150b..6c410b9 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java
@@ -24,6 +24,7 @@ import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.logical.LogicalAggregate;
+import org.apache.calcite.rel.logical.LogicalCorrelate;
import org.apache.calcite.rel.logical.LogicalFilter;
import org.apache.calcite.rel.logical.LogicalIntersect;
import org.apache.calcite.rel.logical.LogicalJoin;
@@ -37,6 +38,7 @@ import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.sql.SemiJoinType;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.tools.RelBuilderFactory;
@@ -60,6 +62,9 @@ public class RelFactories {
public static final JoinFactory DEFAULT_JOIN_FACTORY = new JoinFactoryImpl();
+ public static final CorrelateFactory DEFAULT_CORRELATE_FACTORY =
+ new CorrelateFactoryImpl();
+
public static final SemiJoinFactory DEFAULT_SEMI_JOIN_FACTORY =
new SemiJoinFactoryImpl();
@@ -234,14 +239,19 @@ public class RelFactories {
* @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
+ * @param variablesSet Set of variables that are set by the
* LHS and used by the RHS and are not available to
* nodes above this LogicalJoin in the tree
+ * @param joinType Join type
* @param semiJoinDone Whether this join has been translated to a
* semi-join
*/
RelNode createJoin(RelNode left, RelNode right, RexNode condition,
+ Set<CorrelationId> variablesSet, JoinRelType joinType,
+ boolean semiJoinDone);
+
+ @Deprecated // to be removed before 2.0
+ RelNode createJoin(RelNode left, RelNode right, RexNode condition,
JoinRelType joinType, Set<String> variablesStopped,
boolean semiJoinDone);
}
@@ -252,10 +262,51 @@ public class RelFactories {
*/
private static class JoinFactoryImpl implements JoinFactory {
public RelNode createJoin(RelNode left, RelNode right,
- RexNode condition, JoinRelType joinType,
- Set<String> variablesStopped, boolean semiJoinDone) {
- return LogicalJoin.create(left, right, condition, joinType,
- variablesStopped, semiJoinDone, ImmutableList.<RelDataTypeField>of());
+ RexNode condition, Set<CorrelationId> variablesSet,
+ JoinRelType joinType, boolean semiJoinDone) {
+ return LogicalJoin.create(left, right, condition, variablesSet, joinType,
+ semiJoinDone, ImmutableList.<RelDataTypeField>of());
+ }
+
+ public RelNode createJoin(RelNode left, RelNode right, RexNode condition,
+ JoinRelType joinType, Set<String> variablesStopped,
+ boolean semiJoinDone) {
+ return createJoin(left, right, condition,
+ CorrelationId.setOf(variablesStopped), joinType, semiJoinDone);
+ }
+ }
+
+ /**
+ * Can create a correlate of the appropriate type for a rule's calling
+ * convention.
+ *
+ * <p>The result is typically a {@link Correlate}.
+ */
+ public interface CorrelateFactory {
+ /**
+ * Creates a correlate.
+ *
+ * @param left Left input
+ * @param right Right input
+ * @param correlationId Variable name for the row of left input
+ * @param requiredColumns Required columns
+ * @param joinType Join type
+ */
+ RelNode createCorrelate(RelNode left, RelNode right,
+ CorrelationId correlationId, ImmutableBitSet requiredColumns,
+ SemiJoinType joinType);
+ }
+
+ /**
+ * Implementation of {@link CorrelateFactory} that returns a vanilla
+ * {@link org.apache.calcite.rel.logical.LogicalCorrelate}.
+ */
+ private static class CorrelateFactoryImpl implements CorrelateFactory {
+ public RelNode createCorrelate(RelNode left, RelNode right,
+ CorrelationId correlationId, ImmutableBitSet requiredColumns,
+ SemiJoinType joinType) {
+ return LogicalCorrelate.create(left, right, correlationId,
+ requiredColumns, joinType);
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/rel/core/SemiJoin.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/SemiJoin.java b/core/src/main/java/org/apache/calcite/rel/core/SemiJoin.java
index 4570919..6db45f1 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/SemiJoin.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/SemiJoin.java
@@ -71,8 +71,8 @@ public class SemiJoin extends EquiJoin {
condition,
leftKeys,
rightKeys,
- JoinRelType.INNER,
- ImmutableSet.<String>of());
+ ImmutableSet.<CorrelationId>of(),
+ JoinRelType.INNER);
}
/** Creates a SemiJoin. */
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java b/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
index a4da2d4..92324ba 100644
--- a/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
+++ b/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
@@ -397,7 +397,7 @@ public class RelJson {
if (correl != null) {
final Object jsonType = map.get("type");
RelDataType type = toType(cluster.getTypeFactory(), jsonType);
- return rexBuilder.makeCorrel(type, correl);
+ return rexBuilder.makeCorrel(type, new CorrelationId(correl));
}
if (map.containsKey("literal")) {
final Object literal = map.get("literal");
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/rel/logical/LogicalCalc.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalCalc.java b/core/src/main/java/org/apache/calcite/rel/logical/LogicalCalc.java
index 3fb2123..3ca1645 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalCalc.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalCalc.java
@@ -26,6 +26,7 @@ import org.apache.calcite.rel.RelDistribution;
import org.apache.calcite.rel.RelDistributionTraitDef;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Calc;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.metadata.RelMdCollation;
import org.apache.calcite.rel.metadata.RelMdDistribution;
import org.apache.calcite.rel.rules.FilterToCalcRule;
@@ -113,9 +114,9 @@ public final class LogicalCalc extends Calc {
return new LogicalCalc(getCluster(), traitSet, child, program);
}
- @Override public void collectVariablesUsed(Set<String> variableSet) {
+ @Override public void collectVariablesUsed(Set<CorrelationId> variableSet) {
final RelOptUtil.VariableUsedVisitor vuv =
- new RelOptUtil.VariableUsedVisitor();
+ new RelOptUtil.VariableUsedVisitor(null);
for (RexNode expr : program.getExprList()) {
expr.accept(vuv);
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/rel/logical/LogicalCorrelate.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalCorrelate.java b/core/src/main/java/org/apache/calcite/rel/logical/LogicalCorrelate.java
index fd403e0..c0c69d4 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalCorrelate.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalCorrelate.java
@@ -19,6 +19,7 @@ package org.apache.calcite.rel.logical;
import org.apache.calcite.plan.Convention;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.prepare.CalcitePrepareImpl;
import org.apache.calcite.rel.RelInput;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelShuttle;
@@ -26,6 +27,7 @@ import org.apache.calcite.rel.core.Correlate;
import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.sql.SemiJoinType;
import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.Litmus;
/**
* A relational operator that performs nested-loop joins.
@@ -69,6 +71,7 @@ public final class LogicalCorrelate extends Correlate {
correlationId,
requiredColumns,
joinType);
+ assert !CalcitePrepareImpl.DEBUG || isValid(Litmus.THROW);
}
@Deprecated // to be removed before 2.0
http://git-wip-us.apache.org/repos/asf/calcite/blob/505a9064/core/src/main/java/org/apache/calcite/rel/logical/LogicalFilter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalFilter.java b/core/src/main/java/org/apache/calcite/rel/logical/LogicalFilter.java
index 79b0b1d..d25874e 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalFilter.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalFilter.java
@@ -26,20 +26,27 @@ import org.apache.calcite.rel.RelDistributionTraitDef;
import org.apache.calcite.rel.RelInput;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelShuttle;
+import org.apache.calcite.rel.RelWriter;
+import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.metadata.RelMdCollation;
import org.apache.calcite.rel.metadata.RelMdDistribution;
import org.apache.calcite.rex.RexNode;
+import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
import java.util.List;
+import java.util.Set;
/**
* Sub-class of {@link org.apache.calcite.rel.core.Filter}
* not targeted at any particular engine or calling convention.
*/
public final class LogicalFilter extends Filter {
+ private final ImmutableSet<CorrelationId> variablesSet;
+
//~ Constructors -----------------------------------------------------------
/**
@@ -51,21 +58,35 @@ public final class LogicalFilter extends Filter {
* @param child Input relational expression
* @param condition Boolean expression which determines whether a row is
* allowed to pass
+ * @param variablesSet Correlation variables set by this relational expression
+ * to be used by nested expressions
*/
public LogicalFilter(
RelOptCluster cluster,
RelTraitSet traitSet,
RelNode child,
- RexNode condition) {
+ RexNode condition,
+ ImmutableSet<CorrelationId> variablesSet) {
super(cluster, traitSet, child, condition);
+ this.variablesSet = Preconditions.checkNotNull(variablesSet);
}
@Deprecated // to be removed before 2.0
public LogicalFilter(
RelOptCluster cluster,
+ RelTraitSet traitSet,
RelNode child,
RexNode condition) {
- this(cluster, cluster.traitSetOf(Convention.NONE), child, condition);
+ this(cluster, traitSet, child, condition, ImmutableSet.<CorrelationId>of());
+ }
+
+ @Deprecated // to be removed before 2.0
+ public LogicalFilter(
+ RelOptCluster cluster,
+ RelNode child,
+ RexNode condition) {
+ this(cluster, cluster.traitSetOf(Convention.NONE), child, condition,
+ ImmutableSet.<CorrelationId>of());
}
/**
@@ -73,10 +94,17 @@ public final class LogicalFilter extends Filter {
*/
public LogicalFilter(RelInput input) {
super(input);
+ this.variablesSet = ImmutableSet.of();
}
/** Creates a LogicalFilter. */
public static LogicalFilter create(final RelNode input, RexNode condition) {
+ return create(input, condition, ImmutableSet.<CorrelationId>of());
+ }
+
+ /** Creates a LogicalFilter. */
+ public static LogicalFilter create(final RelNode input, RexNode condition,
+ ImmutableSet<CorrelationId> variablesSet) {
final RelOptCluster cluster = input.getCluster();
final RelTraitSet traitSet = cluster.traitSetOf(Convention.NONE)
.replaceIfs(RelCollationTraitDef.INSTANCE,
@@ -91,20 +119,30 @@ public final class LogicalFilter extends Filter {
return RelMdDistribution.filter(input);
}
});
- return new LogicalFilter(cluster, traitSet, input, condition);
+ return new LogicalFilter(cluster, traitSet, input, condition, variablesSet);
}
//~ Methods ----------------------------------------------------------------
+ @Override public Set<CorrelationId> getVariablesSet() {
+ return variablesSet;
+ }
+
public LogicalFilter copy(RelTraitSet traitSet, RelNode input,
RexNode condition) {
assert traitSet.containsIfApplicable(Convention.NONE);
- return new LogicalFilter(getCluster(), traitSet, input, condition);
+ return new LogicalFilter(getCluster(), traitSet, input, condition,
+ variablesSet);
}
@Override public RelNode accept(RelShuttle shuttle) {
return shuttle.visit(this);
}
+
+ @Override public RelWriter explainTerms(RelWriter pw) {
+ return super.explainTerms(pw)
+ .itemIf("variablesSet", variablesSet, !variablesSet.isEmpty());
+ }
}
// End LogicalFilter.java