[CALCITE-1637] Add mutable equivalents for all relational expressions
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/316a0587 Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/316a0587 Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/316a0587 Branch: refs/heads/master Commit: 316a05872b358e8388890c04dee48adc45812f71 Parents: 5431bd9 Author: maryannxue <[email protected]> Authored: Tue Feb 21 15:19:41 2017 -0800 Committer: maryannxue <[email protected]> Committed: Tue Feb 21 15:19:41 2017 -0800 ---------------------------------------------------------------------- .../MaterializedViewSubstitutionVisitor.java | 50 +- .../calcite/plan/SubstitutionVisitor.java | 1106 ++---------------- .../org/apache/calcite/rel/mutable/Holder.java | 46 + .../calcite/rel/mutable/MutableAggregate.java | 97 ++ .../calcite/rel/mutable/MutableBiRel.java | 77 ++ .../apache/calcite/rel/mutable/MutableCalc.java | 64 + .../calcite/rel/mutable/MutableCollect.java | 65 + .../calcite/rel/mutable/MutableCorrelate.java | 91 ++ .../calcite/rel/mutable/MutableExchange.java | 62 + .../calcite/rel/mutable/MutableFilter.java | 64 + .../calcite/rel/mutable/MutableIntersect.java | 55 + .../apache/calcite/rel/mutable/MutableJoin.java | 94 ++ .../calcite/rel/mutable/MutableLeafRel.java | 48 + .../calcite/rel/mutable/MutableMinus.java | 55 + .../calcite/rel/mutable/MutableMultiRel.java | 65 + .../calcite/rel/mutable/MutableProject.java | 100 ++ .../apache/calcite/rel/mutable/MutableRel.java | 148 +++ .../calcite/rel/mutable/MutableRelType.java | 44 + .../calcite/rel/mutable/MutableRelVisitor.java | 34 + .../apache/calcite/rel/mutable/MutableRels.java | 400 +++++++ .../calcite/rel/mutable/MutableSample.java | 69 ++ .../apache/calcite/rel/mutable/MutableScan.java | 56 + .../calcite/rel/mutable/MutableSemiJoin.java | 90 ++ .../calcite/rel/mutable/MutableSetOp.java | 52 + .../calcite/rel/mutable/MutableSingleRel.java | 61 + .../apache/calcite/rel/mutable/MutableSort.java | 81 ++ .../rel/mutable/MutableTableFunctionScan.java | 96 ++ .../calcite/rel/mutable/MutableTableModify.java | 113 ++ .../calcite/rel/mutable/MutableUncollect.java | 67 ++ .../calcite/rel/mutable/MutableUnion.java | 55 + .../calcite/rel/mutable/MutableValues.java | 56 + .../calcite/rel/mutable/MutableWindow.java | 73 ++ .../calcite/rel/mutable/package-info.java | 39 + .../org/apache/calcite/test/CalciteSuite.java | 1 + .../calcite/test/MaterializationTest.java | 29 + .../org/apache/calcite/test/MutableRelTest.java | 235 ++++ 36 files changed, 2904 insertions(+), 1034 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/316a0587/core/src/main/java/org/apache/calcite/plan/MaterializedViewSubstitutionVisitor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/plan/MaterializedViewSubstitutionVisitor.java b/core/src/main/java/org/apache/calcite/plan/MaterializedViewSubstitutionVisitor.java index da7b18d..c1e0e37 100644 --- a/core/src/main/java/org/apache/calcite/plan/MaterializedViewSubstitutionVisitor.java +++ b/core/src/main/java/org/apache/calcite/plan/MaterializedViewSubstitutionVisitor.java @@ -17,6 +17,10 @@ package org.apache.calcite.plan; import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.mutable.MutableFilter; +import org.apache.calcite.rel.mutable.MutableProject; +import org.apache.calcite.rel.mutable.MutableRel; +import org.apache.calcite.rel.mutable.MutableRels; import org.apache.calcite.rel.type.RelDataTypeField; import org.apache.calcite.rex.RexInputRef; import org.apache.calcite.rex.RexNode; @@ -48,8 +52,8 @@ public class MaterializedViewSubstitutionVisitor extends SubstitutionVisitor { /** * Implementation of {@link SubstitutionVisitor.UnifyRule} that matches a - * {@link SubstitutionVisitor.MutableProject} to a - * {@link SubstitutionVisitor.MutableProject} where the condition of the target + * {@link MutableProject} to a + * {@link MutableProject} where the condition of the target * relation is weaker. * * <p>Example: target has a weaker condition and contains all columns selected @@ -76,19 +80,18 @@ public class MaterializedViewSubstitutionVisitor extends SubstitutionVisitor { final MutableProject query = (MutableProject) call.query; final List<RelDataTypeField> oldFieldList = - query.getInput().getRowType().getFieldList(); + query.getInput().rowType.getFieldList(); final List<RelDataTypeField> newFieldList = - call.target.getRowType().getFieldList(); + call.target.rowType.getFieldList(); List<RexNode> newProjects; try { - newProjects = transformRex(query.getProjects(), oldFieldList, newFieldList); + newProjects = transformRex(query.projects, oldFieldList, newFieldList); } catch (MatchFailed e) { return null; } final MutableProject newProject = - MutableProject.of( - query.getRowType(), call.target, newProjects); + MutableProject.of(query.rowType, call.target, newProjects); final MutableRel newProject2 = MutableRels.strip(newProject); return call.result(newProject2); @@ -109,9 +112,9 @@ public class MaterializedViewSubstitutionVisitor extends SubstitutionVisitor { (MutableFilter) queryProject.getInput(); RexNode newCondition; try { - newCondition = transformRex(innerFilter.getCondition(), - innerFilter.getInput().getRowType().getFieldList(), - target.getRowType().getFieldList()); + newCondition = transformRex(innerFilter.condition, + innerFilter.getInput().rowType.getFieldList(), + target.rowType.getFieldList()); } catch (MatchFailed e) { return null; } @@ -129,8 +132,8 @@ public class MaterializedViewSubstitutionVisitor extends SubstitutionVisitor { /** * Implementation of {@link SubstitutionVisitor.UnifyRule} that matches a - * {@link SubstitutionVisitor.MutableFilter} to a - * {@link SubstitutionVisitor.MutableFilter} where the condition of the target + * {@link MutableFilter} to a + * {@link MutableFilter} where the condition of the target * relation is weaker. * * <p>Example: target has a weaker condition</p> @@ -153,7 +156,7 @@ public class MaterializedViewSubstitutionVisitor extends SubstitutionVisitor { public UnifyResult apply(UnifyRuleCall call) { final MutableFilter query = (MutableFilter) call.query; final MutableFilter target = (MutableFilter) call.target; - final MutableFilter newFilter = MutableFilter.of(target, query.getCondition()); + final MutableFilter newFilter = MutableFilter.of(target, query.condition); return call.result(newFilter); } @@ -173,9 +176,9 @@ public class MaterializedViewSubstitutionVisitor extends SubstitutionVisitor { /** * Implementation of {@link SubstitutionVisitor.UnifyRule} that matches a - * {@link SubstitutionVisitor.MutableFilter} to a - * {@link SubstitutionVisitor.MutableProject} on top of a - * {@link SubstitutionVisitor.MutableFilter} where the condition of the target + * {@link MutableFilter} to a + * {@link MutableProject} on top of a + * {@link MutableFilter} where the condition of the target * relation is weaker. * * <p>Example: target has a weaker condition and is a permutation projection of @@ -203,22 +206,21 @@ public class MaterializedViewSubstitutionVisitor extends SubstitutionVisitor { final MutableRel query = call.query; final List<RelDataTypeField> oldFieldList = - query.getRowType().getFieldList(); + query.rowType.getFieldList(); final List<RelDataTypeField> newFieldList = - call.target.getRowType().getFieldList(); + call.target.rowType.getFieldList(); List<RexNode> newProjects; try { newProjects = transformRex( (List<RexNode>) call.getCluster().getRexBuilder().identityProjects( - query.getRowType()), + query.rowType), oldFieldList, newFieldList); } catch (MatchFailed e) { return null; } final MutableProject newProject = - MutableProject.of( - query.getRowType(), call.target, newProjects); + MutableProject.of(query.rowType, call.target, newProjects); final MutableRel newProject2 = MutableRels.strip(newProject); return call.result(newProject2); @@ -234,9 +236,9 @@ public class MaterializedViewSubstitutionVisitor extends SubstitutionVisitor { final MutableFilter filter = (MutableFilter) query; RexNode newCondition; try { - newCondition = transformRex(filter.getCondition(), - filter.getInput().getRowType().getFieldList(), - target.getRowType().getFieldList()); + newCondition = transformRex(filter.condition, + filter.getInput().rowType.getFieldList(), + target.rowType.getFieldList()); } catch (MatchFailed e) { return null; } http://git-wip-us.apache.org/repos/asf/calcite/blob/316a0587/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 edba57f..02c63b0 100644 --- a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java +++ b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java @@ -16,28 +16,21 @@ */ package org.apache.calcite.plan; -import org.apache.calcite.avatica.util.Spaces; import org.apache.calcite.linq4j.Ord; import org.apache.calcite.prepare.CalcitePrepareImpl; -import org.apache.calcite.rel.RelCollation; 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; -import org.apache.calcite.rel.core.Project; -import org.apache.calcite.rel.core.Sort; -import org.apache.calcite.rel.core.TableScan; -import org.apache.calcite.rel.core.Values; -import org.apache.calcite.rel.logical.LogicalAggregate; import org.apache.calcite.rel.logical.LogicalFilter; -import org.apache.calcite.rel.logical.LogicalJoin; import org.apache.calcite.rel.logical.LogicalProject; -import org.apache.calcite.rel.logical.LogicalSort; -import org.apache.calcite.rel.logical.LogicalUnion; +import org.apache.calcite.rel.mutable.Holder; +import org.apache.calcite.rel.mutable.MutableAggregate; +import org.apache.calcite.rel.mutable.MutableFilter; +import org.apache.calcite.rel.mutable.MutableProject; +import org.apache.calcite.rel.mutable.MutableRel; +import org.apache.calcite.rel.mutable.MutableRelVisitor; +import org.apache.calcite.rel.mutable.MutableRels; +import org.apache.calcite.rel.mutable.MutableScan; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeField; import org.apache.calcite.rex.RexBuilder; @@ -51,7 +44,6 @@ import org.apache.calcite.rex.RexUtil; import org.apache.calcite.runtime.PredicateImpl; import org.apache.calcite.sql.SqlAggFunction; import org.apache.calcite.sql.fun.SqlStdOperatorTable; -import org.apache.calcite.sql.validate.SqlValidatorUtil; import org.apache.calcite.util.Bug; import org.apache.calcite.util.ControlFlowException; import org.apache.calcite.util.ImmutableBitSet; @@ -63,12 +55,10 @@ import org.apache.calcite.util.mapping.Mappings; import org.apache.calcite.util.trace.CalciteTrace; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Equivalence; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -77,14 +67,11 @@ import com.google.common.collect.Sets; import org.slf4j.Logger; -import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; import static org.apache.calcite.rex.RexUtil.andNot; @@ -127,25 +114,6 @@ public class SubstitutionVisitor { private static final Logger LOGGER = CalciteTrace.getPlannerTracer(); - /** Equivalence that compares objects by their {@link Object#toString()} - * method. */ - private static final Equivalence<Object> STRING_EQUIVALENCE = - new Equivalence<Object>() { - @Override protected boolean doEquivalent(Object o, Object o2) { - return o.toString().equals(o2.toString()); - } - - @Override protected int doHash(Object o) { - return o.toString().hashCode(); - } - }; - - /** Equivalence that compares {@link Lists}s by the - * {@link Object#toString()} of their elements. */ - @SuppressWarnings("unchecked") - private static final Equivalence<List<?>> PAIRWISE_STRING_EQUIVALENCE = - (Equivalence) STRING_EQUIVALENCE.pairwise(); - protected static final ImmutableList<UnifyRule> DEFAULT_RULES = ImmutableList.<UnifyRule>of( TrivialRule.INSTANCE, @@ -194,14 +162,14 @@ public class SubstitutionVisitor { ImmutableList<UnifyRule> rules) { this.cluster = target_.getCluster(); this.rules = rules; - this.query = Holder.of(toMutable(query_)); - this.target = toMutable(target_); + this.query = Holder.of(MutableRels.toMutable(query_)); + this.target = MutableRels.toMutable(target_); final Set<MutableRel> parents = Sets.newIdentityHashSet(); final List<MutableRel> allNodes = new ArrayList<>(); final MutableRelVisitor visitor = new MutableRelVisitor() { public void visit(MutableRel node) { - parents.add(node.parent); + parents.add(node.getParent()); allNodes.add(node); super.visit(node); } @@ -221,46 +189,6 @@ public class SubstitutionVisitor { queryLeaves = ImmutableList.copyOf(allNodes); } - private static MutableRel toMutable(RelNode rel) { - if (rel instanceof TableScan) { - return MutableScan.of((TableScan) rel); - } - if (rel instanceof Values) { - return MutableValues.of((Values) rel); - } - if (rel instanceof Project) { - final Project project = (Project) rel; - final MutableRel input = toMutable(project.getInput()); - return MutableProject.of(input, project.getProjects(), - project.getRowType().getFieldNames()); - } - if (rel instanceof Filter) { - final Filter filter = (Filter) rel; - final MutableRel input = toMutable(filter.getInput()); - return MutableFilter.of(input, filter.getCondition()); - } - if (rel instanceof Aggregate) { - final Aggregate aggregate = (Aggregate) rel; - final MutableRel input = toMutable(aggregate.getInput()); - return MutableAggregate.of(input, aggregate.indicator, - aggregate.getGroupSet(), aggregate.getGroupSets(), - aggregate.getAggCallList()); - } - if (rel instanceof Join) { - final Join join = (Join) rel; - final MutableRel left = toMutable(join.getLeft()); - final MutableRel right = toMutable(join.getRight()); - return MutableJoin.of(join.getCluster(), left, right, - join.getCondition(), join.getJoinType(), join.getVariablesSet()); - } - if (rel instanceof Sort) { - final Sort sort = (Sort) rel; - final MutableRel input = toMutable(sort.getInput()); - return MutableSort.of(input, sort.getCollation(), sort.offset, sort.fetch); - } - throw new RuntimeException("cannot translate " + rel + " to MutableRel"); - } - void register(MutableRel result, MutableRel query) { } @@ -406,8 +334,8 @@ public class SubstitutionVisitor { public RelNode go0(RelNode replacement_) { assert false; // not called - MutableRel replacement = toMutable(replacement_); - assert MutableRels.equalType( + MutableRel replacement = MutableRels.toMutable(replacement_); + assert equalType( "target", target, "replacement", replacement, Litmus.THROW); replacementMap.put(target, replacement); final UnifyResult unifyResult = matchRecurse(target); @@ -430,7 +358,7 @@ public class SubstitutionVisitor { + "\nnode:\n" + node.deep()); } - return fromMutable(node); + return MutableRels.fromMutable(node); } /** @@ -442,12 +370,12 @@ public class SubstitutionVisitor { * A join R. */ public List<RelNode> go(RelNode replacement_) { - List<List<Replacement>> matches = go(toMutable(replacement_)); + List<List<Replacement>> matches = go(MutableRels.toMutable(replacement_)); if (matches.isEmpty()) { return ImmutableList.of(); } List<RelNode> sub = Lists.newArrayList(); - sub.add(fromMutable(query.input)); + sub.add(MutableRels.fromMutable(query.getInput())); reverseSubstitute(query, matches, sub, 0, matches.size()); return sub; } @@ -460,7 +388,7 @@ public class SubstitutionVisitor { * substitution in different places. */ private List<List<Replacement>> go(MutableRel replacement) { - assert MutableRels.equalType( + assert equalType( "target", target, "replacement", replacement, Litmus.THROW); final List<MutableRel> queryDescendants = MutableRels.descendants(query); final List<MutableRel> targetDescendants = MutableRels.descendants(target); @@ -530,8 +458,8 @@ public class SubstitutionVisitor { // Meanwhile we stop matching the descendants and jump // to the next subtree in pre-order traversal. if (!target.equals(replacement)) { - Replacement r = MutableRels.replace( - query.input, target, copyMutable(replacement)); + Replacement r = replace( + query.getInput(), target, replacement.clone()); assert r != null : rule + "should have returned a result containing the target."; attempted.add(r); @@ -575,7 +503,7 @@ public class SubstitutionVisitor { /** * Represents a replacement action: before → after. */ - private static class Replacement { + static class Replacement { final MutableRel before; final MutableRel after; @@ -585,6 +513,37 @@ public class SubstitutionVisitor { } } + /** Within a relational expression {@code query}, replaces occurrences of + * {@code find} with {@code replace}. + * + * <p>Assumes relational expressions (and their descendants) are not null. + * Does not handle cycles. */ + public static Replacement replace(MutableRel query, MutableRel find, + MutableRel replace) { + if (find.equals(replace)) { + // Short-cut common case. + return null; + } + assert equalType("find", find, "replace", replace, Litmus.THROW); + return replaceRecurse(query, find, replace); + } + + /** Helper for {@link #replace}. */ + private static Replacement replaceRecurse(MutableRel query, + MutableRel find, MutableRel replace) { + if (find.equals(query)) { + query.replaceInParent(replace); + return new Replacement(query, replace); + } + for (MutableRel input : query.getInputs()) { + Replacement r = replaceRecurse(input, find, replace); + if (r != null) { + return r; + } + } + return null; + } + private static void undoReplacement(List<Replacement> replacement) { for (int i = replacement.size() - 1; i >= 0; i--) { Replacement r = replacement.get(i); @@ -608,99 +567,12 @@ public class SubstitutionVisitor { reverseSubstitute(query, rem, sub, replaceCount, maxCount); undoReplacement(matches.get(0)); if (++replaceCount < maxCount) { - sub.add(fromMutable(query.input)); + sub.add(MutableRels.fromMutable(query.getInput())); } reverseSubstitute(query, rem, sub, replaceCount, maxCount); redoReplacement(matches.get(0)); } - private static List<RelNode> fromMutables(List<MutableRel> nodes) { - return Lists.transform(nodes, - new Function<MutableRel, RelNode>() { - public RelNode apply(MutableRel mutableRel) { - return fromMutable(mutableRel); - } - }); - } - - private static RelNode fromMutable(MutableRel node) { - switch (node.type) { - case SCAN: - case VALUES: - return ((MutableLeafRel) node).rel; - case PROJECT: - final MutableProject project = (MutableProject) node; - return LogicalProject.create(fromMutable(project.input), - project.projects, project.rowType); - case FILTER: - final MutableFilter filter = (MutableFilter) node; - return LogicalFilter.create(fromMutable(filter.input), - filter.condition); - case AGGREGATE: - final MutableAggregate aggregate = (MutableAggregate) node; - return LogicalAggregate.create(fromMutable(aggregate.input), - aggregate.indicator, aggregate.groupSet, aggregate.groupSets, - aggregate.aggCalls); - case SORT: - final MutableSort sort = (MutableSort) node; - return LogicalSort.create(fromMutable(sort.input), sort.collation, - sort.offset, sort.fetch); - case UNION: - final MutableUnion union = (MutableUnion) node; - return LogicalUnion.create(fromMutables(union.inputs), union.all); - case JOIN: - final MutableJoin join = (MutableJoin) node; - return LogicalJoin.create(fromMutable(join.getLeft()), fromMutable(join.getRight()), - join.getCondition(), join.getVariablesSet(), join.getJoinType()); - default: - throw new AssertionError(node.deep()); - } - } - - private static List<MutableRel> copyMutables(List<MutableRel> nodes) { - return Lists.transform(nodes, - new Function<MutableRel, MutableRel>() { - public MutableRel apply(MutableRel mutableRel) { - return copyMutable(mutableRel); - } - }); - } - - private static MutableRel copyMutable(MutableRel node) { - switch (node.type) { - case SCAN: - return MutableScan.of((TableScan) ((MutableScan) node).rel); - case VALUES: - return MutableValues.of((Values) ((MutableValues) node).rel); - case PROJECT: - final MutableProject project = (MutableProject) node; - return MutableProject.of(project.rowType, - copyMutable(project.input), project.projects); - case FILTER: - final MutableFilter filter = (MutableFilter) node; - return MutableFilter.of(copyMutable(filter.input), filter.condition); - case AGGREGATE: - final MutableAggregate aggregate = (MutableAggregate) node; - return MutableAggregate.of(copyMutable(aggregate.input), - aggregate.indicator, aggregate.groupSet, aggregate.groupSets, - aggregate.aggCalls); - case SORT: - final MutableSort sort = (MutableSort) node; - return MutableSort.of(copyMutable(sort.input), sort.collation, - sort.offset, sort.fetch); - case UNION: - final MutableUnion union = (MutableUnion) node; - return MutableUnion.of(copyMutables(union.inputs), union.all); - case JOIN: - final MutableJoin join = (MutableJoin) node; - return MutableJoin.of(join.cluster, copyMutable(join.getLeft()), - copyMutable(join.getRight()), join.getCondition(), join.getJoinType(), - join.getVariablesSet()); - default: - throw new AssertionError(node.deep()); - } - } - private UnifyResult matchRecurse(MutableRel target) { assert false; // not called final List<MutableRel> targetInputs = target.getInputs(); @@ -901,13 +773,13 @@ public class SubstitutionVisitor { public UnifyResult result(MutableRel result) { assert MutableRels.contains(result, target); - assert MutableRels.equalType("result", result, "query", query, + assert equalType("result", result, "query", query, Litmus.THROW); MutableRel replace = replacementMap.get(target); if (replace != null) { assert false; // replacementMap is always empty // result = - MutableRels.replace(result, target, replace); + replace(result, target, replace); } register(result, query); return new UnifyResult(this, result); @@ -938,7 +810,7 @@ public class SubstitutionVisitor { UnifyResult(UnifyRuleCall call, MutableRel result) { this.call = call; - assert MutableRels.equalType("query", call.query, "result", result, + assert equalType("query", call.query, "result", result, Litmus.THROW); this.result = result; } @@ -1035,13 +907,12 @@ public class SubstitutionVisitor { final List<RexNode> newProjects; try { newProjects = (List<RexNode>) - shuttle.apply(rexBuilder.identityProjects(query.getRowType())); + shuttle.apply(rexBuilder.identityProjects(query.rowType)); } catch (MatchFailed e) { return null; } final MutableProject newProject = - MutableProject.of( - query.getRowType(), target, newProjects); + MutableProject.of(query.rowType, target, newProjects); final MutableRel newProject2 = MutableRels.strip(newProject); return call.result(newProject2); } @@ -1064,13 +935,12 @@ public class SubstitutionVisitor { final RexShuttle shuttle = getRexShuttle(target); final List<RexNode> newProjects; try { - newProjects = shuttle.apply(query.getProjects()); + newProjects = shuttle.apply(query.projects); } catch (MatchFailed e) { return null; } final MutableProject newProject = - MutableProject.of( - query.getRowType(), target, newProjects); + MutableProject.of(query.rowType, target, newProjects); final MutableRel newProject2 = MutableRels.strip(newProject); return call.result(newProject2); } @@ -1097,16 +967,16 @@ public class SubstitutionVisitor { final RexNode newCondition; final MutableFilter query = (MutableFilter) call.query; try { - newCondition = query.getCondition().accept(shuttle); + newCondition = query.condition.accept(shuttle); } catch (MatchFailed e) { return null; } final MutableFilter newFilter = MutableFilter.of(target, newCondition); - if (query.parent instanceof MutableProject) { + if (query.getParent() instanceof MutableProject) { final MutableRel inverse = - invert(((MutableProject) query.parent).getNamedProjects(), + invert(((MutableProject) query.getParent()).getNamedProjects(), newFilter, shuttle); - return call.create(query.parent).result(inverse); + return call.create(query.getParent()).result(inverse); } else { final MutableRel inverse = invert(query, newFilter, target); return call.result(inverse); @@ -1141,15 +1011,15 @@ public class SubstitutionVisitor { MutableProject project) { LOGGER.trace("SubstitutionVisitor: invert:\nmodel: {}\ninput: {}\nproject: {}\n", model, input, project); - if (project.getProjects().size() < model.getRowType().getFieldCount()) { + if (project.projects.size() < model.rowType.getFieldCount()) { throw MatchFailed.INSTANCE; } final List<RexNode> exprList = new ArrayList<>(); final RexBuilder rexBuilder = model.cluster.getRexBuilder(); - for (RelDataTypeField field : model.getRowType().getFieldList()) { + for (RelDataTypeField field : model.rowType.getFieldList()) { exprList.add(rexBuilder.makeZeroLiteral(field.getType())); } - for (Ord<RexNode> expr : Ord.zip(project.getProjects())) { + for (Ord<RexNode> expr : Ord.zip(project.projects)) { if (expr.e instanceof RexInputRef) { final int target = ((RexInputRef) expr.e).getIndex(); exprList.set(target, @@ -1194,8 +1064,8 @@ public class SubstitutionVisitor { MutableFilter createFilter(MutableFilter query, MutableFilter target) { final RexNode newCondition = - splitFilter(query.cluster.getRexBuilder(), query.getCondition(), - target.getCondition()); + splitFilter(query.cluster.getRexBuilder(), query.condition, + target.condition); if (newCondition == null) { // Could not map query onto target. return null; @@ -1219,8 +1089,8 @@ public class SubstitutionVisitor { } public UnifyResult apply(UnifyRuleCall call) { - if (call.query.parent instanceof MutableFilter) { - final UnifyRuleCall in2 = call.create(call.query.parent); + if (call.query.getParent() instanceof MutableFilter) { + final UnifyRuleCall in2 = call.create(call.query.getParent()); final MutableFilter query = (MutableFilter) in2.query; final MutableFilter target = (MutableFilter) in2.target; final MutableFilter newFilter = @@ -1258,7 +1128,7 @@ public class SubstitutionVisitor { // target: SELECT x, y, SUM(a) AS s, COUNT(b) AS cb FROM t GROUP BY x, y // transforms to // result: SELECT x, SUM(cb) FROM (target) GROUP BY x - if (!target.getGroupSet().contains(query.getGroupSet())) { + if (!target.groupSet.contains(query.groupSet)) { return null; } MutableRel result = unifyAggregates(query, target); @@ -1271,11 +1141,11 @@ public class SubstitutionVisitor { public static MutableAggregate permute(MutableAggregate aggregate, MutableRel input, Mapping mapping) { - ImmutableBitSet groupSet = Mappings.apply(mapping, aggregate.getGroupSet()); + ImmutableBitSet groupSet = Mappings.apply(mapping, aggregate.groupSet); ImmutableList<ImmutableBitSet> groupSets = - Mappings.apply2(mapping, aggregate.getGroupSets()); + Mappings.apply2(mapping, aggregate.groupSets); List<AggregateCall> aggregateCalls = - apply(mapping, aggregate.getAggCallList()); + apply(mapping, aggregate.aggCalls); return MutableAggregate.of(input, aggregate.indicator, groupSet, groupSets, aggregateCalls); } @@ -1298,15 +1168,15 @@ public class SubstitutionVisitor { throw new AssertionError(Bug.CALCITE_461_FIXED); } MutableRel result; - if (query.getGroupSet().equals(target.getGroupSet())) { + if (query.groupSet.equals(target.groupSet)) { // Same level of aggregation. Generate a project. final List<Integer> projects = Lists.newArrayList(); - final int groupCount = query.getGroupSet().cardinality(); + final int groupCount = query.groupSet.cardinality(); for (int i = 0; i < groupCount; i++) { projects.add(i); } - for (AggregateCall aggregateCall : query.getAggCallList()) { - int i = target.getAggCallList().indexOf(aggregateCall); + for (AggregateCall aggregateCall : query.aggCalls) { + int i = target.aggCalls.indexOf(aggregateCall); if (i < 0) { return null; } @@ -1316,8 +1186,8 @@ public class SubstitutionVisitor { } else { // Target is coarser level of aggregation. Generate an aggregate. final ImmutableBitSet.Builder groupSet = ImmutableBitSet.builder(); - final List<Integer> targetGroupList = target.getGroupSet().asList(); - for (int c : query.getGroupSet()) { + final List<Integer> targetGroupList = target.groupSet.asList(); + for (int c : query.groupSet) { int c2 = targetGroupList.indexOf(c); if (c2 < 0) { return null; @@ -1325,11 +1195,11 @@ public class SubstitutionVisitor { groupSet.set(c2); } final List<AggregateCall> aggregateCalls = Lists.newArrayList(); - for (AggregateCall aggregateCall : query.getAggCallList()) { + for (AggregateCall aggregateCall : query.aggCalls) { if (aggregateCall.isDistinct()) { return null; } - int i = target.getAggCallList().indexOf(aggregateCall); + int i = target.aggCalls.indexOf(aggregateCall); if (i < 0) { return null; } @@ -1342,7 +1212,7 @@ public class SubstitutionVisitor { result = MutableAggregate.of(target, false, groupSet.build(), null, aggregateCalls); } - return MutableRels.createCastRel(result, query.getRowType(), true); + return MutableRels.createCastRel(result, query.rowType, true); } /** Implementation of {@link UnifyRule} that matches a @@ -1402,7 +1272,7 @@ public class SubstitutionVisitor { * expressions to references to them. */ protected static RexShuttle getRexShuttle(MutableProject target) { final Map<String, Integer> map = new HashMap<>(); - for (RexNode e : target.getProjects()) { + for (RexNode e : target.projects) { map.put(e.toString(), map.size()); } return new RexShuttle() { @@ -1424,796 +1294,6 @@ public class SubstitutionVisitor { }; } - /** Type of {@code MutableRel}. */ - private enum MutableRelType { - SCAN, - PROJECT, - FILTER, - AGGREGATE, - SORT, - UNION, - JOIN, - HOLDER, - VALUES - } - - /** Visitor over {@link MutableRel}. */ - private static class MutableRelVisitor { - private MutableRel root; - - public void visit(MutableRel node) { - node.childrenAccept(this); - } - - public MutableRel go(MutableRel p) { - this.root = p; - visit(p); - return root; - } - } - - /** Mutable equivalent of {@link RelNode}. - * - * <p>Each node has mutable state, and keeps track of its parent and position - * within parent. - * It doesn't make sense to canonize {@code MutableRels}, - * otherwise one node could end up with multiple parents. - * It follows that {@code #hashCode} and {@code #equals} are less efficient - * than their {@code RelNode} counterparts. - * But, you don't need to copy a {@code MutableRel} in order to change it. - * For this reason, you should use {@code MutableRel} for short-lived - * operations, and transcribe back to {@code RelNode} when you are done.</p> - */ - protected abstract static class MutableRel { - MutableRel parent; - int ordinalInParent; - public final RelOptCluster cluster; - final RelDataType rowType; - final MutableRelType type; - - private MutableRel(RelOptCluster cluster, RelDataType rowType, - MutableRelType type) { - this.cluster = cluster; - this.rowType = rowType; - this.type = type; - } - - public RelDataType getRowType() { - return rowType; - } - - public abstract void setInput(int ordinalInParent, MutableRel input); - - public abstract List<MutableRel> getInputs(); - - public abstract void childrenAccept(MutableRelVisitor visitor); - - /** Replaces this {@code MutableRel} in its parent with another node at the - * same position. - * - * <p>Before the method, {@code child} must be an orphan (have null parent) - * and after this method, this {@code MutableRel} is an orphan. - * - * @return The parent - */ - public MutableRel replaceInParent(MutableRel child) { - final MutableRel parent = this.parent; - if (this != child) { -/* - if (child.parent != null) { - child.parent.setInput(child.ordinalInParent, null); - child.parent = null; - } -*/ - if (parent != null) { - parent.setInput(ordinalInParent, child); - this.parent = null; - this.ordinalInParent = 0; - } - } - return parent; - } - - public abstract StringBuilder digest(StringBuilder buf); - - public final String deep() { - return new MutableRelDumper().apply(this); - } - - @Override public final String toString() { - return deep(); - } - - public MutableRel getParent() { return parent; } - } - - /** Implementation of {@link MutableRel} whose only purpose is to have a - * child. Used as the root of a tree. */ - private static class Holder extends MutableSingleRel { - private Holder(MutableRelType type, RelDataType rowType, MutableRel input) { - super(type, rowType, input); - } - - static Holder of(MutableRel input) { - return new Holder(MutableRelType.HOLDER, input.rowType, input); - } - - @Override public StringBuilder digest(StringBuilder buf) { - return buf.append("Holder"); - } - } - - /** Abstract base class for implementations of {@link MutableRel} that have - * no inputs. */ - protected abstract static class MutableLeafRel extends MutableRel { - protected final RelNode rel; - - MutableLeafRel(MutableRelType type, RelNode rel) { - super(rel.getCluster(), rel.getRowType(), type); - this.rel = rel; - } - - public void setInput(int ordinalInParent, MutableRel input) { - throw new IllegalArgumentException(); - } - - public List<MutableRel> getInputs() { - return ImmutableList.of(); - } - - public void childrenAccept(MutableRelVisitor visitor) { - // no children - nothing to do - } - } - - /** Mutable equivalent of {@link SingleRel}. */ - protected abstract static class MutableSingleRel extends MutableRel { - protected MutableRel input; - - MutableSingleRel(MutableRelType type, RelDataType rowType, - MutableRel input) { - super(input.cluster, rowType, type); - this.input = input; - input.parent = this; - input.ordinalInParent = 0; - } - - public void setInput(int ordinalInParent, MutableRel input) { - if (ordinalInParent >= 1) { - throw new IllegalArgumentException(); - } - this.input = input; - if (input != null) { - input.parent = this; - input.ordinalInParent = 0; - } - } - - public List<MutableRel> getInputs() { - return ImmutableList.of(input); - } - - public void childrenAccept(MutableRelVisitor visitor) { - visitor.visit(input); - } - - public MutableRel getInput() { - return input; - } - } - - /** Mutable equivalent of - * {@link org.apache.calcite.rel.logical.LogicalTableScan}. */ - protected static class MutableScan extends MutableLeafRel { - private MutableScan(TableScan rel) { - super(MutableRelType.SCAN, rel); - } - - static MutableScan of(TableScan rel) { - return new MutableScan(rel); - } - - @Override public boolean equals(Object obj) { - return obj == this - || obj instanceof MutableScan - && rel.equals(((MutableScan) obj).rel); - } - - @Override public int hashCode() { - return rel.hashCode(); - } - - @Override public StringBuilder digest(StringBuilder buf) { - return buf.append("Scan(table: ") - .append(rel.getTable().getQualifiedName()).append(")"); - } - } - - /** Mutable equivalent of {@link org.apache.calcite.rel.core.Values}. */ - protected static class MutableValues extends MutableLeafRel { - private MutableValues(Values rel) { - super(MutableRelType.VALUES, rel); - } - - static MutableValues of(Values rel) { - return new MutableValues(rel); - } - - @Override public boolean equals(Object obj) { - return obj == this - || obj instanceof MutableValues - && rel == ((MutableValues) obj).rel; - } - - @Override public int hashCode() { - return rel.hashCode(); - } - - @Override public StringBuilder digest(StringBuilder buf) { - return buf.append("Values(tuples: ") - .append(((Values) rel).getTuples()).append(")"); - } - } - - /** Mutable equivalent of - * {@link org.apache.calcite.rel.logical.LogicalProject}. */ - protected static class MutableProject extends MutableSingleRel { - private final List<RexNode> projects; - - private MutableProject(RelDataType rowType, MutableRel input, - List<RexNode> projects) { - super(MutableRelType.PROJECT, rowType, input); - this.projects = projects; - assert RexUtil.compatibleTypes(projects, rowType, Litmus.THROW); - } - - public static MutableProject of(RelDataType rowType, MutableRel input, - List<RexNode> projects) { - return new MutableProject(rowType, input, projects); - } - - /** Equivalent to - * {@link RelOptUtil#createProject(org.apache.calcite.rel.RelNode, java.util.List, java.util.List)} - * for {@link MutableRel}. */ - public static MutableRel of(MutableRel child, List<RexNode> exprList, - List<String> fieldNameList) { - final RelDataType rowType = - RexUtil.createStructType(child.cluster.getTypeFactory(), exprList, - fieldNameList, SqlValidatorUtil.F_SUGGESTER); - return of(rowType, child, exprList); - } - - @Override public boolean equals(Object obj) { - return obj == this - || obj instanceof MutableProject - && PAIRWISE_STRING_EQUIVALENCE.equivalent( - projects, ((MutableProject) obj).projects) - && input.equals(((MutableProject) obj).input); - } - - @Override public int hashCode() { - return Objects.hash(input, - PAIRWISE_STRING_EQUIVALENCE.hash(projects)); - } - - @Override public StringBuilder digest(StringBuilder buf) { - return buf.append("Project(projects: ").append(projects).append(")"); - } - - public List<RexNode> getProjects() { - return projects; - } - - /** Returns a list of (expression, name) pairs. */ - public final List<Pair<RexNode, String>> getNamedProjects() { - return Pair.zip(getProjects(), getRowType().getFieldNames()); - } - - public Mappings.TargetMapping getMapping() { - return Project.getMapping( - input.getRowType().getFieldCount(), projects); - } - } - - /** Mutable equivalent of - * {@link org.apache.calcite.rel.logical.LogicalFilter}. */ - protected static class MutableFilter extends MutableSingleRel { - private final RexNode condition; - - private MutableFilter(MutableRel input, RexNode condition) { - super(MutableRelType.FILTER, input.rowType, input); - this.condition = condition; - } - - public static MutableFilter of(MutableRel input, RexNode condition) { - return new MutableFilter(input, condition); - } - - @Override public boolean equals(Object obj) { - return obj == this - || obj instanceof MutableFilter - && condition.toString().equals( - ((MutableFilter) obj).condition.toString()) - && input.equals(((MutableFilter) obj).input); - } - - @Override public int hashCode() { - return Objects.hash(input, condition.toString()); - } - - @Override public StringBuilder digest(StringBuilder buf) { - return buf.append("Filter(condition: ").append(condition).append(")"); - } - - public RexNode getCondition() { - return condition; - } - } - - /** Mutable equivalent of - * {@link org.apache.calcite.rel.logical.LogicalAggregate}. */ - protected static class MutableAggregate extends MutableSingleRel { - public final boolean indicator; - private final ImmutableBitSet groupSet; - private final ImmutableList<ImmutableBitSet> groupSets; - private final List<AggregateCall> aggCalls; - - private MutableAggregate(MutableRel input, RelDataType rowType, - boolean indicator, ImmutableBitSet groupSet, - List<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) { - super(MutableRelType.AGGREGATE, rowType, input); - this.indicator = indicator; - this.groupSet = groupSet; - this.groupSets = groupSets == null - ? ImmutableList.of(groupSet) - : ImmutableList.copyOf(groupSets); - this.aggCalls = aggCalls; - } - - static MutableAggregate of(MutableRel input, boolean indicator, - ImmutableBitSet groupSet, ImmutableList<ImmutableBitSet> groupSets, - List<AggregateCall> aggCalls) { - RelDataType rowType = - Aggregate.deriveRowType(input.cluster.getTypeFactory(), - input.getRowType(), indicator, groupSet, groupSets, aggCalls); - return new MutableAggregate(input, rowType, indicator, groupSet, - groupSets, aggCalls); - } - - @Override public boolean equals(Object obj) { - return obj == this - || obj instanceof MutableAggregate - && groupSet.equals(((MutableAggregate) obj).groupSet) - && aggCalls.equals(((MutableAggregate) obj).aggCalls) - && input.equals(((MutableAggregate) obj).input); - } - - @Override public int hashCode() { - return Objects.hash(input, groupSet, aggCalls); - } - - @Override public StringBuilder digest(StringBuilder buf) { - return buf.append("Aggregate(groupSet: ").append(groupSet) - .append(", groupSets: ").append(groupSets) - .append(", calls: ").append(aggCalls).append(")"); - } - - public ImmutableBitSet getGroupSet() { - return groupSet; - } - - public ImmutableList<ImmutableBitSet> getGroupSets() { - return groupSets; - } - - public List<AggregateCall> getAggCallList() { - return aggCalls; - } - - public Aggregate.Group getGroupType() { - return Aggregate.Group.induce(groupSet, groupSets); - } - } - - /** Mutable equivalent of {@link org.apache.calcite.rel.core.Sort}. */ - protected static class MutableSort extends MutableSingleRel { - private final RelCollation collation; - private final RexNode offset; - private final RexNode fetch; - - private MutableSort(MutableRel input, RelCollation collation, - RexNode offset, RexNode fetch) { - super(MutableRelType.SORT, input.rowType, input); - this.collation = collation; - this.offset = offset; - this.fetch = fetch; - } - - static MutableSort of(MutableRel input, RelCollation collation, - RexNode offset, RexNode fetch) { - return new MutableSort(input, collation, offset, fetch); - } - - @Override public boolean equals(Object obj) { - return obj == this - || obj instanceof MutableSort - && collation.equals(((MutableSort) obj).collation) - && Objects.equals(offset, ((MutableSort) obj).offset) - && Objects.equals(fetch, ((MutableSort) obj).fetch) - && input.equals(((MutableSort) obj).input); - } - - @Override public int hashCode() { - return Objects.hash(input, collation, offset, fetch); - } - - @Override public StringBuilder digest(StringBuilder buf) { - buf.append("Sort(collation: ").append(collation); - if (offset != null) { - buf.append(", offset: ").append(offset); - } - if (fetch != null) { - buf.append(", fetch: ").append(fetch); - } - return buf.append(")"); - } - } - - /** Base class for set-operations. */ - protected abstract static class MutableSetOp extends MutableRel { - protected final List<MutableRel> inputs; - - private MutableSetOp(RelOptCluster cluster, RelDataType rowType, - MutableRelType type, List<MutableRel> inputs) { - super(cluster, rowType, type); - this.inputs = inputs; - } - - @Override public void setInput(int ordinalInParent, MutableRel input) { - inputs.set(ordinalInParent, input); - if (input != null) { - input.parent = this; - input.ordinalInParent = ordinalInParent; - } - } - - @Override public List<MutableRel> getInputs() { - return inputs; - } - - @Override public void childrenAccept(MutableRelVisitor visitor) { - for (MutableRel input : inputs) { - visitor.visit(input); - } - } - } - - /** Mutable equivalent of - * {@link org.apache.calcite.rel.logical.LogicalUnion}. */ - protected static class MutableUnion extends MutableSetOp { - public boolean all; - - private MutableUnion(RelOptCluster cluster, RelDataType rowType, - List<MutableRel> inputs, boolean all) { - super(cluster, rowType, MutableRelType.UNION, inputs); - this.all = all; - } - - static MutableUnion of(List<MutableRel> inputs, boolean all) { - assert inputs.size() >= 2; - final MutableRel input0 = inputs.get(0); - return new MutableUnion(input0.cluster, input0.rowType, inputs, all); - } - - @Override public boolean equals(Object obj) { - return obj == this - || obj instanceof MutableUnion - && inputs.equals(((MutableUnion) obj).getInputs()); - } - - @Override public int hashCode() { - return Objects.hash(type, inputs); - } - - @Override public StringBuilder digest(StringBuilder buf) { - return buf.append("Union"); - } - } - - /** Base Class for relations with two inputs */ - private abstract static class MutableBiRel extends MutableRel { - protected MutableRel left; - protected MutableRel right; - - MutableBiRel(MutableRelType type, RelOptCluster cluster, RelDataType rowType, - MutableRel left, MutableRel right) { - super(cluster, rowType, type); - this.left = left; - left.parent = this; - left.ordinalInParent = 0; - - this.right = right; - right.parent = this; - right.ordinalInParent = 1; - } - - public void setInput(int ordinalInParent, MutableRel input) { - if (ordinalInParent > 1) { - throw new IllegalArgumentException(); - } - if (ordinalInParent == 0) { - this.left = input; - } else { - this.right = input; - } - if (input != null) { - input.parent = this; - input.ordinalInParent = ordinalInParent; - } - } - - public List<MutableRel> getInputs() { - return ImmutableList.of(left, right); - } - - public MutableRel getLeft() { - return left; - } - - public MutableRel getRight() { - return right; - } - - public void childrenAccept(MutableRelVisitor visitor) { - - visitor.visit(left); - visitor.visit(right); - } - } - - /** Mutable equivalent of - * {@link org.apache.calcite.rel.logical.LogicalJoin}. */ - private static class MutableJoin extends MutableBiRel { - //~ Instance fields -------------------------------------------------------- - - protected final RexNode condition; - protected final ImmutableSet<CorrelationId> variablesSet; - - /** - * Values must be of enumeration {@link JoinRelType}, except that - * {@link JoinRelType#RIGHT} is disallowed. - */ - protected JoinRelType joinType; - - private MutableJoin( - RelDataType rowType, - MutableRel left, - MutableRel right, - RexNode condition, - JoinRelType joinType, - Set<CorrelationId> variablesSet) { - super(MutableRelType.JOIN, left.cluster, rowType, left, right); - this.condition = Preconditions.checkNotNull(condition); - this.variablesSet = ImmutableSet.copyOf(variablesSet); - this.joinType = Preconditions.checkNotNull(joinType); - } - - public RexNode getCondition() { - return condition; - } - - public JoinRelType getJoinType() { - return joinType; - } - - public ImmutableSet<CorrelationId> getVariablesSet() { - return variablesSet; - } - - static MutableJoin of(RelOptCluster cluster, MutableRel left, - MutableRel right, RexNode condition, JoinRelType joinType, - Set<CorrelationId> variablesStopped) { - List<RelDataTypeField> fieldList = Collections.emptyList(); - RelDataType rowType = - SqlValidatorUtil.deriveJoinRowType(left.getRowType(), - right.getRowType(), joinType, cluster.getTypeFactory(), null, - fieldList); - return new MutableJoin(rowType, left, right, condition, joinType, - variablesStopped); - } - - @Override public boolean equals(Object obj) { - return obj == this - || obj instanceof MutableJoin - && joinType == ((MutableJoin) obj).joinType - && condition.toString().equals( - ((MutableJoin) obj).condition.toString()) - && left.equals(((MutableJoin) obj).left) - && right.equals(((MutableJoin) obj).right); - } - - @Override public int hashCode() { - return Objects.hash(left, right, condition.toString(), joinType); - } - - @Override public StringBuilder digest(StringBuilder buf) { - return buf.append("Join(left: ").append(left) - .append(", right:").append(right) - .append(")"); - } - } - - /** Utilities for dealing with {@link MutableRel}s. */ - protected static class MutableRels { - public static boolean contains(MutableRel ancestor, - final MutableRel target) { - if (ancestor.equals(target)) { - // Short-cut common case. - return true; - } - try { - new MutableRelVisitor() { - @Override public void visit(MutableRel node) { - if (node.equals(target)) { - throw Util.FoundOne.NULL; - } - super.visit(node); - } - // CHECKSTYLE: IGNORE 1 - }.go(ancestor); - return false; - } catch (Util.FoundOne e) { - return true; - } - } - - public static MutableRel preOrderTraverseNext(MutableRel node) { - MutableRel parent = node.getParent(); - int ordinal = node.ordinalInParent + 1; - while (parent != null) { - if (parent.getInputs().size() > ordinal) { - return parent.getInputs().get(ordinal); - } - node = parent; - parent = node.getParent(); - ordinal = node.ordinalInParent + 1; - } - return null; - } - - private static List<MutableRel> descendants(MutableRel query) { - final List<MutableRel> list = new ArrayList<>(); - descendantsRecurse(list, query); - return list; - } - - private static void descendantsRecurse(List<MutableRel> list, - MutableRel rel) { - list.add(rel); - for (MutableRel input : rel.getInputs()) { - descendantsRecurse(list, input); - } - } - - /** Returns whether two relational expressions have the same row-type. */ - public static boolean equalType(String desc0, MutableRel rel0, String desc1, - MutableRel rel1, Litmus litmus) { - return RelOptUtil.equal(desc0, rel0.getRowType(), - desc1, rel1.getRowType(), litmus); - } - - /** Within a relational expression {@code query}, replaces occurrences of - * {@code find} with {@code replace}. - * - * <p>Assumes relational expressions (and their descendants) are not null. - * Does not handle cycles. */ - public static Replacement replace(MutableRel query, MutableRel find, - MutableRel replace) { - if (find.equals(replace)) { - // Short-cut common case. - return null; - } - assert equalType("find", find, "replace", replace, Litmus.THROW); - return replaceRecurse(query, find, replace); - } - - /** Helper for {@link #replace}. */ - private static Replacement replaceRecurse(MutableRel query, - MutableRel find, MutableRel replace) { - if (find.equals(query)) { - query.replaceInParent(replace); - return new Replacement(query, replace); - } - for (MutableRel input : query.getInputs()) { - Replacement r = replaceRecurse(input, find, replace); - if (r != null) { - return r; - } - } - return null; - } - - /** Based on - * {@link org.apache.calcite.rel.rules.ProjectRemoveRule#strip}. */ - public static MutableRel strip(MutableProject project) { - return isTrivial(project) ? project.getInput() : project; - } - - /** Based on - * {@link org.apache.calcite.rel.rules.ProjectRemoveRule#isTrivial(org.apache.calcite.rel.core.Project)}. */ - public static boolean isTrivial(MutableProject project) { - MutableRel child = project.getInput(); - final RelDataType childRowType = child.getRowType(); - return RexUtil.isIdentity(project.getProjects(), childRowType); - } - - /** Equivalent to - * {@link RelOptUtil#createProject(org.apache.calcite.rel.RelNode, java.util.List)} - * for {@link MutableRel}. */ - public static MutableRel createProject(final MutableRel child, - final List<Integer> posList) { - final RelDataType rowType = child.getRowType(); - if (Mappings.isIdentity(posList, rowType.getFieldCount())) { - return child; - } - return MutableProject.of( - RelOptUtil.permute(child.cluster.getTypeFactory(), rowType, - Mappings.bijection(posList)), - child, - new AbstractList<RexNode>() { - public int size() { - return posList.size(); - } - - public RexNode get(int index) { - final int pos = posList.get(index); - return RexInputRef.of(pos, rowType); - } - }); - } - - /** Equivalence to {@link org.apache.calcite.plan.RelOptUtil#createCastRel} - * for {@link MutableRel}. */ - public static MutableRel createCastRel(MutableRel rel, - RelDataType castRowType, boolean rename) { - RelDataType rowType = rel.getRowType(); - if (RelOptUtil.areRowTypesEqual(rowType, castRowType, rename)) { - // nothing to do - return rel; - } - List<RexNode> castExps = - RexUtil.generateCastExpressions(rel.cluster.getRexBuilder(), - castRowType, rowType); - final List<String> fieldNames = - rename ? castRowType.getFieldNames() : rowType.getFieldNames(); - return MutableProject.of(rel, castExps, fieldNames); - } - } - - /** Visitor that prints an indented tree of {@link MutableRel}s. */ - protected static class MutableRelDumper extends MutableRelVisitor { - private final StringBuilder buf = new StringBuilder(); - private int level; - - @Override public void visit(MutableRel node) { - Spaces.append(buf, level * 2); - if (node == null) { - buf.append("null"); - } else { - node.digest(buf); - buf.append("\n"); - ++level; - super.visit(node); - --level; - } - } - - public String apply(MutableRel rel) { - go(rel); - return buf.toString(); - } - } - /** Returns if one rel is weaker than another. */ protected boolean isWeaker(MutableRel rel0, MutableRel rel) { if (rel0 == rel || equivalents.get(rel0).contains(rel)) { @@ -2225,7 +1305,7 @@ public class SubstitutionVisitor { return false; } - if (!rel.getRowType().equals(rel0.getRowType())) { + if (!rel.rowType.equals(rel0.rowType)) { return false; } @@ -2238,12 +1318,18 @@ public class SubstitutionVisitor { RexExecutorImpl rexImpl = (RexExecutorImpl) (rel.cluster.getPlanner().getExecutor()); - RexImplicationChecker rexImplicationChecker = new RexImplicationChecker( - rel.cluster.getRexBuilder(), - rexImpl, rel.getRowType()); + RexImplicationChecker rexImplicationChecker = + new RexImplicationChecker( + rel.cluster.getRexBuilder(), rexImpl, rel.rowType); + + return rexImplicationChecker.implies(((MutableFilter) rel0).condition, + ((MutableFilter) rel).condition); + } - return rexImplicationChecker.implies(((MutableFilter) rel0).getCondition(), - ((MutableFilter) rel).getCondition()); + /** Returns whether two relational expressions have the same row-type. */ + public static boolean equalType(String desc0, MutableRel rel0, String desc1, + MutableRel rel1, Litmus litmus) { + return RelOptUtil.equal(desc0, rel0.rowType, desc1, rel1.rowType, litmus); } /** Operand to a {@link UnifyRule}. */ http://git-wip-us.apache.org/repos/asf/calcite/blob/316a0587/core/src/main/java/org/apache/calcite/rel/mutable/Holder.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/mutable/Holder.java b/core/src/main/java/org/apache/calcite/rel/mutable/Holder.java new file mode 100644 index 0000000..b4da54f --- /dev/null +++ b/core/src/main/java/org/apache/calcite/rel/mutable/Holder.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.rel.mutable; + +import org.apache.calcite.rel.type.RelDataType; + +/** Implementation of {@link MutableRel} whose only purpose is to have a + * child. Used as the root of a tree. */ +public class Holder extends MutableSingleRel { + private Holder(RelDataType rowType, MutableRel input) { + super(MutableRelType.HOLDER, rowType, input); + } + + /** + * Creates a Holder. + * + * @param input Input relational expression + */ + public static Holder of(MutableRel input) { + return new Holder(input.rowType, input); + } + + @Override public StringBuilder digest(StringBuilder buf) { + return buf.append("Holder"); + } + + @Override public MutableRel clone() { + return Holder.of(input.clone()); + } +} + +// End Holder.java http://git-wip-us.apache.org/repos/asf/calcite/blob/316a0587/core/src/main/java/org/apache/calcite/rel/mutable/MutableAggregate.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/mutable/MutableAggregate.java b/core/src/main/java/org/apache/calcite/rel/mutable/MutableAggregate.java new file mode 100644 index 0000000..546b62a --- /dev/null +++ b/core/src/main/java/org/apache/calcite/rel/mutable/MutableAggregate.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.rel.mutable; + +import org.apache.calcite.rel.core.Aggregate; +import org.apache.calcite.rel.core.AggregateCall; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.util.ImmutableBitSet; + +import com.google.common.collect.ImmutableList; + +import java.util.List; +import java.util.Objects; + +/** Mutable equivalent of {@link org.apache.calcite.rel.core.Aggregate}. */ +public class MutableAggregate extends MutableSingleRel { + public final boolean indicator; + public final ImmutableBitSet groupSet; + public final ImmutableList<ImmutableBitSet> groupSets; + public final List<AggregateCall> aggCalls; + + private MutableAggregate(MutableRel input, RelDataType rowType, + boolean indicator, ImmutableBitSet groupSet, + List<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) { + super(MutableRelType.AGGREGATE, rowType, input); + this.indicator = indicator; + this.groupSet = groupSet; + this.groupSets = groupSets == null + ? ImmutableList.of(groupSet) + : ImmutableList.copyOf(groupSets); + this.aggCalls = aggCalls; + } + + /** + * Creates a MutableAggregate. + * + * @param input Input relational expression + * @param indicator Whether row type should include indicator fields to + * indicate which grouping set is active; must be true if + * aggregate is not simple + * @param groupSet Bit set of grouping fields + * @param groupSets List of all grouping sets; null for just {@code groupSet} + * @param aggCalls Collection of calls to aggregate functions + */ + public static MutableAggregate of(MutableRel input, boolean indicator, + ImmutableBitSet groupSet, ImmutableList<ImmutableBitSet> groupSets, + List<AggregateCall> aggCalls) { + RelDataType rowType = + Aggregate.deriveRowType(input.cluster.getTypeFactory(), + input.rowType, indicator, groupSet, groupSets, aggCalls); + return new MutableAggregate(input, rowType, indicator, groupSet, + groupSets, aggCalls); + } + + @Override public boolean equals(Object obj) { + return obj == this + || obj instanceof MutableAggregate + && groupSet.equals(((MutableAggregate) obj).groupSet) + && aggCalls.equals(((MutableAggregate) obj).aggCalls) + && input.equals(((MutableAggregate) obj).input); + } + + @Override public int hashCode() { + return Objects.hash(input, groupSet, aggCalls); + } + + @Override public StringBuilder digest(StringBuilder buf) { + return buf.append("Aggregate(groupSet: ").append(groupSet) + .append(", groupSets: ").append(groupSets) + .append(", calls: ").append(aggCalls).append(")"); + } + + public Aggregate.Group getGroupType() { + return Aggregate.Group.induce(groupSet, groupSets); + } + + @Override public MutableRel clone() { + return MutableAggregate.of(input.clone(), + indicator, groupSet, groupSets, aggCalls); + } +} + +// End MutableAggregate.java http://git-wip-us.apache.org/repos/asf/calcite/blob/316a0587/core/src/main/java/org/apache/calcite/rel/mutable/MutableBiRel.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/mutable/MutableBiRel.java b/core/src/main/java/org/apache/calcite/rel/mutable/MutableBiRel.java new file mode 100644 index 0000000..2c082ac --- /dev/null +++ b/core/src/main/java/org/apache/calcite/rel/mutable/MutableBiRel.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.rel.mutable; + +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.rel.type.RelDataType; + +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** Mutable equivalent of {@link org.apache.calcite.rel.BiRel}. */ +abstract class MutableBiRel extends MutableRel { + protected MutableRel left; + protected MutableRel right; + + protected MutableBiRel(MutableRelType type, RelOptCluster cluster, + RelDataType rowType, MutableRel left, MutableRel right) { + super(cluster, rowType, type); + this.left = left; + left.parent = this; + left.ordinalInParent = 0; + + this.right = right; + right.parent = this; + right.ordinalInParent = 1; + } + + public void setInput(int ordinalInParent, MutableRel input) { + if (ordinalInParent > 1) { + throw new IllegalArgumentException(); + } + if (ordinalInParent == 0) { + this.left = input; + } else { + this.right = input; + } + if (input != null) { + input.parent = this; + input.ordinalInParent = ordinalInParent; + } + } + + public List<MutableRel> getInputs() { + return ImmutableList.of(left, right); + } + + public MutableRel getLeft() { + return left; + } + + public MutableRel getRight() { + return right; + } + + public void childrenAccept(MutableRelVisitor visitor) { + + visitor.visit(left); + visitor.visit(right); + } +} + +// End MutableBiRel.java http://git-wip-us.apache.org/repos/asf/calcite/blob/316a0587/core/src/main/java/org/apache/calcite/rel/mutable/MutableCalc.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/mutable/MutableCalc.java b/core/src/main/java/org/apache/calcite/rel/mutable/MutableCalc.java new file mode 100644 index 0000000..3aca910 --- /dev/null +++ b/core/src/main/java/org/apache/calcite/rel/mutable/MutableCalc.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.rel.mutable; + +import org.apache.calcite.rex.RexProgram; + +import java.util.Objects; + +/** Mutable equivalent of {@link org.apache.calcite.rel.core.Calc}. */ +public class MutableCalc extends MutableSingleRel { + public final RexProgram program; + + private MutableCalc(MutableRel input, RexProgram program) { + super(MutableRelType.CALC, program.getOutputRowType(), input); + this.program = program; + } + + /** + * Creates a MutableCalc + * + * @param input Input relational expression + * @param program Calc program + */ + public static MutableCalc of(MutableRel input, RexProgram program) { + return new MutableCalc(input, program); + } + + @Override public boolean equals(Object obj) { + return obj == this + || obj instanceof MutableCalc + && MutableRel.STRING_EQUIVALENCE.equivalent( + program, ((MutableCalc) obj).program) + && input.equals(((MutableCalc) obj).input); + } + + @Override public int hashCode() { + return Objects.hash(input, + MutableRel.STRING_EQUIVALENCE.hash(program)); + } + + @Override public StringBuilder digest(StringBuilder buf) { + return buf.append("Calc(program: ").append(program).append(")"); + } + + @Override public MutableRel clone() { + return MutableCalc.of(input.clone(), program); + } +} + +// End MutableCalc.java http://git-wip-us.apache.org/repos/asf/calcite/blob/316a0587/core/src/main/java/org/apache/calcite/rel/mutable/MutableCollect.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/mutable/MutableCollect.java b/core/src/main/java/org/apache/calcite/rel/mutable/MutableCollect.java new file mode 100644 index 0000000..4e413f5 --- /dev/null +++ b/core/src/main/java/org/apache/calcite/rel/mutable/MutableCollect.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.rel.mutable; + +import org.apache.calcite.rel.type.RelDataType; + +import java.util.Objects; + +/** Mutable equivalent of {@link org.apache.calcite.rel.core.Collect}. */ +public class MutableCollect extends MutableSingleRel { + public final String fieldName; + + private MutableCollect(RelDataType rowType, + MutableRel input, String fieldName) { + super(MutableRelType.COLLECT, rowType, input); + this.fieldName = fieldName; + } + + /** + * Creates a MutableCollect. + * + * @param rowType Row type + * @param input Input relational expression + * @param fieldName Name of the sole output field + */ + public static MutableCollect of(RelDataType rowType, + MutableRel input, String fieldName) { + return new MutableCollect(rowType, input, fieldName); + } + + @Override public boolean equals(Object obj) { + return obj == this + || obj instanceof MutableCollect + && fieldName.equals(((MutableCollect) obj).fieldName) + && input.equals(((MutableCollect) obj).input); + } + + @Override public int hashCode() { + return Objects.hash(input, fieldName); + } + + @Override public StringBuilder digest(StringBuilder buf) { + return buf.append("Collect(fieldName: ").append(fieldName).append(")"); + } + + @Override public MutableRel clone() { + return MutableCollect.of(rowType, input.clone(), fieldName); + } +} + +// End MutableCollect.java http://git-wip-us.apache.org/repos/asf/calcite/blob/316a0587/core/src/main/java/org/apache/calcite/rel/mutable/MutableCorrelate.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/mutable/MutableCorrelate.java b/core/src/main/java/org/apache/calcite/rel/mutable/MutableCorrelate.java new file mode 100644 index 0000000..5be0152 --- /dev/null +++ b/core/src/main/java/org/apache/calcite/rel/mutable/MutableCorrelate.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.rel.mutable; + +import org.apache.calcite.rel.core.CorrelationId; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.sql.SemiJoinType; +import org.apache.calcite.util.ImmutableBitSet; + +import java.util.Objects; + +/** Mutable equivalent of {@link org.apache.calcite.rel.core.Correlate}. */ +public class MutableCorrelate extends MutableBiRel { + public final CorrelationId correlationId; + public final ImmutableBitSet requiredColumns; + public final SemiJoinType joinType; + + private MutableCorrelate( + RelDataType rowType, + MutableRel left, + MutableRel right, + CorrelationId correlationId, + ImmutableBitSet requiredColumns, + SemiJoinType joinType) { + super(MutableRelType.CORRELATE, left.cluster, rowType, left, right); + this.correlationId = correlationId; + this.requiredColumns = requiredColumns; + this.joinType = joinType; + } + + /** + * Creates a MutableCorrelate. + * + * @param rowType Row type + * @param left Left input relational expression + * @param right Right input relational expression + * @param correlationId Variable name for the row of left input + * @param requiredColumns Required columns + * @param joinType Join type + */ + public static MutableCorrelate of(RelDataType rowType, MutableRel left, + MutableRel right, CorrelationId correlationId, + ImmutableBitSet requiredColumns, SemiJoinType joinType) { + return new MutableCorrelate(rowType, left, right, correlationId, + requiredColumns, joinType); + } + + @Override public boolean equals(Object obj) { + return obj == this + || obj instanceof MutableCorrelate + && correlationId.equals( + ((MutableCorrelate) obj).correlationId) + && requiredColumns.equals( + ((MutableCorrelate) obj).requiredColumns) + && joinType == ((MutableCorrelate) obj).joinType + && left.equals(((MutableCorrelate) obj).left) + && right.equals(((MutableCorrelate) obj).right); + } + + @Override public int hashCode() { + return Objects.hash(left, right, correlationId, requiredColumns, joinType); + } + + @Override public StringBuilder digest(StringBuilder buf) { + return buf.append("Correlate(correlationId: ").append(correlationId) + .append(", requiredColumns: ").append(requiredColumns) + .append(", joinType: ").append(joinType) + .append(")"); + } + + @Override public MutableRel clone() { + return MutableCorrelate.of(rowType, left.clone(), + right.clone(), correlationId, requiredColumns, joinType); + } +} + +// End MutableCorrelate.java http://git-wip-us.apache.org/repos/asf/calcite/blob/316a0587/core/src/main/java/org/apache/calcite/rel/mutable/MutableExchange.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/mutable/MutableExchange.java b/core/src/main/java/org/apache/calcite/rel/mutable/MutableExchange.java new file mode 100644 index 0000000..2c3c28d --- /dev/null +++ b/core/src/main/java/org/apache/calcite/rel/mutable/MutableExchange.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.rel.mutable; + +import org.apache.calcite.rel.RelDistribution; + +import java.util.Objects; + +/** Mutable equivalent of {@link org.apache.calcite.rel.core.Exchange}. */ +public class MutableExchange extends MutableSingleRel { + public final RelDistribution distribution; + + private MutableExchange(MutableRel input, RelDistribution distribution) { + super(MutableRelType.EXCHANGE, input.rowType, input); + this.distribution = distribution; + } + + /** + * Creates a MutableExchange. + * + * @param input Input relational expression + * @param distribution Distribution specification + */ + public static MutableExchange of(MutableRel input, RelDistribution distribution) { + return new MutableExchange(input, distribution); + } + + @Override public boolean equals(Object obj) { + return obj == this + || obj instanceof MutableExchange + && distribution.equals(((MutableExchange) obj).distribution) + && input.equals(((MutableExchange) obj).input); + } + + @Override public int hashCode() { + return Objects.hash(input, distribution); + } + + @Override public StringBuilder digest(StringBuilder buf) { + return buf.append("Exchange(distribution: ").append(distribution).append(")"); + } + + @Override public MutableRel clone() { + return MutableExchange.of(input.clone(), distribution); + } +} + +// End MutableExchange.java http://git-wip-us.apache.org/repos/asf/calcite/blob/316a0587/core/src/main/java/org/apache/calcite/rel/mutable/MutableFilter.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/mutable/MutableFilter.java b/core/src/main/java/org/apache/calcite/rel/mutable/MutableFilter.java new file mode 100644 index 0000000..787487f --- /dev/null +++ b/core/src/main/java/org/apache/calcite/rel/mutable/MutableFilter.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.rel.mutable; + +import org.apache.calcite.rex.RexNode; + +import java.util.Objects; + +/** Mutable equivalent of {@link org.apache.calcite.rel.core.Filter}. */ +public class MutableFilter extends MutableSingleRel { + public final RexNode condition; + + private MutableFilter(MutableRel input, RexNode condition) { + super(MutableRelType.FILTER, input.rowType, input); + this.condition = condition; + } + + /** + * Creates a MutableFilter. + * + * @param input Input relational expression + * @param condition Boolean expression which determines whether a row is + * allowed to pass + */ + public static MutableFilter of(MutableRel input, RexNode condition) { + return new MutableFilter(input, condition); + } + + @Override public boolean equals(Object obj) { + return obj == this + || obj instanceof MutableFilter + && condition.toString().equals( + ((MutableFilter) obj).condition.toString()) + && input.equals(((MutableFilter) obj).input); + } + + @Override public int hashCode() { + return Objects.hash(input, condition.toString()); + } + + @Override public StringBuilder digest(StringBuilder buf) { + return buf.append("Filter(condition: ").append(condition).append(")"); + } + + @Override public MutableRel clone() { + return MutableFilter.of(input.clone(), condition); + } +} + +// End MutableFilter.java http://git-wip-us.apache.org/repos/asf/calcite/blob/316a0587/core/src/main/java/org/apache/calcite/rel/mutable/MutableIntersect.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/mutable/MutableIntersect.java b/core/src/main/java/org/apache/calcite/rel/mutable/MutableIntersect.java new file mode 100644 index 0000000..5829f80 --- /dev/null +++ b/core/src/main/java/org/apache/calcite/rel/mutable/MutableIntersect.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.rel.mutable; + +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.rel.type.RelDataType; + +import java.util.List; + +/** Mutable equivalent of {@link org.apache.calcite.rel.core.Intersect}. */ +public class MutableIntersect extends MutableSetOp { + private MutableIntersect(RelOptCluster cluster, RelDataType rowType, + List<MutableRel> inputs, boolean all) { + super(cluster, rowType, MutableRelType.INTERSECT, inputs, all); + } + + /** + * Creates a MutableIntersect. + * + * @param rowType Row type + * @param inputs Input relational expressions + * @param all Whether to perform a multiset intersection or a set + * intersection + */ + public static MutableIntersect of( + RelDataType rowType, List<MutableRel> inputs, boolean all) { + assert inputs.size() >= 2; + final MutableRel input0 = inputs.get(0); + return new MutableIntersect(input0.cluster, rowType, inputs, all); + } + + @Override public StringBuilder digest(StringBuilder buf) { + return buf.append("Intersect(all: ").append(all).append(")"); + } + + @Override public MutableRel clone() { + return MutableIntersect.of(rowType, cloneChildren(), all); + } +} + +// End MutableIntersect.java
