You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2014/12/18 08:28:12 UTC
[3/3] incubator-calcite git commit: [CALCITE-479] Migrate
RelNode.getChildExps to RelNode.accept(RexShuttle)
[CALCITE-479] Migrate RelNode.getChildExps to RelNode.accept(RexShuttle)
Close apache/incubator-calcite#31
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/288254b2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/288254b2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/288254b2
Branch: refs/heads/master
Commit: 288254b22b270b9a6e893490e776a3ba4ff01fb6
Parents: 86c7c08
Author: Vladimir Sitnikov <si...@gmail.com>
Authored: Sun Dec 14 15:41:57 2014 +0300
Committer: Julian Hyde <jh...@apache.org>
Committed: Wed Dec 17 20:50:56 2014 -0800
----------------------------------------------------------------------
.../enumerable/EnumerableTableFunctionScan.java | 10 ++-
.../org/apache/calcite/plan/RelOptUtil.java | 30 ++++---
.../apache/calcite/plan/VisitorRelVisitor.java | 55 -------------
.../org/apache/calcite/rel/AbstractRelNode.java | 5 ++
.../calcite/rel/RelHomogeneousShuttle.java | 86 ++++++++++++++++++++
.../java/org/apache/calcite/rel/RelNode.java | 14 ++++
.../java/org/apache/calcite/rel/core/Calc.java | 28 +++++++
.../org/apache/calcite/rel/core/Filter.java | 9 ++
.../java/org/apache/calcite/rel/core/Join.java | 9 ++
.../org/apache/calcite/rel/core/Project.java | 9 ++
.../java/org/apache/calcite/rel/core/Sort.java | 15 ++++
.../calcite/rel/core/TableFunctionScan.java | 65 +++++++++++++--
.../calcite/rel/externalize/RelWriterImpl.java | 22 ++---
.../rel/logical/LogicalTableFunctionScan.java | 14 +++-
.../org/apache/calcite/rel/rules/MultiJoin.java | 25 ++++++
.../rel/rules/ReduceExpressionsRule.java | 10 ++-
.../java/org/apache/calcite/rex/RexShuttle.java | 5 +-
.../sql2rel/DeduplicateCorrelateVariables.java | 45 ++--------
.../apache/calcite/sql2rel/RelFieldTrimmer.java | 4 +-
19 files changed, 318 insertions(+), 142 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableFunctionScan.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableFunctionScan.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableFunctionScan.java
index 936e7fc..d8baf19 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableFunctionScan.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableFunctionScan.java
@@ -45,9 +45,15 @@ public class EnumerableTableFunctionScan extends TableFunctionScan
columnMappings);
}
- @Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
+ @Override public EnumerableTableFunctionScan copy(
+ RelTraitSet traitSet,
+ List<RelNode> inputs,
+ RexNode rexCall,
+ Type elementType,
+ RelDataType rowType,
+ Set<RelColumnMapping> columnMappings) {
return new EnumerableTableFunctionScan(getCluster(), traitSet, inputs,
- getElementType(), getRowType(), getCall(), getColumnMappings());
+ elementType, rowType, rexCall, columnMappings);
}
public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/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 3c31ed2..9cc2401 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -19,7 +19,9 @@ package org.apache.calcite.plan;
import org.apache.calcite.linq4j.Ord;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelCollationImpl;
+import org.apache.calcite.rel.RelHomogeneousShuttle;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.RelShuttle;
import org.apache.calcite.rel.RelVisitor;
import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.core.AggregateCall;
@@ -152,22 +154,18 @@ public abstract class RelOptUtil {
*/
public static Set<String> getVariablesUsed(RelNode rel) {
final VariableUsedVisitor vuv = new VariableUsedVisitor();
- final VisitorRelVisitor visitor =
- new VisitorRelVisitor(vuv) {
- // implement RelVisitor
- public void visit(
- RelNode p,
- int ordinal,
- RelNode parent) {
- p.collectVariablesUsed(vuv.variables);
- super.visit(p, ordinal, parent);
-
- // Important! Remove stopped variables AFTER we visit
- // children. (which what super.visit() does)
- vuv.variables.removeAll(p.getVariablesStopped());
- }
- };
- visitor.go(rel);
+ 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;
+ }
+ };
+ rel.accept(visitor);
return vuv.variables;
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/plan/VisitorRelVisitor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/VisitorRelVisitor.java b/core/src/main/java/org/apache/calcite/plan/VisitorRelVisitor.java
deleted file mode 100644
index d4cd0f5..0000000
--- a/core/src/main/java/org/apache/calcite/plan/VisitorRelVisitor.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.plan;
-
-import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.RelVisitor;
-import org.apache.calcite.rex.RexNode;
-import org.apache.calcite.rex.RexVisitor;
-
-import java.util.List;
-
-/**
- * Walks over a tree of {@link RelNode relational expressions}, walking a
- * {@link RexVisitor} over every expression in that tree.
- */
-public class VisitorRelVisitor extends RelVisitor {
- //~ Instance fields --------------------------------------------------------
-
- protected final RexVisitor<?> visitor;
-
- //~ Constructors -----------------------------------------------------------
-
- public VisitorRelVisitor(RexVisitor<?> visitor) {
- this.visitor = visitor;
- }
-
- //~ Methods ----------------------------------------------------------------
-
- public void visit(
- RelNode p,
- int ordinal,
- RelNode parent) {
- List<RexNode> childExps = p.getChildExps();
- for (RexNode childExp : childExps) {
- childExp.accept(visitor);
- }
- p.childrenAccept(this);
- }
-}
-
-// End VisitorRelVisitor.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/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 a1f78d4..7b24e46 100644
--- a/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
+++ b/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
@@ -31,6 +31,7 @@ import org.apache.calcite.rel.metadata.Metadata;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.sql.SqlExplainLevel;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.Pair;
@@ -253,6 +254,10 @@ public abstract class AbstractRelNode implements RelNode {
return shuttle.visit(this);
}
+ public RelNode accept(RexShuttle shuttle) {
+ return this;
+ }
+
public RelOptCost computeSelfCost(RelOptPlanner planner) {
// by default, assume cost is proportional to number of rows
double rowCount = RelMetadataQuery.getRowCount(this);
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/rel/RelHomogeneousShuttle.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/RelHomogeneousShuttle.java b/core/src/main/java/org/apache/calcite/rel/RelHomogeneousShuttle.java
new file mode 100644
index 0000000..56fa883
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/rel/RelHomogeneousShuttle.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.rel;
+
+import org.apache.calcite.rel.core.Sort;
+import org.apache.calcite.rel.core.TableFunctionScan;
+import org.apache.calcite.rel.core.TableScan;
+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;
+import org.apache.calcite.rel.logical.LogicalMinus;
+import org.apache.calcite.rel.logical.LogicalProject;
+import org.apache.calcite.rel.logical.LogicalUnion;
+import org.apache.calcite.rel.logical.LogicalValues;
+
+/**
+ * Visits all the relations in a homogeneous way: always redirects calls to
+ * {@code accept(RelNode)}.
+ */
+public class RelHomogeneousShuttle extends RelShuttleImpl {
+ @Override public RelNode visit(LogicalAggregate aggregate) {
+ return visit((RelNode) aggregate);
+ }
+
+ @Override public RelNode visit(TableScan scan) {
+ return visit((RelNode) scan);
+ }
+
+ @Override public RelNode visit(TableFunctionScan scan) {
+ return visit((RelNode) scan);
+ }
+
+ @Override public RelNode visit(LogicalValues values) {
+ return visit((RelNode) values);
+ }
+
+ @Override public RelNode visit(LogicalFilter filter) {
+ return visit((RelNode) filter);
+ }
+
+ @Override public RelNode visit(LogicalProject project) {
+ return visit((RelNode) project);
+ }
+
+ @Override public RelNode visit(LogicalJoin join) {
+ return visit((RelNode) join);
+ }
+
+ @Override public RelNode visit(LogicalCorrelate correlate) {
+ return visit((RelNode) correlate);
+ }
+
+ @Override public RelNode visit(LogicalUnion union) {
+ return visit((RelNode) union);
+ }
+
+ @Override public RelNode visit(LogicalIntersect intersect) {
+ return visit((RelNode) intersect);
+ }
+
+ @Override public RelNode visit(LogicalMinus minus) {
+ return visit((RelNode) minus);
+ }
+
+ @Override public RelNode visit(Sort sort) {
+ return visit((RelNode) sort);
+ }
+}
+
+// End RelHomogeneousShuttle.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/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 36e735e..c4a2aca 100644
--- a/core/src/main/java/org/apache/calcite/rel/RelNode.java
+++ b/core/src/main/java/org/apache/calcite/rel/RelNode.java
@@ -27,6 +27,7 @@ import org.apache.calcite.rel.metadata.Metadata;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.util.ImmutableBitSet;
import java.util.List;
@@ -85,8 +86,11 @@ public interface RelNode extends RelOptNode, Cloneable {
* implementations will return an immutable list. If there are no
* child expressions, returns an empty list, not <code>null</code>.
*
+ * @deprecated use #accept(org.apache.calcite.rex.RexShuttle)
* @return List of this relational expression's child expressions
+ * @see #accept(org.apache.calcite.rex.RexShuttle)
*/
+ @Deprecated
List<RexNode> getChildExps();
/**
@@ -369,6 +373,16 @@ public interface RelNode extends RelOptNode, Cloneable {
* this node's children
*/
RelNode accept(RelShuttle shuttle);
+
+ /**
+ * Accepts a visit from a shuttle. If the shuttle updates expression, then
+ * a copy of the relation should be created.
+ *
+ * @param shuttle Shuttle
+ * @return A copy of this node incorporating changes made by the shuttle to
+ * this node's children
+ */
+ RelNode accept(RexShuttle shuttle);
}
// End RelNode.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/rel/core/Calc.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/Calc.java b/core/src/main/java/org/apache/calcite/rel/core/Calc.java
index 47240f0..b8b9b5c 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/Calc.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/Calc.java
@@ -28,7 +28,10 @@ import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.SingleRel;
import org.apache.calcite.rel.logical.LogicalFilter;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rex.RexLocalRef;
+import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexProgram;
+import org.apache.calcite.rex.RexShuttle;
import com.google.common.collect.ImmutableList;
@@ -144,6 +147,31 @@ public abstract class Calc extends SingleRel {
public RelWriter explainTerms(RelWriter pw) {
return program.explainCalc(super.explainTerms(pw));
}
+
+ public RelNode accept(RexShuttle shuttle) {
+ List<RexNode> oldExprs = program.getExprList();
+ List<RexNode> exprs = shuttle.apply(oldExprs);
+ List<RexLocalRef> oldProjects = program.getProjectList();
+ List<RexLocalRef> projects = shuttle.apply(oldProjects);
+ RexLocalRef oldCondition = program.getCondition();
+ RexNode condition = shuttle.apply(oldCondition);
+ assert condition instanceof RexLocalRef
+ : "Invalid condition after rewrite. Expected RexLocalRef, got "
+ + condition;
+ if (exprs == oldExprs
+ && projects == oldProjects
+ && condition == oldCondition) {
+ return this;
+ }
+ return copy(traitSet, getInput(),
+ new RexProgram(
+ program.getInputRowType(),
+ exprs,
+ projects,
+ (RexLocalRef) condition,
+ program.getOutputRowType()),
+ collationList);
+ }
}
// End Calc.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/rel/core/Filter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/Filter.java b/core/src/main/java/org/apache/calcite/rel/core/Filter.java
index 8fbdb0e..ca271db 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/Filter.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/Filter.java
@@ -29,6 +29,7 @@ import org.apache.calcite.rex.RexChecker;
import org.apache.calcite.rex.RexLocalRef;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexProgram;
+import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.rex.RexUtil;
import com.google.common.collect.ImmutableList;
@@ -96,6 +97,14 @@ public abstract class Filter extends SingleRel {
return ImmutableList.of(condition);
}
+ public RelNode accept(RexShuttle shuttle) {
+ RexNode condition = shuttle.apply(this.condition);
+ if (this.condition == condition) {
+ return this;
+ }
+ return copy(traitSet, getInput(), condition);
+ }
+
public RexNode getCondition() {
return condition;
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/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 9405a6e..1a6b5c1 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
@@ -29,6 +29,7 @@ import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rex.RexChecker;
import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.sql.type.SqlTypeName;
import com.google.common.collect.ImmutableList;
@@ -97,6 +98,14 @@ public abstract class Join extends BiRel {
return ImmutableList.of(condition);
}
+ public RelNode accept(RexShuttle shuttle) {
+ RexNode condition = shuttle.apply(this.condition);
+ if (this.condition == condition) {
+ return this;
+ }
+ return copy(traitSet, condition, left, right, joinType, isSemiJoinDone());
+ }
+
public RexNode getCondition() {
return condition;
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/rel/core/Project.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/Project.java b/core/src/main/java/org/apache/calcite/rel/core/Project.java
index 9032ca3..ec3978b 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/Project.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/Project.java
@@ -38,6 +38,7 @@ import org.apache.calcite.rex.RexFieldAccess;
import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexLocalRef;
import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.rex.RexVisitorImpl;
import org.apache.calcite.sql.SqlExplainLevel;
@@ -151,6 +152,14 @@ public abstract class Project extends SingleRel {
return exps;
}
+ public RelNode accept(RexShuttle shuttle) {
+ List<RexNode> exps = shuttle.apply(this.exps);
+ if (this.exps == exps) {
+ return this;
+ }
+ return copy(traitSet, getInput(), exps, rowType);
+ }
+
/**
* Returns the project expressions.
*
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/rel/core/Sort.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/Sort.java b/core/src/main/java/org/apache/calcite/rel/core/Sort.java
index 5c91666..445afb2 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/Sort.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/Sort.java
@@ -32,6 +32,7 @@ import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.SingleRel;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.util.Util;
import com.google.common.collect.ImmutableList;
@@ -162,6 +163,20 @@ public class Sort extends SingleRel {
return fieldExps;
}
+ public RelNode accept(RexShuttle shuttle) {
+ RexNode offset = shuttle.apply(this.offset);
+ RexNode fetch = shuttle.apply(this.fetch);
+ List<RexNode> fieldExps = shuttle.apply(this.fieldExps);
+ assert fieldExps == this.fieldExps
+ : "Sort node does not support modification of input field expressions."
+ + " Old expressions: " + this.fieldExps + ", new ones: " + fieldExps;
+ if (offset == this.offset
+ && fetch == this.fetch) {
+ return this;
+ }
+ return copy(traitSet, getInput(), collation, offset, fetch);
+ }
+
/**
* Returns the array of {@link RelFieldCollation}s asked for by the sort
* specification, from most significant to least significant.
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/rel/core/TableFunctionScan.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/TableFunctionScan.java b/core/src/main/java/org/apache/calcite/rel/core/TableFunctionScan.java
index 282b1f3..bffa50f 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/TableFunctionScan.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/TableFunctionScan.java
@@ -27,6 +27,7 @@ import org.apache.calcite.rel.metadata.RelColumnMapping;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -63,18 +64,19 @@ public abstract class TableFunctionScan extends AbstractRelNode {
*
* @param cluster Cluster that this relational expression belongs to
* @param inputs 0 or more relational inputs
- * @param rexCall function invocation expression
- * @param elementType element type of the collection that will implement
+ * @param rexCall Function invocation expression
+ * @param elementType Element type of the collection that will implement
* this table
- * @param rowType row type produced by function
- * @param columnMappings column mappings associated with this function
+ * @param rowType Row type produced by function
+ * @param columnMappings Column mappings associated with this function
*/
protected TableFunctionScan(
RelOptCluster cluster,
RelTraitSet traits,
List<RelNode> inputs,
RexNode rexCall,
- Type elementType, RelDataType rowType,
+ Type elementType,
+ RelDataType rowType,
Set<RelColumnMapping> columnMappings) {
super(cluster, traits);
this.rexCall = rexCall;
@@ -98,6 +100,34 @@ public abstract class TableFunctionScan extends AbstractRelNode {
//~ Methods ----------------------------------------------------------------
+ @Override public final TableFunctionScan copy(RelTraitSet traitSet,
+ List<RelNode> inputs) {
+ return copy(traitSet, inputs, rexCall, elementType, rowType,
+ columnMappings);
+ }
+
+ /**
+ * Copies this relational expression, substituting traits and
+ * inputs.
+ *
+ * @param traitSet Traits
+ * @param inputs 0 or more relational inputs
+ * @param rexCall Function invocation expression
+ * @param elementType Element type of the collection that will implement
+ * this table
+ * @param rowType Row type produced by function
+ * @param columnMappings Column mappings associated with this function
+ * @return Copy of this relational expression, substituting traits and
+ * inputs
+ */
+ public abstract TableFunctionScan copy(
+ RelTraitSet traitSet,
+ List<RelNode> inputs,
+ RexNode rexCall,
+ Type elementType,
+ RelDataType rowType,
+ Set<RelColumnMapping> columnMappings);
+
@Override public List<RelNode> getInputs() {
return inputs;
}
@@ -106,6 +136,15 @@ public abstract class TableFunctionScan extends AbstractRelNode {
return ImmutableList.of(rexCall);
}
+ public RelNode accept(RexShuttle shuttle) {
+ RexNode rexCall = shuttle.apply(this.rexCall);
+ if (rexCall == this.rexCall) {
+ return this;
+ }
+ return copy(traitSet, inputs, rexCall, elementType, rowType,
+ columnMappings);
+ }
+
@Override public void replaceInput(int ordinalInParent, RelNode p) {
final List<RelNode> newInputs = new ArrayList<RelNode>(inputs);
newInputs.set(ordinalInParent, p);
@@ -132,10 +171,16 @@ public abstract class TableFunctionScan extends AbstractRelNode {
return nRows;
}
+ /**
+ * Returns function invocation expression.
+ *
+ * <p>Within this rexCall, instances of
+ * {@link org.apache.calcite.rex.RexInputRef} refer to entire input
+ * {@link org.apache.calcite.rel.RelNode}s rather than their fields.
+ *
+ * @return function invocation expression
+ */
public RexNode getCall() {
- // NOTE jvs 7-May-2006: Within this rexCall, instances
- // of RexInputRef refer to entire input RelNodes rather
- // than their fields.
return rexCall;
}
@@ -153,6 +198,9 @@ public abstract class TableFunctionScan extends AbstractRelNode {
}
/**
+ * Returns set of mappings known for this table function, or null if unknown
+ * (not the same as empty!).
+ *
* @return set of mappings known for this table function, or null if unknown
* (not the same as empty!)
*/
@@ -162,6 +210,7 @@ public abstract class TableFunctionScan extends AbstractRelNode {
/**
* Returns element type of the collection that will implement this table.
+ *
* @return element type of the collection that will implement this table
*/
public Type getElementType() {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/rel/externalize/RelWriterImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/externalize/RelWriterImpl.java b/core/src/main/java/org/apache/calcite/rel/externalize/RelWriterImpl.java
index e39e421..63fb3ab 100644
--- a/core/src/main/java/org/apache/calcite/rel/externalize/RelWriterImpl.java
+++ b/core/src/main/java/org/apache/calcite/rel/externalize/RelWriterImpl.java
@@ -21,7 +21,6 @@ import org.apache.calcite.linq4j.Ord;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
-import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SqlExplainLevel;
import org.apache.calcite.util.Pair;
@@ -154,6 +153,16 @@ public class RelWriterImpl implements RelWriter {
}
public RelWriter done(RelNode node) {
+ assert checkInputsPresentInExplain(node);
+ final List<Pair<String, Object>> valuesCopy =
+ ImmutableList.copyOf(values);
+ values.clear();
+ explain_(node, valuesCopy);
+ pw.flush();
+ return this;
+ }
+
+ private boolean checkInputsPresentInExplain(RelNode node) {
int i = 0;
if (values.size() > 0 && values.get(0).left.equals("subset")) {
++i;
@@ -162,16 +171,7 @@ public class RelWriterImpl implements RelWriter {
assert values.get(i).right == input;
++i;
}
- for (RexNode expr : node.getChildExps()) {
- assert values.get(i).right == expr;
- ++i;
- }
- final List<Pair<String, Object>> valuesCopy =
- ImmutableList.copyOf(values);
- values.clear();
- explain_(node, valuesCopy);
- pw.flush();
- return this;
+ return true;
}
public boolean nest() {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java b/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java
index de0d1fa..e4e02f6 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalTableFunctionScan.java
@@ -75,14 +75,20 @@ public class LogicalTableFunctionScan extends TableFunctionScan {
//~ Methods ----------------------------------------------------------------
- @Override public LogicalTableFunctionScan copy(RelTraitSet traitSet,
- List<RelNode> inputs) {
+ @Override public LogicalTableFunctionScan copy(
+ RelTraitSet traitSet,
+ List<RelNode> inputs,
+ RexNode rexCall,
+ Type elementType,
+ RelDataType rowType,
+ Set<RelColumnMapping> columnMappings) {
assert traitSet.containsIfApplicable(Convention.NONE);
return new LogicalTableFunctionScan(
getCluster(),
inputs,
- getCall(),
- getElementType(), getRowType(),
+ rexCall,
+ elementType,
+ rowType,
columnMappings);
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/rel/rules/MultiJoin.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/MultiJoin.java b/core/src/main/java/org/apache/calcite/rel/rules/MultiJoin.java
index ce651bc..153f31b 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/MultiJoin.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/MultiJoin.java
@@ -26,6 +26,7 @@ import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.core.JoinRelType;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.ImmutableIntList;
import org.apache.calcite.util.ImmutableNullableList;
@@ -182,6 +183,30 @@ public final class MultiJoin extends AbstractRelNode {
return ImmutableList.of(joinFilter);
}
+ public RelNode accept(RexShuttle shuttle) {
+ RexNode joinFilter = shuttle.apply(this.joinFilter);
+ List<RexNode> outerJoinConditions = shuttle.apply(this.outerJoinConditions);
+ RexNode postJoinFilter = shuttle.apply(this.postJoinFilter);
+
+ if (joinFilter == this.joinFilter
+ && outerJoinConditions == this.outerJoinConditions
+ && postJoinFilter == this.postJoinFilter) {
+ return this;
+ }
+
+ return new MultiJoin(
+ getCluster(),
+ inputs,
+ joinFilter,
+ rowType,
+ isFullOuterJoin,
+ outerJoinConditions,
+ joinTypes,
+ projFields,
+ joinFieldRefCountsMap,
+ postJoinFilter);
+ }
+
/**
* @return join filters associated with this MultiJoin
*/
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
index c41a99d..f5a0ef7 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
@@ -88,7 +88,8 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
"ReduceExpressionsRule(Filter)") {
public void onMatch(RelOptRuleCall call) {
LogicalFilter filter = call.rel(0);
- List<RexNode> expList = new ArrayList<RexNode>(filter.getChildExps());
+ List<RexNode> expList = new ArrayList<RexNode>(1);
+ expList.add(filter.getCondition());
RexNode newConditionExp;
boolean reduced;
if (reduceExpressions(filter, expList)) {
@@ -100,7 +101,7 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
// predicate to see if it was already a constant,
// in which case we don't need any runtime decision
// about filtering.
- newConditionExp = filter.getChildExps().get(0);
+ newConditionExp = filter.getCondition();
reduced = false;
}
if (newConditionExp.isAlwaysTrue()) {
@@ -178,7 +179,7 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
public void onMatch(RelOptRuleCall call) {
LogicalProject project = call.rel(0);
List<RexNode> expList =
- new ArrayList<RexNode>(project.getChildExps());
+ new ArrayList<RexNode>(project.getProjects());
if (reduceExpressions(project, expList)) {
call.transformTo(
new LogicalProject(
@@ -200,7 +201,8 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
"ReduceExpressionsRule(Join)") {
public void onMatch(RelOptRuleCall call) {
final Join join = call.rel(0);
- List<RexNode> expList = new ArrayList<RexNode>(join.getChildExps());
+ List<RexNode> expList = new ArrayList<RexNode>(1);
+ expList.add(join.getCondition());
if (reduceExpressions(join, expList)) {
call.transformTo(
join.copy(
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/rex/RexShuttle.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexShuttle.java b/core/src/main/java/org/apache/calcite/rex/RexShuttle.java
index bd3ce46..9c6e46d 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexShuttle.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexShuttle.java
@@ -218,7 +218,7 @@ public class RexShuttle implements RexVisitor<RexNode> {
int changeCount = 0;
for (int i = 0; i < exprList.size(); i++) {
T expr = exprList.get(i);
- T expr2 = (T) expr.accept(this);
+ T expr2 = (T) apply(expr); // Avoid NPE if expr is null
if (expr != expr2) {
++changeCount;
exprList.set(i, expr2);
@@ -232,6 +232,9 @@ public class RexShuttle implements RexVisitor<RexNode> {
* resulting list. Does not modify the initial list.
*/
public final <T extends RexNode> List<T> apply(List<T> exprList) {
+ if (exprList == null) {
+ return null;
+ }
final List<T> list2 = new ArrayList<T>(exprList);
if (mutate(list2)) {
return list2;
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/sql2rel/DeduplicateCorrelateVariables.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/DeduplicateCorrelateVariables.java b/core/src/main/java/org/apache/calcite/sql2rel/DeduplicateCorrelateVariables.java
index 206ed2b..2ce1048 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/DeduplicateCorrelateVariables.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/DeduplicateCorrelateVariables.java
@@ -16,24 +16,20 @@
*/
package org.apache.calcite.sql2rel;
+import org.apache.calcite.rel.RelHomogeneousShuttle;
import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.RelShuttleImpl;
-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.rex.RexBuilder;
import org.apache.calcite.rex.RexCorrelVariable;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexShuttle;
-import java.util.List;
import java.util.Set;
/**
* Rewrites relations to ensure the same correlation is referenced by the same
* correlation variable.
*/
-public class DeduplicateCorrelateVariables extends RelShuttleImpl {
+public class DeduplicateCorrelateVariables extends RelHomogeneousShuttle {
private final RexShuttle dedupRex;
/**
@@ -67,40 +63,9 @@ public class DeduplicateCorrelateVariables extends RelShuttleImpl {
canonical, altNames);
}
- @Override
- public RelNode visit(LogicalFilter filter) {
- LogicalFilter newFilter = (LogicalFilter) super.visit(filter);
- RexNode condition = filter.getCondition();
- RexNode newCondition = condition.accept(dedupRex);
- if (condition != newCondition) {
- return newFilter.copy(newFilter.getTraitSet(), newFilter.getInput(),
- newCondition);
- }
- return newFilter;
- }
-
- @Override
- public RelNode visit(LogicalProject project) {
- LogicalProject project2 = (LogicalProject) super.visit(project);
- List<RexNode> childExps = project2.getChildExps();
- List<RexNode> newExps = dedupRex.apply(childExps);
- if (childExps != newExps) {
- return project2.copy(project2.getTraitSet(), project2.getInput(),
- newExps, project2.getRowType());
- }
- return project2;
- }
-
- @Override
- public RelNode visit(LogicalJoin join) {
- LogicalJoin join2 = (LogicalJoin) super.visit(join);
- RexNode condition = join2.getCondition();
- RexNode newCondition = condition.accept(dedupRex);
- if (condition != newCondition) {
- return join2.copy(join2.getTraitSet(), newCondition, join2.getLeft(),
- join2.getRight(), join2.getJoinType(), join2.isSemiJoinDone());
- }
- return join2;
+ @Override public RelNode visit(RelNode other) {
+ RelNode next = super.visit(other);
+ return next.accept(dedupRex);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/288254b2/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java b/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java
index dbbfa3f..4bfe35b 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java
@@ -925,7 +925,9 @@ public class RelFieldTrimmer implements ReflectiveVisitor {
LogicalTableFunctionScan newTabFun = tabFun;
if (!tabFun.getInputs().equals(newInputs)) {
- newTabFun = tabFun.copy(tabFun.getTraitSet(), newInputs);
+ newTabFun = tabFun.copy(tabFun.getTraitSet(), newInputs,
+ tabFun.getCall(), tabFun.getElementType(), tabFun.getRowType(),
+ tabFun.getColumnMappings());
}
assert newTabFun.getClass() == tabFun.getClass();