You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by da...@apache.org on 2020/06/16 03:11:21 UTC
[calcite] branch master updated: [CALCITE-3786] Add Digest
interface to enable efficient hashCode(equals) for RexNode and RelNode
This is an automated email from the ASF dual-hosted git repository.
danny0405 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new 69f2586 [CALCITE-3786] Add Digest interface to enable efficient hashCode(equals) for RexNode and RelNode
69f2586 is described below
commit 69f25863f5f4197c17927a39a82cbf1cffd12b80
Author: yuzhao.cyz <yu...@gmail.com>
AuthorDate: Tue Jun 9 21:16:22 2020 +0800
[CALCITE-3786] Add Digest interface to enable efficient hashCode(equals) for RexNode and RelNode
* Add class Digest used to identify the node;
* There is a pre-computed hashcode to speedup #hashCode and #equals;
* Change RexCall to use object#equals instead of pure string digest
comparison;
* We only support RexInputRef normalization which is the most common
case;
* Remove RexNode#toStringRaw because it makes the thing complicated,
RexNode can always be normalized(default true).
---
.../org/apache/calcite/adapter/jdbc/JdbcRules.java | 2 +-
.../apache/calcite/plan/AbstractRelOptPlanner.java | 14 --
.../main/java/org/apache/calcite/plan/Digest.java | 256 +++++++++++++++++++++
.../plan/MaterializedViewSubstitutionVisitor.java | 2 +-
.../java/org/apache/calcite/plan/RelOptNode.java | 2 +-
.../java/org/apache/calcite/plan/RelOptUtil.java | 19 +-
.../org/apache/calcite/plan/hep/HepPlanner.java | 13 +-
.../org/apache/calcite/plan/hep/HepRelVertex.java | 5 +-
.../org/apache/calcite/plan/volcano/RelSubset.java | 10 +-
.../calcite/plan/volcano/VolcanoPlanner.java | 39 ++--
.../org/apache/calcite/rel/AbstractRelNode.java | 81 ++-----
.../main/java/org/apache/calcite/rel/RelNode.java | 3 +-
.../java/org/apache/calcite/rel/RelWriter.java | 15 --
.../java/org/apache/calcite/rel/core/Match.java | 10 +
.../java/org/apache/calcite/rel/core/Window.java | 22 +-
.../calcite/rel/externalize/RelJsonWriter.java | 5 +-
.../calcite/rel/externalize/RelWriterImpl.java | 21 +-
.../rel/metadata/RelMdExpressionLineage.java | 2 +-
.../calcite/rel/rel2sql/RelToSqlConverter.java | 4 +-
.../rel/rules/JoinProjectTransposeRule.java | 4 +-
.../rel/rules/ProjectWindowTransposeRule.java | 4 +-
.../materialize/MaterializedViewAggregateRule.java | 22 +-
.../materialize/MaterializedViewJoinRule.java | 4 +-
.../rules/materialize/MaterializedViewRule.java | 2 +-
.../main/java/org/apache/calcite/rex/RexCall.java | 148 +++++-------
.../main/java/org/apache/calcite/rex/RexNode.java | 63 +----
.../main/java/org/apache/calcite/rex/RexOver.java | 21 ++
.../java/org/apache/calcite/rex/RexSubQuery.java | 10 +
.../main/java/org/apache/calcite/sql/SqlKind.java | 19 ++
.../calcite/sql/fun/SqlStdOperatorTable.java | 20 ++
.../calcite/materialize/LatticeSuggesterTest.java | 4 +-
.../org/apache/calcite/plan/RelOptUtilTest.java | 8 +-
.../calcite/plan/volcano/TraitPropagationTest.java | 4 +-
.../calcite/plan/volcano/VolcanoPlannerTest.java | 10 +-
.../calcite/rel/rules/DateRangeRulesTest.java | 4 +-
.../calcite/rex/RexCallNormalizationTest.java | 76 +++---
.../org/apache/calcite/rex/RexProgramTest.java | 8 +-
.../org/apache/calcite/rex/RexProgramTestBase.java | 39 ++--
.../rex/RexSqlStandardConvertletTableTest.java | 6 +-
.../org/apache/calcite/test/HepPlannerTest.java | 6 +-
.../org/apache/calcite/test/JdbcAdapterTest.java | 4 +-
.../java/org/apache/calcite/test/LatticeTest.java | 6 +-
.../test/MaterializedViewRelOptRulesTest.java | 3 +-
.../MaterializedViewSubstitutionVisitorTest.java | 10 +-
.../org/apache/calcite/test/RelBuilderTest.java | 6 +-
.../org/apache/calcite/test/RelMetadataTest.java | 14 +-
.../org/apache/calcite/test/RelOptRulesTest.java | 2 +-
.../apache/calcite/test/RexTransformerTest.java | 4 +-
.../apache/calcite/test/SqlHintsConverterTest.java | 6 +-
.../test/enumerable/EnumerableCorrelateTest.java | 8 +-
.../org/apache/calcite/test/RelOptRulesTest.xml | 74 +++---
.../apache/calcite/test/SqlToRelConverterTest.xml | 24 +-
.../org/apache/calcite/test/TopDownOptTest.xml | 4 +-
core/src/test/resources/sql/blank.iq | 2 +-
core/src/test/resources/sql/sub-query.iq | 4 +-
.../apache/calcite/adapter/druid/DruidRules.java | 2 +-
.../calcite/piglet/PigToSqlAggregateRule.java | 6 +-
57 files changed, 664 insertions(+), 522 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
index 4b9b1b4..438781b 100644
--- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
+++ b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
@@ -523,7 +523,7 @@ public class JdbcRules {
private static boolean userDefinedFunctionInProject(Project project) {
CheckingUserDefinedFunctionVisitor visitor = new CheckingUserDefinedFunctionVisitor();
- for (RexNode node : project.getChildExps()) {
+ for (RexNode node : project.getProjects()) {
node.accept(visitor);
if (visitor.containsUserDefinedFunction()) {
return true;
diff --git a/core/src/main/java/org/apache/calcite/plan/AbstractRelOptPlanner.java b/core/src/main/java/org/apache/calcite/plan/AbstractRelOptPlanner.java
index cf350b6..08731a8 100644
--- a/core/src/main/java/org/apache/calcite/plan/AbstractRelOptPlanner.java
+++ b/core/src/main/java/org/apache/calcite/plan/AbstractRelOptPlanner.java
@@ -20,7 +20,6 @@ import org.apache.calcite.plan.volcano.RelSubset;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
-import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexExecutor;
import org.apache.calcite.util.CancelFlag;
import org.apache.calcite.util.Pair;
@@ -443,19 +442,6 @@ public abstract class AbstractRelOptPlanner implements RelOptPlanner {
});
}
- /** Computes the key for relational expression digest cache. */
- protected static Pair<String, List<RelDataType>> key(RelNode rel) {
- return key(rel.getDigest(), rel.getRowType());
- }
-
- /** Computes the key for relational expression digest cache. */
- protected static Pair<String, List<RelDataType>> key(String digest, RelDataType relType) {
- final List<RelDataType> v = relType.isStruct()
- ? Pair.right(relType.getFieldList())
- : Collections.singletonList(relType);
- return Pair.of(digest, v);
- }
-
/** Listener for counting the attempts of each rule. Only enabled under DEBUG level.*/
private class RuleAttemptsListener implements RelOptListener {
private long beforeTimestamp;
diff --git a/core/src/main/java/org/apache/calcite/plan/Digest.java b/core/src/main/java/org/apache/calcite/plan/Digest.java
new file mode 100644
index 0000000..494cb14
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/plan/Digest.java
@@ -0,0 +1,256 @@
+/*
+ * 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.hint.Hintable;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.util.Pair;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import javax.annotation.Nonnull;
+
+/**
+ * A short description of relational expression's type, inputs, and
+ * other properties. The digest uniquely identifies the node; another node
+ * is equivalent if and only if it has the same value.
+ *
+ * <p>Row type is part of the digest for the rare occasion that similar
+ * expressions have different types, e.g. variants of
+ * {@code Project(child=rel#1, a=null)} where a is a null INTEGER or a
+ * null VARCHAR(10). Row type is represented as fieldTypes only, so {@code RelNode}
+ * that differ with field names only are treated equal.
+ * For instance, {@code Project(input=rel#1,empid=$0)} and {@code Project(input=rel#1,deptno=$0)}
+ * are equal.
+ *
+ * <p>Computed by {@code org.apache.calcite.rel.AbstractRelNode#computeDigest},
+ * assigned by {@link org.apache.calcite.rel.AbstractRelNode#onRegister},
+ * returned by {@link org.apache.calcite.rel.AbstractRelNode#getDigest()}.
+ */
+public class Digest implements Comparable<Digest> {
+
+ //~ Instance fields --------------------------------------------------------
+
+ private final int hashCode;
+ private final List<Pair<String, Object>> items;
+ private final RelNode rel;
+
+ // Used for debugging, computed lazily.
+ private String digest = null;
+
+ //~ Constructors -----------------------------------------------------------
+
+ /**
+ * Creates a digest with given rel and properties.
+ *
+ * @param rel The rel
+ * @param items The properties, e.g. the inputs, the type, the traits and so on
+ */
+ private Digest(RelNode rel, List<Pair<String, Object>> items) {
+ this.rel = rel;
+ this.items = normalizeContents(items);
+ this.hashCode = computeIdentity(rel, this.items);
+ }
+
+ /**
+ * Creates a digest with given rel, the digest is computed as simple,
+ * see {@link #simpleRelDigest(RelNode)}.
+ */
+ private Digest(RelNode rel) {
+ this(rel, simpleRelDigest(rel));
+ }
+
+ /** Creates a digest with given rel and string format digest. */
+ private Digest(RelNode rel, String digest) {
+ this.rel = rel;
+ this.items = Collections.emptyList();
+ this.digest = digest;
+ this.hashCode = this.digest.hashCode();
+ }
+
+ /** Returns the identity of this digest which is used to speedup hashCode and equals. */
+ private static int computeIdentity(RelNode rel, List<Pair<String, Object>> contents) {
+ return Objects.hash(collect(rel, contents, false));
+ }
+
+ /**
+ * Collects the items used for {@link #hashCode} and {@link #equals}.
+ *
+ * <p>Generally, the items used for hashCode and equals should be the same. The exception
+ * is the row type of the relational expression: the row type is needed because during
+ * planning, new equivalent rels may be produced with changed fields nullability
+ * (i.e. most of them comes from the rex simplify or constant reduction).
+ * This expects to be rare case, so the hashcode is computed without row type
+ * but when it conflicts, we compare with the row type involved(sans field names).
+ *
+ * @param rel The rel to compute digest
+ * @param contents The rel properties should be considered in digest
+ * @param withType Whether to involve the row type
+ */
+ private static Object[] collect(
+ RelNode rel,
+ List<Pair<String, Object>> contents,
+ boolean withType) {
+ List<Object> hashCodeItems = new ArrayList<>();
+ // The type name.
+ hashCodeItems.add(rel.getRelTypeName());
+ // The traits.
+ hashCodeItems.addAll(rel.getTraitSet());
+ // The hints.
+ if (rel instanceof Hintable) {
+ hashCodeItems.addAll(((Hintable) rel).getHints());
+ }
+ if (withType) {
+ // The row type sans field names.
+ RelDataType relType = rel.getRowType();
+ if (relType.isStruct()) {
+ hashCodeItems.addAll(Pair.right(relType.getFieldList()));
+ } else {
+ // Make a decision here because
+ // some downstream projects have custom rel type which has no explicit fields.
+ hashCodeItems.add(relType);
+ }
+ }
+ // The rel node contents(e.g. the inputs or exprs).
+ hashCodeItems.addAll(contents);
+ return hashCodeItems.toArray();
+ }
+
+ /** Normalizes the rel node properties, currently, just to replace the
+ * {@link RelNode} with a simple string format digest. **/
+ private static List<Pair<String, Object>> normalizeContents(
+ List<Pair<String, Object>> items) {
+ List<Pair<String, Object>> normalized = new ArrayList<>();
+ for (Pair<String, Object> item : items) {
+ if (item.right instanceof RelNode) {
+ RelNode input = (RelNode) item.right;
+ normalized.add(Pair.of(item.left, simpleRelDigest(input)));
+ } else {
+ normalized.add(item);
+ }
+ }
+ return normalized;
+ }
+
+ /**
+ * Returns a simple string format digest.
+ *
+ * <p>Currently, returns composition of class name and id.
+ *
+ * @param rel The rel
+ */
+ private static String simpleRelDigest(RelNode rel) {
+ return rel.getRelTypeName() + '#' + rel.getId();
+ }
+
+ @Override public String toString() {
+ if (null != digest) {
+ return digest;
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append(rel.getRelTypeName());
+
+ for (RelTrait trait : rel.getTraitSet()) {
+ sb.append('.');
+ sb.append(trait.toString());
+ }
+
+ sb.append('(');
+ int j = 0;
+ for (Pair<String, Object> item : items) {
+ if (j++ > 0) {
+ sb.append(',');
+ }
+ sb.append(item.left);
+ sb.append('=');
+ sb.append(item.right);
+ }
+ sb.append(')');
+ digest = sb.toString();
+ return digest;
+ }
+
+ @Override public int compareTo(@Nonnull Digest other) {
+ return this.equals(other) ? 0 : this.rel.getId() - other.rel.getId();
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Digest that = (Digest) o;
+ return hashCode == that.hashCode && deepEquals(that);
+ }
+
+ /**
+ * The method is used to resolve hash conflict, in current 6000+ tests, there are about 8
+ * tests with conflict, so we do not cache the hash code items in order to
+ * reduce mem consumption.
+ */
+ private boolean deepEquals(Digest other) {
+ Object[] thisItems = collect(this.rel, this.items, true);
+ Object[] thatItems = collect(other.rel, other.items, true);
+ if (thisItems.length != thatItems.length) {
+ return false;
+ }
+ for (int i = 0; i < thisItems.length; i++) {
+ if (!Objects.equals(thisItems[i], thatItems[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override public int hashCode() {
+ return hashCode;
+ }
+
+ /**
+ * Creates a digest with given rel and properties.
+ */
+ public static Digest create(RelNode rel, List<Pair<String, Object>> contents) {
+ return new Digest(rel, contents);
+ }
+
+ /**
+ * Creates a digest with given rel.
+ */
+ public static Digest create(RelNode rel) {
+ return new Digest(rel);
+ }
+
+ /**
+ * Creates a digest with given rel and string format digest
+ */
+ public static Digest create(RelNode rel, String digest) {
+ return new Digest(rel, digest);
+ }
+
+ /**
+ * Instantiates a digest with solid string format digest, this digest should only
+ * be used as a initial.
+ */
+ public static Digest initial(RelNode rel) {
+ return new Digest(rel, simpleRelDigest(rel));
+ }
+}
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 0ddee54..cc3692c 100644
--- a/core/src/main/java/org/apache/calcite/plan/MaterializedViewSubstitutionVisitor.java
+++ b/core/src/main/java/org/apache/calcite/plan/MaterializedViewSubstitutionVisitor.java
@@ -22,7 +22,7 @@ import org.apache.calcite.tools.RelBuilderFactory;
/**
* Extension to {@link SubstitutionVisitor}.
*/
-@Deprecated // Kept for backward compatibility and to be removed before 2.0
+@Deprecated // to be removed before 2.0
public class MaterializedViewSubstitutionVisitor extends SubstitutionVisitor {
public MaterializedViewSubstitutionVisitor(RelNode target_, RelNode query_) {
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptNode.java b/core/src/main/java/org/apache/calcite/plan/RelOptNode.java
index 2a0f077..8484f54 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptNode.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptNode.java
@@ -47,7 +47,7 @@ public interface RelOptNode {
*
* @return Digest of this {@code RelNode}
*/
- String getDigest();
+ Digest getDigest();
/**
* Retrieves this RelNode's traits. Note that although the RelTraitSet
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 8ace22d..1083047 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -182,20 +182,14 @@ public abstract class RelOptUtil {
* Whether this node contains a limit specification.
*/
public static boolean isLimit(RelNode rel) {
- if ((rel instanceof Sort) && ((Sort) rel).fetch != null) {
- return true;
- }
- return false;
+ return (rel instanceof Sort) && ((Sort) rel).fetch != null;
}
/**
* Whether this node contains a sort specification.
*/
public static boolean isOrder(RelNode rel) {
- if ((rel instanceof Sort) && !((Sort) rel).getCollation().getFieldCollations().isEmpty()) {
- return true;
- }
- return false;
+ return (rel instanceof Sort) && !((Sort) rel).getCollation().getFieldCollations().isEmpty();
}
/**
@@ -227,8 +221,9 @@ public abstract class RelOptUtil {
* or its children.
*/
public static List<String> findAllTableQualifiedNames(RelNode rel) {
- return Lists.transform(findAllTables(rel),
- table -> table.getQualifiedName().toString());
+ return findAllTables(rel).stream()
+ .map(table -> table.getQualifiedName().toString())
+ .collect(Collectors.toList());
}
/**
@@ -3802,7 +3797,7 @@ public abstract class RelOptUtil {
return true;
}
final RexImplicationChecker checker =
- new RexImplicationChecker(rexBuilder, (RexExecutorImpl) executor,
+ new RexImplicationChecker(rexBuilder, executor,
rowType);
final RexNode first =
RexUtil.composeConjunction(rexBuilder, predicates.pulledUpPredicates);
@@ -4185,7 +4180,6 @@ public abstract class RelOptUtil {
/** Converts types to descriptive strings. */
public static class TypeDumper {
- private final String extraIndent = " ";
private String indent;
private final PrintWriter pw;
@@ -4203,6 +4197,7 @@ public abstract class RelOptUtil {
// J VARCHAR(240))
pw.println("RECORD (");
String prevIndent = indent;
+ String extraIndent = " ";
this.indent = indent + extraIndent;
acceptFields(fields);
this.indent = prevIndent;
diff --git a/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java b/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java
index 44b4fb8..36bd186 100644
--- a/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java
+++ b/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java
@@ -21,6 +21,7 @@ import org.apache.calcite.linq4j.function.Functions;
import org.apache.calcite.plan.AbstractRelOptPlanner;
import org.apache.calcite.plan.CommonRelSubExprRule;
import org.apache.calcite.plan.Context;
+import org.apache.calcite.plan.Digest;
import org.apache.calcite.plan.RelOptCost;
import org.apache.calcite.plan.RelOptCostFactory;
import org.apache.calcite.plan.RelOptCostImpl;
@@ -84,7 +85,7 @@ public class HepPlanner extends AbstractRelOptPlanner {
* {@link RelDataType} is represented with its field types as {@code List<RelDataType>}.
* This enables to treat as equal projects that differ in expression names only.
*/
- private final Map<Pair<String, List<RelDataType>>, HepRelVertex> mapDigestToVertex =
+ private final Map<Digest, HepRelVertex> mapDigestToVertex =
new HashMap<>();
private int nTransformations;
@@ -810,8 +811,7 @@ public class HepPlanner extends AbstractRelOptPlanner {
// try to find equivalent rel only if DAG is allowed
if (!noDag) {
// Now, check if an equivalent vertex already exists in graph.
- Pair<String, List<RelDataType>> key = key(rel);
- HepRelVertex equivVertex = mapDigestToVertex.get(key);
+ HepRelVertex equivVertex = mapDigestToVertex.get(rel.getDigest());
if (equivVertex != null) {
// Use existing vertex.
return equivVertex;
@@ -900,7 +900,7 @@ public class HepPlanner extends AbstractRelOptPlanner {
// reachable from here.
notifyDiscard(vertex.getCurrentRel());
}
- Pair<String, List<RelDataType>> oldKey = key(vertex.getCurrentRel());
+ Digest oldKey = vertex.getCurrentRel().getDigest();
if (mapDigestToVertex.get(oldKey) == vertex) {
mapDigestToVertex.remove(oldKey);
}
@@ -911,8 +911,7 @@ public class HepPlanner extends AbstractRelOptPlanner {
// otherwise the digest will be removed wrongly in the mapDigestToVertex
// when collectGC
// so it must update the digest that map to vertex
- Pair<String, List<RelDataType>> newKey = key(rel);
- mapDigestToVertex.put(newKey, vertex);
+ mapDigestToVertex.put(rel.getDigest(), vertex);
if (rel != vertex.getCurrentRel()) {
vertex.replaceRel(rel);
}
@@ -978,7 +977,7 @@ public class HepPlanner extends AbstractRelOptPlanner {
graphSizeLastGC = graph.vertexSet().size();
// Clean up digest map too.
- Iterator<Map.Entry<Pair<String, List<RelDataType>>, HepRelVertex>> digestIter =
+ Iterator<Map.Entry<Digest, HepRelVertex>> digestIter =
mapDigestToVertex.entrySet().iterator();
while (digestIter.hasNext()) {
HepRelVertex vertex = digestIter.next().getValue();
diff --git a/core/src/main/java/org/apache/calcite/plan/hep/HepRelVertex.java b/core/src/main/java/org/apache/calcite/plan/hep/HepRelVertex.java
index 6ec8a6c..92394b1 100644
--- a/core/src/main/java/org/apache/calcite/plan/hep/HepRelVertex.java
+++ b/core/src/main/java/org/apache/calcite/plan/hep/HepRelVertex.java
@@ -16,6 +16,7 @@
*/
package org.apache.calcite.plan.hep;
+import org.apache.calcite.plan.Digest;
import org.apache.calcite.plan.RelOptCost;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelTraitSet;
@@ -75,8 +76,8 @@ public class HepRelVertex extends AbstractRelNode {
return currentRel.getRowType();
}
- @Override protected String computeDigest() {
- return "HepRelVertex(" + currentRel + ")";
+ @Override protected Digest computeDigest() {
+ return Digest.create(this, getRelTypeName() + '#' + getCurrentRel().getId());
}
/**
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java b/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
index 8b0a78a..e821496 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
@@ -17,6 +17,7 @@
package org.apache.calcite.plan.volcano;
import org.apache.calcite.linq4j.Linq4j;
+import org.apache.calcite.plan.Digest;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptCost;
import org.apache.calcite.plan.RelOptListener;
@@ -224,13 +225,14 @@ public class RelSubset extends AbstractRelNode {
pw.done(input);
}
- @Override protected String computeDigest() {
- StringBuilder digest = new StringBuilder("Subset#");
+ @Override protected Digest computeDigest() {
+ StringBuilder digest = new StringBuilder(getRelTypeName());
+ digest.append('#');
digest.append(set.id);
- for (RelTrait trait : traitSet) {
+ for (RelTrait trait : getTraitSet()) {
digest.append('.').append(trait);
}
- return digest.toString();
+ return Digest.create(this, digest.toString());
}
@Override protected RelDataType deriveRowType() {
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
index 8374f1b..4842932 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
@@ -22,6 +22,7 @@ import org.apache.calcite.plan.AbstractRelOptPlanner;
import org.apache.calcite.plan.Context;
import org.apache.calcite.plan.Convention;
import org.apache.calcite.plan.ConventionTraitDef;
+import org.apache.calcite.plan.Digest;
import org.apache.calcite.plan.RelOptCost;
import org.apache.calcite.plan.RelOptCostFactory;
import org.apache.calcite.plan.RelOptLattice;
@@ -48,7 +49,6 @@ import org.apache.calcite.rel.metadata.RelMdUtil;
import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.rules.TransformationRule;
-import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.runtime.Hook;
import org.apache.calcite.sql.SqlExplainLevel;
import org.apache.calcite.util.Litmus;
@@ -102,17 +102,8 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
/**
* Canonical map from {@link String digest} to the unique
* {@link RelNode relational expression} with that digest.
- *
- * <p>Row type is part of the key for the rare occasion that similar
- * expressions have different types, e.g. variants of
- * {@code Project(child=rel#1, a=null)} where a is a null INTEGER or a
- * null VARCHAR(10).</p>
- * <p>Row type is represented as fieldTypes only, so {@code RelNode} that differ
- * with field names only are treated equal.
- * For instance, {@code Project(input=rel#1,empid=$0)} and {@code Project(input=rel#1,deptno=$0)}
- * are equal</p>
*/
- private final Map<Pair<String, List<RelDataType>>, RelNode> mapDigestToRel =
+ private final Map<Digest, RelNode> mapDigestToRel =
new HashMap<>();
/**
@@ -898,15 +889,13 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
* @param rel Relational expression
*/
void rename(RelNode rel) {
- final String oldDigest = rel.getDigest();
+ final Digest oldDigest = rel.getDigest();
if (fixUpInputs(rel)) {
- final Pair<String, List<RelDataType>> oldKey = key(oldDigest, rel.getRowType());
- final RelNode removed = mapDigestToRel.remove(oldKey);
+ final RelNode removed = mapDigestToRel.remove(oldDigest);
assert removed == rel;
- final String newDigest = rel.recomputeDigest();
+ final Digest newDigest = rel.recomputeDigest();
LOGGER.trace("Rename #{} from '{}' to '{}'", rel.getId(), oldDigest, newDigest);
- final Pair<String, List<RelDataType>> key = key(rel);
- final RelNode equivRel = mapDigestToRel.put(key, rel);
+ final RelNode equivRel = mapDigestToRel.put(newDigest, rel);
if (equivRel != null) {
assert equivRel != rel;
@@ -915,7 +904,7 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
LOGGER.trace("After renaming rel#{} it is now equivalent to rel#{}",
rel.getId(), equivRel.getId());
- mapDigestToRel.put(key, equivRel);
+ mapDigestToRel.put(newDigest, equivRel);
checkPruned(equivRel, rel);
RelSubset equivRelSubset = getSubset(equivRel);
@@ -970,8 +959,7 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
// Is there an equivalent relational expression? (This might have
// just occurred because the relational expression's child was just
// found to be equivalent to another set.)
- final Pair<String, List<RelDataType>> key = key(rel);
- RelNode equivRel = mapDigestToRel.get(key);
+ RelNode equivRel = mapDigestToRel.get(rel.getDigest());
if (equivRel != null && equivRel != rel) {
assert equivRel.getClass() == rel.getClass();
assert equivRel.getTraitSet().equals(rel.getTraitSet());
@@ -1180,8 +1168,8 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
// If it is equivalent to an existing expression, return the set that
// the equivalent expression belongs to.
- Pair<String, List<RelDataType>> key = key(rel);
- RelNode equivExp = mapDigestToRel.get(key);
+ Digest digest = rel.getDigest();
+ RelNode equivExp = mapDigestToRel.get(digest);
if (equivExp == null) {
// do nothing
} else if (equivExp == rel) {
@@ -1218,9 +1206,8 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
// check whether we are now equivalent to an existing
// expression.
if (fixUpInputs(rel)) {
- rel.recomputeDigest();
- key = key(rel);
- RelNode equivRel = mapDigestToRel.get(key);
+ digest = rel.recomputeDigest();
+ RelNode equivRel = mapDigestToRel.get(digest);
if ((equivRel != rel) && (equivRel != null)) {
// make sure this bad rel didn't get into the
@@ -1261,7 +1248,7 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
final int subsetBeforeCount = set.subsets.size();
RelSubset subset = addRelToSet(rel, set);
- final RelNode xx = mapDigestToRel.put(key, rel);
+ final RelNode xx = mapDigestToRel.put(digest, rel);
assert xx == null || xx == rel : rel.getDigest();
LOGGER.trace("Register {} in {}", rel, subset);
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 8240c60..c5ec873 100644
--- a/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
+++ b/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
@@ -18,13 +18,13 @@ package org.apache.calcite.rel;
import org.apache.calcite.plan.Convention;
import org.apache.calcite.plan.ConventionTraitDef;
+import org.apache.calcite.plan.Digest;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptCost;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptQuery;
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.RelOptUtil;
-import org.apache.calcite.plan.RelTrait;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.metadata.Metadata;
@@ -70,13 +70,9 @@ public abstract class AbstractRelNode implements RelNode {
protected RelDataType rowType;
/**
- * A short description of this relational expression's type, inputs, and
- * other properties. The string uniquely identifies the node; another node
- * is equivalent if and only if it has the same value. Computed by
- * {@link #computeDigest}, assigned by {@link #onRegister}, returned by
- * {@link #getDigest()}.
+ * The digest that uniquely identifies the node.
*/
- protected String digest;
+ protected Digest digest;
private final RelOptCluster cluster;
@@ -101,7 +97,7 @@ public abstract class AbstractRelNode implements RelNode {
this.cluster = cluster;
this.traitSet = traitSet;
this.id = NEXT_ID.getAndIncrement();
- this.digest = getRelTypeName() + "#" + id;
+ this.digest = Digest.initial(this);
LOGGER.trace("new {}", digest);
}
@@ -148,13 +144,13 @@ public abstract class AbstractRelNode implements RelNode {
return null;
}
- @SuppressWarnings("deprecation")
+ @Deprecated // to be removed before 1.25
public boolean isDistinct() {
final RelMetadataQuery mq = cluster.getMetadataQuery();
return Boolean.TRUE.equals(mq.areRowsUnique(this));
}
- @SuppressWarnings("deprecation")
+ @Deprecated // to be removed before 1.25
public boolean isKey(ImmutableBitSet columns) {
final RelMetadataQuery mq = cluster.getMetadataQuery();
return Boolean.TRUE.equals(mq.areColumnsUnique(this, columns));
@@ -169,7 +165,7 @@ public abstract class AbstractRelNode implements RelNode {
return inputs.get(i);
}
- @SuppressWarnings("deprecation")
+ @Deprecated // to be removed before 1.25
public final RelOptQuery getQuery() {
return getCluster().getQuery();
}
@@ -193,7 +189,7 @@ public abstract class AbstractRelNode implements RelNode {
return litmus.succeed();
}
- @SuppressWarnings("deprecation")
+ @Deprecated // to be removed before 1.25
public boolean isValid(boolean fail) {
return isValid(Litmus.THROW, null);
}
@@ -226,7 +222,7 @@ public abstract class AbstractRelNode implements RelNode {
return Collections.emptyList();
}
- @SuppressWarnings("deprecation")
+ @Deprecated // to be removed before 1.25
public final double getRows() {
return estimateRowCount(cluster.getMetadataQuery());
}
@@ -235,7 +231,7 @@ public abstract class AbstractRelNode implements RelNode {
return 1.0;
}
- @SuppressWarnings("deprecation")
+ @Deprecated // to be removed before 1.25
public final Set<String> getVariablesStopped() {
return CorrelationId.names(getVariablesSet());
}
@@ -281,7 +277,6 @@ public abstract class AbstractRelNode implements RelNode {
RelMetadataQuery mq) {
// by default, assume cost is proportional to number of rows
double rowCount = mq.getRowCount(this);
- double bytesPerRow = 1;
return planner.getCostFactory().makeCost(rowCount, rowCount, 0);
}
@@ -323,15 +318,11 @@ public abstract class AbstractRelNode implements RelNode {
List<RelNode> inputs = new ArrayList<>(oldInputs.size());
for (final RelNode input : oldInputs) {
RelNode e = planner.ensureRegistered(input, null);
- if (e != input) {
- // TODO: change 'equal' to 'eq', which is stronger.
- assert RelOptUtil.equal(
- "rowtype of rel before registration",
- input.getRowType(),
- "rowtype of rel after registration",
- e.getRowType(),
- Litmus.THROW);
- }
+ assert e == input || RelOptUtil.equal("rowtype of rel before registration",
+ input.getRowType(),
+ "rowtype of rel after registration",
+ e.getRowType(),
+ Litmus.THROW);
inputs.add(e);
}
RelNode r = this;
@@ -343,7 +334,7 @@ public abstract class AbstractRelNode implements RelNode {
return r;
}
- public String recomputeDigest() {
+ public Digest recomputeDigest() {
digest = computeDigest();
assert digest != null : "computeDigest() should be non-null";
return digest;
@@ -355,20 +346,20 @@ public abstract class AbstractRelNode implements RelNode {
throw new UnsupportedOperationException("replaceInput called on " + this);
}
- /* Description, consists of id plus digest */
+ /** Description, consists of id plus digest */
public String toString() {
StringBuilder sb = new StringBuilder();
- sb = RelOptUtil.appendRelDescription(sb, this);
+ RelOptUtil.appendRelDescription(sb, this);
return sb.toString();
}
- /* Description, consists of id plus digest */
+ /** Description, consists of id plus digest */
@Deprecated // to be removed before 2.0
public final String getDescription() {
return this.toString();
}
- public final String getDigest() {
+ public final Digest getDigest() {
return digest;
}
@@ -381,7 +372,7 @@ public abstract class AbstractRelNode implements RelNode {
*
* @return Digest
*/
- protected String computeDigest() {
+ protected Digest computeDigest() {
RelDigestWriter rdw = new RelDigestWriter();
explain(rdw);
return rdw.digest;
@@ -421,7 +412,7 @@ public abstract class AbstractRelNode implements RelNode {
private final List<Pair<String, Object>> values = new ArrayList<>();
- String digest = null;
+ Digest digest = null;
@Override public void explain(final RelNode rel, final List<Pair<String, Object>> valueList) {
throw new IllegalStateException("Should not be called for computing digest");
@@ -437,33 +428,7 @@ public abstract class AbstractRelNode implements RelNode {
}
@Override public RelWriter done(RelNode node) {
- StringBuilder sb = new StringBuilder();
- sb.append(node.getRelTypeName());
-
- for (RelTrait trait : node.getTraitSet()) {
- sb.append('.');
- sb.append(trait.toString());
- }
-
- sb.append('(');
- int j = 0;
- for (Pair<String, Object> value : values) {
- if (j++ > 0) {
- sb.append(',');
- }
- sb.append(value.left);
- sb.append('=');
- if (value.right instanceof RelNode) {
- RelNode input = (RelNode) value.right;
- sb.append(input.getRelTypeName());
- sb.append('#');
- sb.append(input.getId());
- } else {
- sb.append(value.right);
- }
- }
- sb.append(')');
- digest = sb.toString();
+ digest = Digest.create(node, values);
return this;
}
}
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 11c35ef..18ff76f 100644
--- a/core/src/main/java/org/apache/calcite/rel/RelNode.java
+++ b/core/src/main/java/org/apache/calcite/rel/RelNode.java
@@ -17,6 +17,7 @@
package org.apache.calcite.rel;
import org.apache.calcite.plan.Convention;
+import org.apache.calcite.plan.Digest;
import org.apache.calcite.plan.RelOptCost;
import org.apache.calcite.plan.RelOptNode;
import org.apache.calcite.plan.RelOptPlanner;
@@ -308,7 +309,7 @@ public interface RelNode extends RelOptNode, Cloneable {
*
* @return Digest of this relational expression
*/
- String recomputeDigest();
+ Digest recomputeDigest();
/**
* Replaces the <code>ordinalInParent</code><sup>th</sup> input. You must
diff --git a/core/src/main/java/org/apache/calcite/rel/RelWriter.java b/core/src/main/java/org/apache/calcite/rel/RelWriter.java
index 4f6d114..92f78b6 100644
--- a/core/src/main/java/org/apache/calcite/rel/RelWriter.java
+++ b/core/src/main/java/org/apache/calcite/rel/RelWriter.java
@@ -16,12 +16,9 @@
*/
package org.apache.calcite.rel;
-import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SqlExplainLevel;
import org.apache.calcite.util.Pair;
-import org.apiguardian.api.API;
-
import java.util.List;
/**
@@ -88,16 +85,4 @@ public interface RelWriter {
default boolean nest() {
return false;
}
-
- /**
- * Activates {@link RexNode} normalization if {@link SqlExplainLevel#DIGEST_ATTRIBUTES} is used.
- * Note: the returned value must be closed, and the API is designed to be used with a
- * try-with-resources.
- * @return a handle that should be closed to revert normalization state
- */
- @API(since = "1.22", status = API.Status.EXPERIMENTAL)
- default RexNode.Closeable withRexNormalize() {
- boolean needNormalize = getDetailLevel() == SqlExplainLevel.DIGEST_ATTRIBUTES;
- return RexNode.withNormalize(needNormalize);
- }
}
diff --git a/core/src/main/java/org/apache/calcite/rel/core/Match.java b/core/src/main/java/org/apache/calcite/rel/core/Match.java
index 12fe3b9..4b1a5ca 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/Match.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/Match.java
@@ -332,5 +332,15 @@ public abstract class Match extends SingleRel {
@Override public int compareTo(RexMRAggCall o) {
return toString().compareTo(o.toString());
}
+
+ @Override public boolean equals(Object obj) {
+ return obj == this
+ || obj instanceof RexMRAggCall
+ && toString().equals(obj.toString());
+ }
+
+ @Override public int hashCode() {
+ return toString().hashCode();
+ }
}
}
diff --git a/core/src/main/java/org/apache/calcite/rel/core/Window.java b/core/src/main/java/org/apache/calcite/rel/core/Window.java
index 71176e5..620afe6 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/Window.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/Window.java
@@ -394,16 +394,24 @@ public abstract class Window extends SingleRel {
this.ignoreNulls = ignoreNulls;
}
- /** {@inheritDoc}
- *
- * <p>Override {@link RexCall}, defining equality based on identity.
- */
- @Override public boolean equals(Object obj) {
- return this == obj;
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ RexWinAggCall that = (RexWinAggCall) o;
+ return ordinal == that.ordinal
+ && distinct == that.distinct
+ && ignoreNulls == that.ignoreNulls;
}
@Override public int hashCode() {
- return Objects.hash(digest, ordinal, distinct);
+ return Objects.hash(super.hashCode(), ordinal, distinct, ignoreNulls);
}
@Override public RexCall clone(RelDataType type, List<RexNode> operands) {
diff --git a/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java b/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java
index acdd2cf..5b6a346 100644
--- a/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java
+++ b/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java
@@ -18,7 +18,6 @@ package org.apache.calcite.rel.externalize;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelWriter;
-import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SqlExplainLevel;
import org.apache.calcite.util.JsonBuilder;
import org.apache.calcite.util.Pair;
@@ -141,8 +140,6 @@ public class RelJsonWriter implements RelWriter {
public String asString() {
final Map<String, Object> map = jsonBuilder.map();
map.put("rels", relList);
- try (RexNode.Closeable ignored = withRexNormalize()) {
- return jsonBuilder.toJsonString(map);
- }
+ return jsonBuilder.toJsonString(map);
}
}
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 02eec8b..3fd1ebc 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;
@@ -125,9 +124,7 @@ public class RelWriterImpl implements RelWriter {
}
public final void explain(RelNode rel, List<Pair<String, Object>> valueList) {
- try (RexNode.Closeable ignored = withRexNormalize()) {
- explain_(rel, valueList);
- }
+ explain_(rel, valueList);
}
public SqlExplainLevel getDetailLevel() {
@@ -144,9 +141,7 @@ public class RelWriterImpl implements RelWriter {
final List<Pair<String, Object>> valuesCopy =
ImmutableList.copyOf(values);
values.clear();
- try (RexNode.Closeable ignored = withRexNormalize()) {
- explain_(node, valuesCopy);
- }
+ explain_(node, valuesCopy);
pw.flush();
return this;
}
@@ -169,15 +164,13 @@ public class RelWriterImpl implements RelWriter {
*/
public String simple() {
final StringBuilder buf = new StringBuilder("(");
- try (RexNode.Closeable ignored = withRexNormalize()) {
- for (Ord<Pair<String, Object>> ord : Ord.zip(values)) {
- if (ord.i > 0) {
- buf.append(", ");
- }
- buf.append(ord.e.left).append("=[").append(ord.e.right).append("]");
+ for (Ord<Pair<String, Object>> ord : Ord.zip(values)) {
+ if (ord.i > 0) {
+ buf.append(", ");
}
- buf.append(")");
+ buf.append(ord.e.left).append("=[").append(ord.e.right).append("]");
}
+ buf.append(")");
return buf.toString();
}
}
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
index 7f495b1..6aba8b3 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
@@ -361,7 +361,7 @@ public class RelMdExpressionLineage
// Infer column origin expressions for given references
final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>();
for (int idx : inputFieldsUsed) {
- final RexNode inputExpr = rel.getChildExps().get(idx);
+ final RexNode inputExpr = rel.getProjects().get(idx);
final Set<RexNode> originalExprs = mq.getExpressionLineage(input, inputExpr);
if (originalExprs == null) {
// Bail out
diff --git a/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java b/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
index a4fcd42..083e5e1 100644
--- a/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
+++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
@@ -326,13 +326,13 @@ public class RelToSqlConverter extends SqlImplementor
e.getVariablesSet();
Result x = visitChild(0, e.getInput());
parseCorrelTable(e, x);
- if (isStar(e.getChildExps(), e.getInput().getRowType(), e.getRowType())) {
+ if (isStar(e.getProjects(), e.getInput().getRowType(), e.getRowType())) {
return x;
}
final Builder builder =
x.builder(e, Clause.SELECT);
final List<SqlNode> selectList = new ArrayList<>();
- for (RexNode ref : e.getChildExps()) {
+ for (RexNode ref : e.getProjects()) {
SqlNode sqlExpr = builder.context.toSql(null, ref);
if (SqlUtil.isNullLiteral(sqlExpr, false)) {
sqlExpr = castNullType(sqlExpr, e.getRowType().getFieldList().get(selectList.size()));
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java
index 085b3e6..b3104dc 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java
@@ -171,11 +171,11 @@ public class JoinProjectTransposeRule extends RelOptRule implements Transformati
}
// Skip projects containing over clause
- if (leftProj != null && RexOver.containsOver(leftProj.getChildExps(), null)) {
+ if (leftProj != null && RexOver.containsOver(leftProj.getProjects(), null)) {
leftProj = null;
leftJoinChild = joinRel.getLeft();
}
- if (rightProj != null && RexOver.containsOver(rightProj.getChildExps(), null)) {
+ if (rightProj != null && RexOver.containsOver(rightProj.getProjects(), null)) {
rightProj = null;
rightJoinChild = joinRel.getRight();
}
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java
index 74b9a96..de52288 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ProjectWindowTransposeRule.java
@@ -174,7 +174,7 @@ public class ProjectWindowTransposeRule extends RelOptRule implements Transforma
// Modify the top LogicalProject
final List<RexNode> topProjExps =
- indexAdjustment.visitList(project.getChildExps());
+ indexAdjustment.visitList(project.getProjects());
final LogicalProject newTopProj = project.copy(
newLogicalWindow.getTraitSet(),
@@ -205,7 +205,7 @@ public class ProjectWindowTransposeRule extends RelOptRule implements Transforma
};
// Reference in LogicalProject
- referenceFinder.visitEach(project.getChildExps());
+ referenceFinder.visitEach(project.getProjects());
// Reference in LogicalWindow
for (Window.Group group : window.groups) {
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewAggregateRule.java b/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewAggregateRule.java
index f4c318d..9ccacf6 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewAggregateRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewAggregateRule.java
@@ -225,9 +225,9 @@ public abstract class MaterializedViewAggregateRule extends MaterializedViewRule
0, 0, aggregateViewNode.getGroupCount(),
newViewNode.getGroupCount(), aggregateViewNode.getGroupCount(),
aggregateViewNode.getAggCallList().size());
- for (int i = 0; i < topViewProject.getChildExps().size(); i++) {
+ for (int i = 0; i < topViewProject.getProjects().size(); i++) {
nodes.add(
- topViewProject.getChildExps().get(i).accept(
+ topViewProject.getProjects().get(i).accept(
new RexPermuteInputsShuttle(shiftMapping, newViewNode)));
fieldNames.add(topViewProject.getRowType().getFieldNames().get(i));
}
@@ -414,7 +414,7 @@ public abstract class MaterializedViewAggregateRule extends MaterializedViewRule
// We have a Project on top, gather only what is needed
final RelOptUtil.InputFinder inputFinder =
new RelOptUtil.InputFinder(new LinkedHashSet<>());
- inputFinder.visitEach(topProject.getChildExps());
+ inputFinder.visitEach(topProject.getProjects());
references = inputFinder.build();
for (int i = 0; i < queryAggregate.getGroupCount(); i++) {
indexes.set(queryAggregate.getGroupSet().nth(i));
@@ -561,8 +561,8 @@ public abstract class MaterializedViewAggregateRule extends MaterializedViewRule
final ImmutableBitSet refs = RelOptUtil.InputFinder.bits(targetNode);
for (int childTargetIdx : refs) {
added = false;
- for (int k = 0; k < topViewProject.getChildExps().size() && !added; k++) {
- RexNode n = topViewProject.getChildExps().get(k);
+ for (int k = 0; k < topViewProject.getProjects().size() && !added; k++) {
+ RexNode n = topViewProject.getProjects().get(k);
if (!n.isA(SqlKind.INPUT_REF)) {
continue;
}
@@ -589,8 +589,8 @@ public abstract class MaterializedViewAggregateRule extends MaterializedViewRule
added = true;
} else {
// This expression should be referenced directly
- for (int k = 0; k < topViewProject.getChildExps().size() && !added; k++) {
- RexNode n = topViewProject.getChildExps().get(k);
+ for (int k = 0; k < topViewProject.getProjects().size() && !added; k++) {
+ RexNode n = topViewProject.getProjects().get(k);
if (!n.isA(SqlKind.INPUT_REF)) {
continue;
}
@@ -623,8 +623,8 @@ public abstract class MaterializedViewAggregateRule extends MaterializedViewRule
}
AggregateCall queryAggCall = queryAggregate.getAggCallList().get(i);
boolean added = false;
- for (int k = 0; k < topViewProject.getChildExps().size() && !added; k++) {
- RexNode n = topViewProject.getChildExps().get(k);
+ for (int k = 0; k < topViewProject.getProjects().size() && !added; k++) {
+ RexNode n = topViewProject.getProjects().get(k);
if (!n.isA(SqlKind.INPUT_REF)) {
continue;
}
@@ -701,7 +701,7 @@ public abstract class MaterializedViewAggregateRule extends MaterializedViewRule
final RelDataType topRowType;
final List<RexNode> topExprs = new ArrayList<>();
if (topProject != null && !unionRewriting) {
- topExprs.addAll(topProject.getChildExps());
+ topExprs.addAll(topProject.getProjects());
topRowType = topProject.getRowType();
} else {
// Add all
@@ -713,7 +713,7 @@ public abstract class MaterializedViewAggregateRule extends MaterializedViewRule
// Available in view.
final Multimap<RexNode, Integer> viewExprs = ArrayListMultimap.create();
int numberViewExprs = 0;
- for (RexNode viewExpr : topViewProject.getChildExps()) {
+ for (RexNode viewExpr : topViewProject.getProjects()) {
viewExprs.put(viewExpr, numberViewExprs++);
}
for (RexNode additionalViewExpr : additionalViewExprs) {
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewJoinRule.java b/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewJoinRule.java
index 7b470fb..ef0fcd2 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewJoinRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewJoinRule.java
@@ -245,7 +245,7 @@ public abstract class MaterializedViewJoinRule extends MaterializedViewRule {
EquivalenceClasses queryEC) {
List<RexNode> exprs = topProject == null
? extractReferences(rexBuilder, node)
- : topProject.getChildExps();
+ : topProject.getProjects();
List<RexNode> exprsLineage = new ArrayList<>(exprs.size());
for (RexNode expr : exprs) {
Set<RexNode> s = mq.getExpressionLineage(node, expr);
@@ -262,7 +262,7 @@ public abstract class MaterializedViewJoinRule extends MaterializedViewRule {
}
List<RexNode> viewExprs = topViewProject == null
? extractReferences(rexBuilder, viewNode)
- : topViewProject.getChildExps();
+ : topViewProject.getProjects();
List<RexNode> rewrittenExprs = rewriteExpressions(rexBuilder, mq, input, viewNode, viewExprs,
queryToViewTableMapping.inverse(), queryEC, true, exprsLineage);
if (rewrittenExprs == null) {
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewRule.java b/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewRule.java
index fc3741c..00e9722 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewRule.java
@@ -428,7 +428,7 @@ public abstract class MaterializedViewRule extends RelOptRule {
// in the view output (condition 2).
List<RexNode> viewExprs = topViewProject == null
? extractReferences(rexBuilder, view)
- : topViewProject.getChildExps();
+ : topViewProject.getProjects();
// For compensationColumnsEquiPred, we use the view equivalence classes,
// since we want to enforce the rest
if (!compensationColumnsEquiPred.isAlwaysTrue()) {
diff --git a/core/src/main/java/org/apache/calcite/rex/RexCall.java b/core/src/main/java/org/apache/calcite/rex/RexCall.java
index d5c2cea..6b8f2ac 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexCall.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexCall.java
@@ -22,18 +22,16 @@ import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlOperator;
import org.apache.calcite.sql.SqlSyntax;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.util.Litmus;
+import org.apache.calcite.util.Pair;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import javax.annotation.Nonnull;
/**
@@ -53,12 +51,6 @@ import javax.annotation.Nonnull;
* no one is going to be generating source code from this tree.)</p>
*/
public class RexCall extends RexNode {
- /**
- * Sort shorter digests first, then order by string representation.
- * The result is designed for consistent output and better readability.
- */
- private static final Comparator<String> OPERAND_READABILITY_COMPARATOR =
- Comparator.comparing(String::length).thenComparing(Comparator.naturalOrder());
//~ Instance fields --------------------------------------------------------
@@ -67,22 +59,6 @@ public class RexCall extends RexNode {
public final RelDataType type;
public final int nodeCount;
- /**
- * Simple binary operators are those operators which expects operands from the same Domain.
- *
- * <p>Example: simple comparisions ({@code =}, {@code <}).
- *
- * <p>Note: it does not contain {@code IN} because that is defined on D x D^n.
- */
- private static final Set<SqlKind> SIMPLE_BINARY_OPS;
-
- static {
- EnumSet<SqlKind> kinds = EnumSet.of(SqlKind.PLUS, SqlKind.MINUS, SqlKind.TIMES, SqlKind.DIVIDE);
- kinds.addAll(SqlKind.COMPARISON);
- kinds.remove(SqlKind.IN);
- SIMPLE_BINARY_OPS = Sets.immutableEnumSet(kinds);
- }
-
//~ Constructors -----------------------------------------------------------
protected RexCall(
@@ -90,8 +66,11 @@ public class RexCall extends RexNode {
SqlOperator op,
List<? extends RexNode> operands) {
this.type = Objects.requireNonNull(type, "type");
- this.op = Objects.requireNonNull(op, "operator");
- this.operands = ImmutableList.copyOf(operands);
+ Objects.requireNonNull(op, "operator");
+ final Pair<SqlOperator, ImmutableList<RexNode>> normalized =
+ normalize(op, operands);
+ this.op = normalized.left;
+ this.operands = normalized.right;
this.nodeCount = RexUtil.nodeCount(1, this.operands);
assert op.getKind() != null : op;
assert op.validRexOperands(operands.size(), Litmus.THROW) : this;
@@ -108,11 +87,10 @@ public class RexCall extends RexNode {
*
* @see RexLiteral#computeDigest(RexDigestIncludeType)
* @param sb destination
- * @return original StringBuilder for fluent API
*/
- protected final StringBuilder appendOperands(StringBuilder sb) {
+ protected final void appendOperands(StringBuilder sb) {
if (operands.isEmpty()) {
- return sb;
+ return;
}
List<String> operandDigests = new ArrayList<>(operands.size());
for (int i = 0; i < operands.size(); i++) {
@@ -123,15 +101,16 @@ public class RexCall extends RexNode {
}
// Type information might be omitted in certain cases to improve readability
// For instance, AND/OR arguments should be BOOLEAN, so
- // AND(true, null) is better than AND(true, null:BOOLEAN), and we keep the same info
- // +($0, 2) is better than +($0, 2:BIGINT). Note: if $0 has BIGINT, then 2 is expected to be
+ // AND(true, null) is better than AND(true, null:BOOLEAN), and we keep the same info.
+
+ // +($0, 2) is better than +($0, 2:BIGINT). Note: if $0 is BIGINT, then 2 is expected to be
// of BIGINT type as well.
RexDigestIncludeType includeType = RexDigestIncludeType.OPTIONAL;
if ((isA(SqlKind.AND) || isA(SqlKind.OR))
&& operand.getType().getSqlTypeName() == SqlTypeName.BOOLEAN) {
includeType = RexDigestIncludeType.NO_TYPE;
}
- if (SIMPLE_BINARY_OPS.contains(getKind()) && operands.size() == 2) {
+ if (SqlKind.SIMPLE_BINARY_OPS.contains(getKind())) {
RexNode otherArg = operands.get(1 - i);
if ((!(otherArg instanceof RexLiteral)
|| ((RexLiteral) otherArg).digestIncludesType() == RexDigestIncludeType.NO_TYPE)
@@ -146,7 +125,6 @@ public class RexCall extends RexNode {
totalLength += s.length();
}
sb.ensureCapacity(sb.length() + totalLength);
- sortOperandsIfNeeded(sb, operands, operandDigests);
for (int i = 0; i < operandDigests.size(); i++) {
String op = operandDigests.get(i);
if (i != 0) {
@@ -154,72 +132,58 @@ public class RexCall extends RexNode {
}
sb.append(op);
}
- return sb;
}
- private void sortOperandsIfNeeded(StringBuilder sb,
- List<RexNode> operands, List<String> operandDigests) {
- if (operands.isEmpty() || !needNormalize()) {
- return;
+ private Pair<SqlOperator, ImmutableList<RexNode>> normalize(
+ SqlOperator operator,
+ List<? extends RexNode> operands) {
+ final ImmutableList<RexNode> oldOperands = ImmutableList.copyOf(operands);
+ final Pair<SqlOperator, ImmutableList<RexNode>> original = Pair.of(operator, oldOperands);
+ if (!needNormalize()) {
+ return original;
+ }
+ if (operands.size() != 2
+ || !operands.stream().allMatch(operand -> operand.getClass() == RexInputRef.class)) {
+ return original;
}
- final SqlKind kind = op.getKind();
+ final RexInputRef operand0 = (RexInputRef) operands.get(0);
+ final RexInputRef operand1 = (RexInputRef) operands.get(1);
+ final SqlKind kind = operator.getKind();
+ if (operand0.getIndex() < operand1.getIndex()) {
+ return original;
+ }
+ // If arguments are the same, then we normalize < vs >
+ // '<' == 60, '>' == 62, so we prefer <.
+ if (operand0.getIndex() == operand1.getIndex()) {
+ if (kind.reverse().compareTo(kind) < 0) {
+ return Pair.of(SqlStdOperatorTable.reverse(operator), oldOperands);
+ } else {
+ return original;
+ }
+ }
+
if (SqlKind.SYMMETRICAL_SAME_ARG_TYPE.contains(kind)) {
final RelDataType firstType = operands.get(0).getType();
for (int i = 1; i < operands.size(); i++) {
if (!equalSansNullability(firstType, operands.get(i).getType())) {
// Arguments have different type, thus they must not be sorted
- return;
+ return original;
}
}
// fall through: order arguments below
} else if (!SqlKind.SYMMETRICAL.contains(kind)
- && (kind == kind.reverse()
- || !op.getName().equals(kind.sql)
- || sb.length() < kind.sql.length() + 1
- || sb.charAt(sb.length() - 1) != '(')) {
+ && kind == kind.reverse()) {
// The operations have to be either symmetrical or reversible
// Nothing matched => we skip argument sorting
- // Note: RexCall digest uses op.getName() that might be different from kind.sql
- // for certain calls. So we skip normalizing the calls that have customized op.getName()
- // We ensure the current string contains enough room for preceding kind.sql otherwise
- // we won't have an option to replace the operator to reverse it in case the operands are
- // reordered.
- return;
+ return original;
}
- // $0=$1 is the same as $1=$0, so we make sure the digest is the same for them
- String oldFirstArg = operandDigests.get(0);
- operandDigests.sort(OPERAND_READABILITY_COMPARATOR);
+ // $0=$1 is the same as $1=$0, so we make sure the digest is the same for them.
// When $1 > $0 is normalized, the operation needs to be flipped
- // So we sort arguments first, then flip the sign
- if (kind != kind.reverse()) {
- assert operands.size() == 2
- : "Compare operation must have 2 arguments: " + this
- + ". Actual arguments are " + operandDigests;
- int operatorEnd = sb.length() - 1 /* ( */;
- int operatorStart = operatorEnd - op.getName().length();
- assert op.getName().contentEquals(sb.subSequence(operatorStart, operatorEnd))
- : "Operation name must precede opening brace like in <=(x, y). Actual content is "
- + sb.subSequence(operatorStart, operatorEnd)
- + " at position " + operatorStart + " in " + sb;
-
- SqlKind newKind = kind.reverse();
-
- // If arguments are the same, then we normalize < vs >
- // '<' == 60, '>' == 62, so we prefer <
- if (operandDigests.get(0).equals(operandDigests.get(1))) {
- if (newKind.compareTo(kind) > 0) {
- // If reverse kind is greater, then skip reversing
- return;
- }
- } else if (oldFirstArg.equals(operandDigests.get(0))) {
- // The sorting did not shuffle the operands, so we do not need to update operation name
- // in the digest
- return;
- }
- // Replace operator name in the digest
- sb.replace(operatorStart, operatorEnd, newKind.sql);
- }
+ // So we sort arguments first, then flip the sign.
+ final SqlOperator newOp = SqlStdOperatorTable.reverse(operator);
+ final ImmutableList<RexNode> newOperands = ImmutableList.of(operand1, operand0);
+ return Pair.of(newOp, newOperands);
}
/**
@@ -359,13 +323,19 @@ public class RexCall extends RexNode {
return new RexCall(type, op, operands);
}
- @Override public boolean equals(Object obj) {
- return obj == this
- || obj instanceof RexCall
- && toString().equals(obj.toString());
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ RexCall rexCall = (RexCall) o;
+ return op.equals(rexCall.op)
+ && operands.equals(rexCall.operands);
}
@Override public int hashCode() {
- return toString().hashCode();
+ return Objects.hash(op, operands);
}
}
diff --git a/core/src/main/java/org/apache/calcite/rex/RexNode.java b/core/src/main/java/org/apache/calcite/rex/RexNode.java
index 7a8f058..88332a2 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexNode.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexNode.java
@@ -23,7 +23,6 @@ import org.apache.calcite.sql.SqlKind;
import org.apiguardian.api.API;
import java.util.Collection;
-import java.util.concurrent.atomic.AtomicInteger;
/**
* Row expression.
@@ -40,54 +39,6 @@ import java.util.concurrent.atomic.AtomicInteger;
* <p>All sub-classes of RexNode are immutable.</p>
*/
public abstract class RexNode {
- /**
- * Sometimes RexCall nodes are located deep (e.g. inside Lists),
- * If the value is non-zero, then a non-normalized representation is printed.
- * int is used to allow for re-entrancy.
- */
- private static final ThreadLocal<AtomicInteger> DESCRIBE_WITHOUT_NORMALIZE =
- ThreadLocal.withInitial(AtomicInteger::new);
-
- /** Removes a Hook after use. */
- @API(since = "1.22", status = API.Status.EXPERIMENTAL)
- public interface Closeable extends AutoCloseable {
- // override, removing "throws"
- @Override void close();
- }
-
- private static final Closeable DECREMENT_ON_CLOSE = () -> {
- DESCRIBE_WITHOUT_NORMALIZE.get().decrementAndGet();
- };
-
- private static final Closeable EMPTY = () -> { };
-
- /**
- * The digest of {@code RexNode} is normalized by default, however, sometimes a non-normalized
- * representation is required.
- * This API enables to skip normalization.
- * Note: the returned value must be closed, and the API is designed to be used with a
- * try-with-resources.
- * @param needNormalize true if normalization should be enabled or false if it should be skipped
- * @return a handle that should be closed to revert normalization state
- */
- @API(since = "1.22", status = API.Status.EXPERIMENTAL)
- public static Closeable withNormalize(boolean needNormalize) {
- return needNormalize ? EMPTY : skipNormalize();
- }
-
- /**
- * The digest of {@code RexNode} is normalized by default, however, sometimes a non-normalized
- * representation is required.
- * This API enables to skip normalization.
- * Note: the returned value must be closed, and the API is designed to be used with a
- * try-with-resources.
- * @return a handle that should be closed to revert normalization state
- */
- @API(since = "1.22", status = API.Status.EXPERIMENTAL)
- public static Closeable skipNormalize() {
- DESCRIBE_WITHOUT_NORMALIZE.get().incrementAndGet();
- return DECREMENT_ON_CLOSE;
- }
/**
* The digest of {@code RexNode} is normalized by default, however, sometimes a non-normalized
@@ -97,8 +48,7 @@ public abstract class RexNode {
*/
@API(since = "1.22", status = API.Status.EXPERIMENTAL)
protected static boolean needNormalize() {
- return DESCRIBE_WITHOUT_NORMALIZE.get().get() == 0
- && CalciteSystemProperty.ENABLE_REX_DIGEST_NORMALIZE.value();
+ return CalciteSystemProperty.ENABLE_REX_DIGEST_NORMALIZE.value();
}
//~ Instance fields --------------------------------------------------------
@@ -147,17 +97,6 @@ public abstract class RexNode {
return digest;
}
- /**
- * Returns string representation of this node.
- * @return the same as {@link #toString()}, but without normalizing the output
- */
- @API(since = "1.22", status = API.Status.EXPERIMENTAL)
- public String toStringRaw() {
- try (Closeable ignored = skipNormalize()) {
- return toString();
- }
- }
-
/** Returns the number of nodes in this expression.
*
* <p>Leaf nodes, such as {@link RexInputRef} or {@link RexLiteral}, have
diff --git a/core/src/main/java/org/apache/calcite/rex/RexOver.java b/core/src/main/java/org/apache/calcite/rex/RexOver.java
index cfdd6c2..e90fa3c 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexOver.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexOver.java
@@ -196,4 +196,25 @@ public class RexOver extends RexCall {
throw OverFound.INSTANCE;
}
}
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ RexOver rexOver = (RexOver) o;
+ return distinct == rexOver.distinct
+ && ignoreNulls == rexOver.ignoreNulls
+ && window.equals(rexOver.window)
+ && op.allowsFraming() == rexOver.op.allowsFraming();
+ }
+
+ @Override public int hashCode() {
+ return Objects.hash(super.hashCode(), window, distinct, ignoreNulls, op.allowsFraming());
+ }
}
diff --git a/core/src/main/java/org/apache/calcite/rex/RexSubQuery.java b/core/src/main/java/org/apache/calcite/rex/RexSubQuery.java
index 5a081dc..d702387 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSubQuery.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSubQuery.java
@@ -136,4 +136,14 @@ public class RexSubQuery extends RexCall {
public RexSubQuery clone(RelNode rel) {
return new RexSubQuery(type, getOperator(), operands, rel);
}
+
+ @Override public boolean equals(Object obj) {
+ return obj == this
+ || obj instanceof RexCall
+ && toString().equals(obj.toString());
+ }
+
+ @Override public int hashCode() {
+ return toString().hashCode();
+ }
}
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlKind.java b/core/src/main/java/org/apache/calcite/sql/SqlKind.java
index b3e42a8..f98a0c2 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlKind.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlKind.java
@@ -16,6 +16,8 @@
*/
package org.apache.calcite.sql;
+import com.google.common.collect.Sets;
+
import org.apiguardian.api.API;
import java.util.Collection;
@@ -1373,6 +1375,23 @@ public enum SqlKind {
EnumSet.of(
PLUS, TIMES);
+ /**
+ * Simple binary operators are those operators which expects operands from the same Domain.
+ *
+ * <p>Example: simple comparisions ({@code =}, {@code <}).
+ *
+ * <p>Note: it does not contain {@code IN} because that is defined on D x D^n.
+ */
+ @API(since = "1.24", status = API.Status.EXPERIMENTAL)
+ public static final Set<SqlKind> SIMPLE_BINARY_OPS;
+
+ static {
+ EnumSet<SqlKind> kinds = EnumSet.of(SqlKind.PLUS, SqlKind.MINUS, SqlKind.TIMES, SqlKind.DIVIDE);
+ kinds.addAll(SqlKind.COMPARISON);
+ kinds.remove(SqlKind.IN);
+ SIMPLE_BINARY_OPS = Sets.immutableEnumSet(kinds);
+ }
+
/** Lower-case name. */
public final String lowerName = name().toLowerCase(Locale.ROOT);
public final String sql;
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
index e026b95..3a6027d 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
@@ -2595,4 +2595,24 @@ public class SqlStdOperatorTable extends ReflectiveSqlOperatorTable {
}
}
+ /** Returns the binary operator that corresponds to this operator but in the opposite
+ * direction. Or returns this, if its kind is not reversible.
+ *
+ * <p>For example, {@code reverse(GREATER_THAN)} returns {@link #LESS_THAN}.
+ */
+ public static SqlOperator reverse(SqlOperator operator) {
+ switch (operator.getKind()) {
+ case GREATER_THAN:
+ return LESS_THAN;
+ case GREATER_THAN_OR_EQUAL:
+ return LESS_THAN_OR_EQUAL;
+ case LESS_THAN:
+ return GREATER_THAN;
+ case LESS_THAN_OR_EQUAL:
+ return GREATER_THAN_OR_EQUAL;
+ default:
+ return operator;
+ }
+ }
+
}
diff --git a/core/src/test/java/org/apache/calcite/materialize/LatticeSuggesterTest.java b/core/src/test/java/org/apache/calcite/materialize/LatticeSuggesterTest.java
index bc3cc8e..f56d49c 100644
--- a/core/src/test/java/org/apache/calcite/materialize/LatticeSuggesterTest.java
+++ b/core/src/test/java/org/apache/calcite/materialize/LatticeSuggesterTest.java
@@ -670,12 +670,12 @@ class LatticeSuggesterTest {
t.addQuery(q0);
assertThat(t.s.latticeMap.size(), is(1));
assertThat(t.s.latticeMap.keySet().iterator().next(),
- is("sales_fact_1997 (customer:+(2, $2)):[MIN(customer.fname)]"));
+ is("sales_fact_1997 (customer:+($2, 2)):[MIN(customer.fname)]"));
assertThat(t.s.space.g.toString(),
is("graph(vertices: [[foodmart, customer],"
+ " [foodmart, sales_fact_1997]], "
+ "edges: [Step([foodmart, sales_fact_1997],"
- + " [foodmart, customer], +(2, $2):+(1, $0))])"));
+ + " [foodmart, customer], +($2, 2):+($0, 1))])"));
}
/** Tests that we can run the suggester against non-JDBC schemas.
diff --git a/core/src/test/java/org/apache/calcite/plan/RelOptUtilTest.java b/core/src/test/java/org/apache/calcite/plan/RelOptUtilTest.java
index d567ce1..5af0d27 100644
--- a/core/src/test/java/org/apache/calcite/plan/RelOptUtilTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/RelOptUtilTest.java
@@ -389,7 +389,7 @@ class RelOptUtilTest {
.toString()));
assertThat(newJoin.getLeft(), is(instanceOf(Project.class)));
Project leftInput = (Project) newJoin.getLeft();
- assertThat(leftInput.getChildExps().get(empRow.getFieldCount()).toString(),
+ assertThat(leftInput.getProjects().get(empRow.getFieldCount()).toString(),
is(relBuilder.call(SqlStdOperatorTable.PLUS, leftKeyInputRef, relBuilder.literal(1))
.toString()));
}
@@ -434,7 +434,7 @@ class RelOptUtilTest {
.toString()));
assertThat(newJoin.getLeft(), is(instanceOf(Project.class)));
Project leftInput = (Project) newJoin.getLeft();
- assertThat(leftInput.getChildExps().get(empRow.getFieldCount()).toString(),
+ assertThat(leftInput.getProjects().get(empRow.getFieldCount()).toString(),
is(relBuilder.call(SqlStdOperatorTable.PLUS, leftKeyInputRef, relBuilder.literal(1))
.toString()));
@@ -486,7 +486,7 @@ class RelOptUtilTest {
.toString()));
assertThat(newJoin.getLeft(), is(instanceOf(Project.class)));
Project leftInput = (Project) newJoin.getLeft();
- assertThat(leftInput.getChildExps().get(empRow.getFieldCount()).toString(),
+ assertThat(leftInput.getProjects().get(empRow.getFieldCount()).toString(),
is(relBuilder.call(SqlStdOperatorTable.PLUS, leftKeyInputRef, relBuilder.literal(1))
.toString()));
}
@@ -538,7 +538,7 @@ class RelOptUtilTest {
.toString()));
assertThat(newJoin.getLeft(), is(instanceOf(Project.class)));
Project leftInput = (Project) newJoin.getLeft();
- assertThat(leftInput.getChildExps().get(empRow.getFieldCount()).toString(),
+ assertThat(leftInput.getProjects().get(empRow.getFieldCount()).toString(),
is(relBuilder.call(SqlStdOperatorTable.PLUS, leftKeyInputRef, relBuilder.literal(1))
.toString()));
}
diff --git a/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java b/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java
index b671282..809174b 100644
--- a/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java
@@ -242,12 +242,12 @@ class TraitPropagationTest {
RelTraitSet outcome = child.getTraitSet().replace(PHYSICAL);
call.transformTo(
new PhysProj(rel.getCluster(), outcome, convert(child, outcome),
- rel.getChildExps(), rel.getRowType()));
+ rel.getProjects(), rel.getRowType()));
}
}
} else {
call.transformTo(
- PhysProj.create(input, rel.getChildExps(), rel.getRowType()));
+ PhysProj.create(input, rel.getProjects(), rel.getRowType()));
}
}
diff --git a/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTest.java b/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTest.java
index d93a223..d98b2bf 100644
--- a/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/volcano/VolcanoPlannerTest.java
@@ -240,9 +240,9 @@ class VolcanoPlannerTest {
assertThat(sort(buf),
equalTo(
sort(
- "NoneSingleRel:Subset#0.NONE.[]",
- "PhysSingleRel:Subset#0.PHYS.[0]",
- "PhysSingleRel:Subset#0.PHYS.[]")));
+ "NoneSingleRel:RelSubset#0.NONE.[]",
+ "PhysSingleRel:RelSubset#0.PHYS.[0]",
+ "PhysSingleRel:RelSubset#0.PHYS.[]")));
}
private static <E extends Comparable> List<E> sort(List<E> list) {
@@ -281,8 +281,8 @@ class VolcanoPlannerTest {
assertTrue(result instanceof PhysSingleRel);
assertThat(sort(buf),
equalTo(
- sort("PhysSingleRel:Subset#0.PHYS.[]",
- "PhysSingleRel:Subset#0.PHYS_3.[]")));
+ sort("PhysSingleRel:RelSubset#0.PHYS.[]",
+ "PhysSingleRel:RelSubset#0.PHYS_3.[]")));
}
/**
diff --git a/core/src/test/java/org/apache/calcite/rel/rules/DateRangeRulesTest.java b/core/src/test/java/org/apache/calcite/rel/rules/DateRangeRulesTest.java
index e729288..bf4ca05 100644
--- a/core/src/test/java/org/apache/calcite/rel/rules/DateRangeRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/rel/rules/DateRangeRulesTest.java
@@ -700,9 +700,9 @@ class DateRangeRulesTest {
private void checkDateRange(Fixture f, RexNode e, String timeZone,
Matcher<String> matcher, Matcher<String> simplifyMatcher) {
e = DateRangeRules.replaceTimeUnits(f.rexBuilder, e, timeZone);
- assertThat(e.toStringRaw(), matcher);
+ assertThat(e.toString(), matcher);
final RexNode e2 = f.simplify.simplify(e);
- assertThat(e2.toStringRaw(), simplifyMatcher);
+ assertThat(e2.toString(), simplifyMatcher);
}
/** Common expressions across tests. */
diff --git a/core/src/test/java/org/apache/calcite/rex/RexCallNormalizationTest.java b/core/src/test/java/org/apache/calcite/rex/RexCallNormalizationTest.java
index e1bcbe4..38d08c1 100644
--- a/core/src/test/java/org/apache/calcite/rex/RexCallNormalizationTest.java
+++ b/core/src/test/java/org/apache/calcite/rex/RexCallNormalizationTest.java
@@ -20,54 +20,40 @@ import org.junit.jupiter.api.Test;
class RexCallNormalizationTest extends RexProgramTestBase {
@Test void digestIsNormalized() {
- final RexNode node = and(or(vBool(1), vBool()), vBool());
- checkDigest(node, "AND(?0.bool0, OR(?0.bool0, ?0.bool1))");
- checkRaw(node, "AND(OR(?0.bool1, ?0.bool0), ?0.bool0)");
+ final RexNode node = and(or(input(tBool(), 1), input(tBool(), 0)), input(tBool(), 0));
+ checkDigest(node, "AND(OR($0, $1), $0)");
- checkDigest(eq(vVarchar(), literal("0123456789012345")),
- "=(?0.varchar0, '0123456789012345')");
- checkDigest(eq(vVarchar(), literal("01")), "=('01', ?0.varchar0)");
- }
-
- @Test void skipNormalizationWorks() {
- final RexNode node = and(or(vBool(1), vBool()), vBool());
- try (RexNode.Closeable ignored = RexNode.skipNormalize()) {
- checkDigest(node, "AND(OR(?0.bool1, ?0.bool0), ?0.bool0)");
- checkRaw(node, "AND(OR(?0.bool1, ?0.bool0), ?0.bool0)");
- }
- }
-
- @Test void skipNormalizeWorks() {
- checkDigest(and(or(vBool(1), vBool()), vBool()),
- "AND(?0.bool0, OR(?0.bool0, ?0.bool1))");
+ checkDigest(eq(input(tVarchar(), 0), literal("0123456789012345")),
+ "=($0, '0123456789012345')");
+ checkDigest(eq(input(tVarchar(), 0), literal("01")), "=($0, '01')");
}
@Test void reversibleSameArgOpsNormalizedToLess() {
- checkDigest(lt(vBool(), vBool()), "<(?0.bool0, ?0.bool0)");
- checkDigest(gt(vBool(), vBool()), "<(?0.bool0, ?0.bool0)");
- checkDigest(le(vBool(), vBool()), "<=(?0.bool0, ?0.bool0)");
- checkDigest(ge(vBool(), vBool()), "<=(?0.bool0, ?0.bool0)");
+ checkDigest(lt(input(tBool(), 0), input(tBool(), 0)), "<($0, $0)");
+ checkDigest(gt(input(tBool(), 0), input(tBool(), 0)), "<($0, $0)");
+ checkDigest(le(input(tBool(), 0), input(tBool(), 0)), "<=($0, $0)");
+ checkDigest(ge(input(tBool(), 0), input(tBool(), 0)), "<=($0, $0)");
}
@Test void reversibleDifferentArgTypesShouldNotBeShuffled() {
- checkDigest(plus(vSmallInt(), vInt()), "+(?0.smallint0, ?0.int0)");
- checkDigest(plus(vInt(), vSmallInt()), "+(?0.int0, ?0.smallint0)");
- checkDigest(mul(vSmallInt(), vInt()), "*(?0.smallint0, ?0.int0)");
- checkDigest(mul(vInt(), vSmallInt()), "*(?0.int0, ?0.smallint0)");
+ checkDigest(plus(input(tSmallInt(), 0), input(tInt(), 1)), "+($0, $1)");
+ checkDigest(plus(input(tInt(), 0), input(tSmallInt(), 1)), "+($0, $1)");
+ checkDigest(mul(input(tSmallInt(), 0), input(tInt(), 1)), "*($0, $1)");
+ checkDigest(mul(input(tInt(), 0), input(tSmallInt(), 1)), "*($0, $1)");
}
@Test void reversibleDifferentNullabilityArgsAreNormalized() {
- checkDigest(plus(vIntNotNull(), vInt()), "+(?0.int0, ?0.notNullInt0)");
- checkDigest(plus(vInt(), vIntNotNull()), "+(?0.int0, ?0.notNullInt0)");
- checkDigest(mul(vIntNotNull(), vInt()), "*(?0.int0, ?0.notNullInt0)");
- checkDigest(mul(vInt(), vIntNotNull()), "*(?0.int0, ?0.notNullInt0)");
+ checkDigest(plus(input(tInt(false), 1), input(tInt(), 0)), "+($0, $1)");
+ checkDigest(plus(input(tInt(), 1), input(tInt(false), 0)), "+($0, $1)");
+ checkDigest(mul(input(tInt(false), 1), input(tInt(), 0)), "*($0, $1)");
+ checkDigest(mul(input(tInt(), 1), input(tInt(false), 0)), "*($0, $1)");
}
@Test void symmetricalDifferentArgOps() {
for (int i = 0; i < 2; i++) {
int j = 1 - i;
- checkDigest(eq(vBool(i), vBool(j)), "=(?0.bool0, ?0.bool1)");
- checkDigest(ne(vBool(i), vBool(j)), "<>(?0.bool0, ?0.bool1)");
+ checkDigest(eq(input(tBool(), i), input(tBool(), j)), "=($0, $1)");
+ checkDigest(ne(input(tBool(), i), input(tBool(), j)), "<>($0, $1)");
}
}
@@ -75,25 +61,25 @@ class RexCallNormalizationTest extends RexProgramTestBase {
for (int i = 0; i < 2; i++) {
int j = 1 - i;
checkDigest(
- lt(vBool(i), vBool(j)),
+ lt(input(tBool(), i), input(tBool(), j)),
i < j
- ? "<(?0.bool0, ?0.bool1)"
- : ">(?0.bool0, ?0.bool1)");
+ ? "<($0, $1)"
+ : ">($0, $1)");
checkDigest(
- le(vBool(i), vBool(j)),
+ le(input(tBool(), i), input(tBool(), j)),
i < j
- ? "<=(?0.bool0, ?0.bool1)"
- : ">=(?0.bool0, ?0.bool1)");
+ ? "<=($0, $1)"
+ : ">=($0, $1)");
checkDigest(
- gt(vBool(i), vBool(j)),
+ gt(input(tBool(), i), input(tBool(), j)),
i < j
- ? ">(?0.bool0, ?0.bool1)"
- : "<(?0.bool0, ?0.bool1)");
+ ? ">($0, $1)"
+ : "<($0, $1)");
checkDigest(
- ge(vBool(i), vBool(j)),
+ ge(input(tBool(), i), input(tBool(), j)),
i < j
- ? ">=(?0.bool0, ?0.bool1)"
- : "<=(?0.bool0, ?0.bool1)");
+ ? ">=($0, $1)"
+ : "<=($0, $1)");
}
}
}
diff --git a/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java b/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
index 53676e4..a5d14c8 100644
--- a/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
@@ -741,7 +741,7 @@ class RexProgramTest extends RexProgramTestBase {
final int nodeCount = cnf.nodeCount();
assertThat((n + 1) * (int) Math.pow(2, n) + 1, equalTo(nodeCount));
if (n == 3) {
- assertThat(cnf.toStringRaw(),
+ assertThat(cnf.toString(),
equalTo("AND(OR(?0.x0, ?0.x1, ?0.x2), OR(?0.x0, ?0.x1, ?0.y2),"
+ " OR(?0.x0, ?0.y1, ?0.x2), OR(?0.x0, ?0.y1, ?0.y2),"
+ " OR(?0.y0, ?0.x1, ?0.x2), OR(?0.y0, ?0.x1, ?0.y2),"
@@ -1104,7 +1104,7 @@ class RexProgramTest extends RexProgramTestBase {
// as previous, using simplifyFilterPredicates
assertThat(simplify
.simplifyFilterPredicates(args)
- .toStringRaw(),
+ .toString(),
equalTo("AND(=(?0.a, 1), =(?0.b, 1))"));
// "a = 1 and a = 10" is always false
@@ -1410,7 +1410,7 @@ class RexProgramTest extends RexProgramTestBase {
// TODO: "b is not unknown" would be the best simplification.
final RexNode simplified =
this.simplify.simplifyUnknownAs(neOrEq, RexUnknownAs.UNKNOWN);
- assertThat(simplified.toStringRaw(),
+ assertThat(simplified.toString(),
equalTo("OR(<>(?0.b, 1), =(?0.b, 1))"));
// "a is null or a is not null" ==> "true"
@@ -2171,7 +2171,7 @@ class RexProgramTest extends RexProgramTestBase {
private void assertTypeAndToString(
RexNode rexNode, String representation, String type) {
- assertEquals(representation, rexNode.toStringRaw());
+ assertEquals(representation, rexNode.toString());
assertEquals(type, rexNode.getType().toString()
+ (rexNode.getType().isNullable() ? "" : " NOT NULL"), "type of " + rexNode);
}
diff --git a/core/src/test/java/org/apache/calcite/rex/RexProgramTestBase.java b/core/src/test/java/org/apache/calcite/rex/RexProgramTestBase.java
index 140fb11..c3a634c 100644
--- a/core/src/test/java/org/apache/calcite/rex/RexProgramTestBase.java
+++ b/core/src/test/java/org/apache/calcite/rex/RexProgramTestBase.java
@@ -30,32 +30,27 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
class RexProgramTestBase extends RexProgramBuilderBase {
protected void checkDigest(RexNode node, String expected) {
- assertEquals(expected, node.toString(), () -> "Digest of " + node.toStringRaw());
- }
-
- protected void checkRaw(RexNode node, String expected) {
- assertEquals(expected, node.toStringRaw(),
- () -> "Raw representation of node with digest " + node);
+ assertEquals(expected, node.toString(), () -> "Digest of " + node.toString());
}
protected void checkCnf(RexNode node, String expected) {
assertThat("RexUtil.toCnf(rexBuilder, " + node + ")",
- RexUtil.toCnf(rexBuilder, node).toStringRaw(), equalTo(expected));
+ RexUtil.toCnf(rexBuilder, node).toString(), equalTo(expected));
}
protected void checkThresholdCnf(RexNode node, int threshold, String expected) {
assertThat("RexUtil.toCnf(rexBuilder, threshold=" + threshold + " , " + node + ")",
- RexUtil.toCnf(rexBuilder, threshold, node).toStringRaw(),
+ RexUtil.toCnf(rexBuilder, threshold, node).toString(),
equalTo(expected));
}
protected void checkPullFactorsUnchanged(RexNode node) {
- checkPullFactors(node, node.toStringRaw());
+ checkPullFactors(node, node.toString());
}
protected void checkPullFactors(RexNode node, String expected) {
assertThat("RexUtil.pullFactors(rexBuilder, " + node + ")",
- RexUtil.pullFactors(rexBuilder, node).toStringRaw(),
+ RexUtil.pullFactors(rexBuilder, node).toString(),
equalTo(expected));
}
@@ -69,7 +64,7 @@ class RexProgramTestBase extends RexProgramBuilderBase {
String actual;
if (node.isA(SqlKind.CAST) || node.isA(SqlKind.NEW_SPECIFICATION)) {
// toString contains type (see RexCall.toString)
- actual = node.toStringRaw();
+ actual = node.toString();
} else {
actual = node + ":" + node.getType() + (node.getType().isNullable() ? "" : " NOT NULL");
}
@@ -78,17 +73,17 @@ class RexProgramTestBase extends RexProgramBuilderBase {
/** Simplifies an expression and checks that the result is as expected. */
protected void checkSimplify(RexNode node, String expected) {
- final String nodeString = node.toStringRaw();
+ final String nodeString = node.toString();
checkSimplify3_(node, expected, expected, expected);
if (expected.equals(nodeString)) {
- throw new AssertionError("expected == node.toStringRaw(); "
+ throw new AssertionError("expected == node.toString(); "
+ "use checkSimplifyUnchanged");
}
}
/** Simplifies an expression and checks that the result is unchanged. */
protected void checkSimplifyUnchanged(RexNode node) {
- final String expected = node.toStringRaw();
+ final String expected = node.toString();
checkSimplify3_(node, expected, expected, expected);
}
@@ -126,16 +121,16 @@ class RexProgramTestBase extends RexProgramBuilderBase {
final RexNode simplified =
simplify.simplifyUnknownAs(node, RexUnknownAs.UNKNOWN);
assertThat("simplify(unknown as unknown): " + node,
- simplified.toStringRaw(), equalTo(expected));
+ simplified.toString(), equalTo(expected));
if (node.getType().getSqlTypeName() == SqlTypeName.BOOLEAN) {
final RexNode simplified2 =
simplify.simplifyUnknownAs(node, RexUnknownAs.FALSE);
assertThat("simplify(unknown as false): " + node,
- simplified2.toStringRaw(), equalTo(expectedFalse));
+ simplified2.toString(), equalTo(expectedFalse));
final RexNode simplified3 =
simplify.simplifyUnknownAs(node, RexUnknownAs.TRUE);
assertThat("simplify(unknown as true): " + node,
- simplified3.toStringRaw(), equalTo(expectedTrue));
+ simplified3.toString(), equalTo(expectedTrue));
} else {
assertThat("node type is not BOOLEAN, so <<expectedFalse>> should match <<expected>>",
expectedFalse, is(expected));
@@ -147,7 +142,7 @@ class RexProgramTestBase extends RexProgramBuilderBase {
protected void checkSimplifyFilter(RexNode node, String expected) {
final RexNode simplified =
this.simplify.simplifyUnknownAs(node, RexUnknownAs.FALSE);
- assertThat(simplified.toStringRaw(), equalTo(expected));
+ assertThat(simplified.toString(), equalTo(expected));
}
protected void checkSimplifyFilter(RexNode node, RelOptPredicateList predicates,
@@ -155,7 +150,7 @@ class RexProgramTestBase extends RexProgramBuilderBase {
final RexNode simplified =
simplify.withPredicates(predicates)
.simplifyUnknownAs(node, RexUnknownAs.FALSE);
- assertThat(simplified.toStringRaw(), equalTo(expected));
+ assertThat(simplified.toString(), equalTo(expected));
}
/** Checks that {@link RexNode#isAlwaysTrue()},
@@ -163,11 +158,11 @@ class RexProgramTestBase extends RexProgramBuilderBase {
* an expression reduces to true or false. */
protected void checkIs(RexNode e, boolean expected) {
assertThat(
- "isAlwaysTrue() of expression: " + e.toStringRaw(), e.isAlwaysTrue(), is(expected));
+ "isAlwaysTrue() of expression: " + e.toString(), e.isAlwaysTrue(), is(expected));
assertThat(
- "isAlwaysFalse() of expression: " + e.toStringRaw(), e.isAlwaysFalse(), is(!expected));
+ "isAlwaysFalse() of expression: " + e.toString(), e.isAlwaysFalse(), is(!expected));
assertThat(
- "Simplification is not using isAlwaysX informations", simplify(e).toStringRaw(),
+ "Simplification is not using isAlwaysX informations", simplify(e).toString(),
is(expected ? "true" : "false"));
}
diff --git a/core/src/test/java/org/apache/calcite/rex/RexSqlStandardConvertletTableTest.java b/core/src/test/java/org/apache/calcite/rex/RexSqlStandardConvertletTableTest.java
index 8ad8357..f5e235b 100644
--- a/core/src/test/java/org/apache/calcite/rex/RexSqlStandardConvertletTableTest.java
+++ b/core/src/test/java/org/apache/calcite/rex/RexSqlStandardConvertletTableTest.java
@@ -44,7 +44,7 @@ class RexSqlStandardConvertletTableTest extends SqlToRelTestBase {
@Test void testCoalesce() {
final Project project = (Project) convertSqlToRel(
"SELECT COALESCE(NULL, 'a')", false);
- final RexNode rex = project.getChildExps().get(0);
+ final RexNode rex = project.getProjects().get(0);
final RexToSqlNodeConverter rexToSqlNodeConverter = rexToSqlNodeConverter();
final SqlNode convertedSql = rexToSqlNodeConverter.convertNode(rex);
assertEquals(
@@ -56,7 +56,7 @@ class RexSqlStandardConvertletTableTest extends SqlToRelTestBase {
final Project project =
(Project) convertSqlToRel(
"SELECT CASE NULL WHEN NULL THEN NULL ELSE 'a' END", false);
- final RexNode rex = project.getChildExps().get(0);
+ final RexNode rex = project.getProjects().get(0);
final RexToSqlNodeConverter rexToSqlNodeConverter = rexToSqlNodeConverter();
final SqlNode convertedSql = rexToSqlNodeConverter.convertNode(rex);
assertEquals(
@@ -67,7 +67,7 @@ class RexSqlStandardConvertletTableTest extends SqlToRelTestBase {
@Test void testCaseNoValue() {
final Project project = (Project) convertSqlToRel(
"SELECT CASE WHEN NULL IS NULL THEN NULL ELSE 'a' END", false);
- final RexNode rex = project.getChildExps().get(0);
+ final RexNode rex = project.getProjects().get(0);
final RexToSqlNodeConverter rexToSqlNodeConverter = rexToSqlNodeConverter();
final SqlNode convertedSql = rexToSqlNodeConverter.convertNode(rex);
assertEquals(
diff --git a/core/src/test/java/org/apache/calcite/test/HepPlannerTest.java b/core/src/test/java/org/apache/calcite/test/HepPlannerTest.java
index 5b5fcc2..a4269c5 100644
--- a/core/src/test/java/org/apache/calcite/test/HepPlannerTest.java
+++ b/core/src/test/java/org/apache/calcite/test/HepPlannerTest.java
@@ -150,8 +150,10 @@ class HepPlannerTest extends RelOptTestBase {
// Bad digest includes full tree like rel#66:LogicalProject(input=rel#64:LogicalUnion(...))
// So the assertion is to ensure digest includes LogicalUnion exactly once
- assertIncludesExactlyOnce("best.getDescription()", best.toString(), "LogicalUnion");
- assertIncludesExactlyOnce("best.getDigest()", best.getDigest(), "LogicalUnion");
+ assertIncludesExactlyOnce("best.getDescription()",
+ best.toString(), "LogicalUnion");
+ assertIncludesExactlyOnce("best.getDigest()",
+ best.getDigest().toString(), "LogicalUnion");
}
private void assertIncludesExactlyOnce(String message, String digest, String substring) {
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java b/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
index 93d9225..d92a451 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
@@ -249,7 +249,7 @@ class JdbcAdapterTest {
+ "on s.losal <= e.sal and s.hisal >= e.sal")
.explainContains("PLAN=JdbcToEnumerableConverter\n"
+ " JdbcProject(EMPNO=[$0], ENAME=[$1], GRADE=[$3])\n"
- + " JdbcJoin(condition=[AND(<=($4, $2), >=($5, $2))], joinType=[inner])\n"
+ + " JdbcJoin(condition=[AND(>=($2, $4), <=($2, $5))], joinType=[inner])\n"
+ " JdbcProject(EMPNO=[$0], ENAME=[$1], SAL=[$5])\n"
+ " JdbcTableScan(table=[[SCOTT, EMP]])\n"
+ " JdbcTableScan(table=[[SCOTT, SALGRADE]])")
@@ -292,7 +292,7 @@ class JdbcAdapterTest {
+ "e.mgr = m.empno and (e.sal > m.sal or m.hiredate > e.hiredate)")
.explainContains("PLAN=JdbcToEnumerableConverter\n"
+ " JdbcProject(EMPNO=[$0], ENAME=[$1], EMPNO0=[$0], ENAME0=[$1])\n"
- + " JdbcJoin(condition=[AND(=($2, $5), OR(>($4, $7), >($6, $3)))], joinType=[inner])\n"
+ + " JdbcJoin(condition=[AND(=($2, $5), OR(>($4, $7), <($3, $6)))], joinType=[inner])\n"
+ " JdbcProject(EMPNO=[$0], ENAME=[$1], MGR=[$3], HIREDATE=[$4], SAL=[$5])\n"
+ " JdbcTableScan(table=[[SCOTT, EMP]])\n"
+ " JdbcProject(EMPNO=[$0], HIREDATE=[$4], SAL=[$5])\n"
diff --git a/core/src/test/java/org/apache/calcite/test/LatticeTest.java b/core/src/test/java/org/apache/calcite/test/LatticeTest.java
index 1a68667..a6591d3 100644
--- a/core/src/test/java/org/apache/calcite/test/LatticeTest.java
+++ b/core/src/test/java/org/apache/calcite/test/LatticeTest.java
@@ -239,9 +239,9 @@ class LatticeTest {
final Map.Entry<String, CalciteSchema.LatticeEntry> entry =
adhoc.unwrap(CalciteSchema.class).getLatticeMap().firstEntry();
final Lattice lattice = entry.getValue().getLattice();
- assertThat(lattice.firstColumn("S"), is(10));
- assertThat(lattice.firstColumn("P"), is(18));
- assertThat(lattice.firstColumn("T"), is(0));
+ assertThat(lattice.firstColumn("S"), is(0));
+ assertThat(lattice.firstColumn("P"), is(8));
+ assertThat(lattice.firstColumn("T"), is(23));
assertThat(lattice.firstColumn("PC"), is(-1));
assertThat(lattice.defaultMeasures.size(), is(1));
assertThat(lattice.rootNode.descendants.size(), is(3));
diff --git a/core/src/test/java/org/apache/calcite/test/MaterializedViewRelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/MaterializedViewRelOptRulesTest.java
index 8e45d23..58019b4 100644
--- a/core/src/test/java/org/apache/calcite/test/MaterializedViewRelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/MaterializedViewRelOptRulesTest.java
@@ -821,8 +821,7 @@ public class MaterializedViewRelOptRulesTest extends AbstractMaterializedViewTes
.withChecker(
resultContains(""
+ "EnumerableCalc(expr#0=[{inputs}], expr#1=[CAST($t0):JavaType(int) NOT NULL], "
- + "expr#2=[1], expr#3=[CAST($t1):INTEGER NOT NULL], expr#4=[=($t2, $t3)], "
- + "EXPR$0=[$t1], $condition=[$t4])\n"
+ + "expr#2=[1], expr#3=[=($t2, $t0)], EXPR$0=[$t1], $condition=[$t3])\n"
+ " EnumerableTableScan(table=[[hr, MV0]])"))
.ok();
}
diff --git a/core/src/test/java/org/apache/calcite/test/MaterializedViewSubstitutionVisitorTest.java b/core/src/test/java/org/apache/calcite/test/MaterializedViewSubstitutionVisitorTest.java
index e599382..2dd25cd 100644
--- a/core/src/test/java/org/apache/calcite/test/MaterializedViewSubstitutionVisitorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/MaterializedViewSubstitutionVisitorTest.java
@@ -1146,7 +1146,7 @@ public class MaterializedViewSubstitutionVisitorTest extends AbstractMaterialize
private void checkSatisfiable(RexNode e, String s) {
assertTrue(SubstitutionVisitor.mayBeSatisfiable(e));
final RexNode simple = simplify.simplifyUnknownAsFalse(e);
- assertEquals(s, simple.toStringRaw());
+ assertEquals(s, simple.toString());
}
@Test void testSplitFilter() {
@@ -1219,7 +1219,7 @@ public class MaterializedViewSubstitutionVisitorTest extends AbstractMaterialize
newFilter = SubstitutionVisitor.splitFilter(simplify,
x_eq_1,
rexBuilder.makeCall(SqlStdOperatorTable.OR, x_eq_1, z_eq_3));
- assertThat(newFilter.toStringRaw(), equalTo("=($0, 1)"));
+ assertThat(newFilter.toString(), equalTo("=($0, 1)"));
// 2b.
// condition: x = 1 or y = 2
@@ -1229,7 +1229,7 @@ public class MaterializedViewSubstitutionVisitorTest extends AbstractMaterialize
newFilter = SubstitutionVisitor.splitFilter(simplify,
rexBuilder.makeCall(SqlStdOperatorTable.OR, x_eq_1, y_eq_2),
rexBuilder.makeCall(SqlStdOperatorTable.OR, x_eq_1, y_eq_2, z_eq_3));
- assertThat(newFilter.toStringRaw(), equalTo("OR(=($0, 1), =($1, 2))"));
+ assertThat(newFilter.toString(), equalTo("OR(=($0, 1), =($1, 2))"));
// 2c.
// condition: x = 1
@@ -1239,7 +1239,7 @@ public class MaterializedViewSubstitutionVisitorTest extends AbstractMaterialize
newFilter = SubstitutionVisitor.splitFilter(simplify,
x_eq_1,
rexBuilder.makeCall(SqlStdOperatorTable.OR, x_eq_1, y_eq_2, z_eq_3));
- assertThat(newFilter.toStringRaw(),
+ assertThat(newFilter.toString(),
equalTo("=($0, 1)"));
// 2d.
@@ -1287,7 +1287,7 @@ public class MaterializedViewSubstitutionVisitorTest extends AbstractMaterialize
newFilter = SubstitutionVisitor.splitFilter(simplify,
rexBuilder.makeCall(SqlStdOperatorTable.AND, x_eq_1, y_eq_2),
y_eq_2);
- assertThat(newFilter.toStringRaw(), equalTo("=($0, 1)"));
+ assertThat(newFilter.toString(), equalTo("=($0, 1)"));
// Example 5.
// condition: x = 1
diff --git a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
index ac45e49..d00228f 100644
--- a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
@@ -1978,7 +1978,7 @@ public class RelBuilderTest {
+ " LogicalTableScan(table=[[scott, DEPT]])\n";
final String expectedWithoutSimplify = ""
+ "LogicalJoin(condition=[OR(null:NULL, "
- + "AND(=($7, 1), =($7, 2), =($8, $7)))], joinType=[inner])\n"
+ + "AND(=($7, 1), =($7, 2), =($7, $8)))], joinType=[inner])\n"
+ " LogicalTableScan(table=[[scott, EMP]])\n"
+ " LogicalTableScan(table=[[scott, DEPT]])\n";
assertThat(f.apply(createBuilder()), hasTree(expected));
@@ -2151,7 +2151,7 @@ public class RelBuilderTest {
builder.field("e", "MGR")))
.build();
final String expected = ""
- + "LogicalFilter(condition=[AND(=($7, $16), =($8, $3))])\n"
+ + "LogicalFilter(condition=[AND(=($7, $16), =($3, $8))])\n"
+ " LogicalJoin(condition=[true], joinType=[inner])\n"
+ " LogicalTableScan(table=[[scott, EMP]])\n"
+ " LogicalJoin(condition=[true], joinType=[inner])\n"
@@ -3544,7 +3544,7 @@ public class RelBuilderTest {
builder.field("EMPNO"),
builder.literal(1),
builder.literal(5));
- assertThat(call.toStringRaw(), is("BETWEEN ASYMMETRIC($0, 1, 5)"));
+ assertThat(call.toString(), is("BETWEEN ASYMMETRIC($0, 1, 5)"));
}
/** Test case for
diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
index 962e484..74abc71 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -2037,7 +2037,7 @@ public class RelMetadataTest extends SqlToRelTestBase {
+ "select empno, comm, deptno from emp where empno=1 and comm=4");
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
assertThat(mq.getPulledUpPredicates(rel).pulledUpPredicates,
- sortsAs("[=($0, 1), OR(AND(=($2, 3), =($1, 2)), =($1, 4))]"));
+ sortsAs("[=($0, 1), OR(AND(=($1, 2), =($2, 3)), =($1, 4))]"));
}
@@ -3066,14 +3066,12 @@ public class RelMetadataTest extends SqlToRelTestBase {
*/
public static <T> Matcher<Iterable<? extends T>> sortsAs(final String value) {
return Matchers.compose(equalTo(value), item -> {
- try (RexNode.Closeable ignored = RexNode.skipNormalize()) {
- final List<String> strings = new ArrayList<>();
- for (T t : item) {
- strings.add(t.toString());
- }
- Collections.sort(strings);
- return strings.toString();
+ final List<String> strings = new ArrayList<>();
+ for (T t : item) {
+ strings.add(t.toString());
}
+ Collections.sort(strings);
+ return strings.toString();
});
}
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index ec2d30d..a5abb11 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -6848,7 +6848,7 @@ class RelOptRulesTest extends RelOptTestBase {
final LogicalProject logicalProject = call.rel(0);
final RelNode input = logicalProject.getInput();
final MyProject myProject = new MyProject(input.getCluster(), input.getTraitSet(), input,
- logicalProject.getChildExps(), logicalProject.getRowType());
+ logicalProject.getProjects(), logicalProject.getRowType());
call.transformTo(myProject);
}
}
diff --git a/core/src/test/java/org/apache/calcite/test/RexTransformerTest.java b/core/src/test/java/org/apache/calcite/test/RexTransformerTest.java
index b7b6104..978d1b3 100644
--- a/core/src/test/java/org/apache/calcite/test/RexTransformerTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexTransformerTest.java
@@ -114,7 +114,7 @@ class RexTransformerTest {
RexTransformer transformer = new RexTransformer(root, rexBuilder);
RexNode result = transformer.transformNullSemantics();
- String actual = result.toStringRaw();
+ String actual = result.toString();
if (!actual.equals(expected)) {
String msg =
"\nExpected=<" + expected + ">\n Actual=<" + actual + ">";
@@ -374,7 +374,7 @@ class RexTransformerTest {
null,
null);
- assertThat(remaining.toStringRaw(), is("<>($0, $9)"));
+ assertThat(remaining.toString(), is("<>($0, $9)"));
assertThat(leftJoinKeys.isEmpty(), is(true));
assertThat(rightJoinKeys.isEmpty(), is(true));
}
diff --git a/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java b/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java
index 4e7a3f6..bf9079a 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java
@@ -76,8 +76,6 @@ import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
-import com.google.common.collect.ImmutableList;
-
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
@@ -510,11 +508,11 @@ class SqlHintsConverterTest extends SqlToRelTestBase {
public void onMatch(RelOptRuleCall call) {
LogicalJoin join = call.rel(0);
- assertThat(1, is(join.getHints().size()));
+ assertThat(join.getHints().size(), is(1));
call.transformTo(
LogicalJoin.create(join.getLeft(),
join.getRight(),
- ImmutableList.of(),
+ join.getHints(),
join.getCondition(),
join.getVariablesSet(),
join.getJoinType()));
diff --git a/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java b/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java
index 11aa4aa..d0a65e9 100644
--- a/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java
+++ b/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java
@@ -96,11 +96,11 @@ class EnumerableCorrelateTest {
planner.removeRule(EnumerableRules.ENUMERABLE_MERGE_JOIN_RULE);
})
.explainContains(""
- + "EnumerableCalc(expr#0..3=[{inputs}], empid=[$t1], name=[$t3])\n"
+ + "PLAN=EnumerableCalc(expr#0..3=[{inputs}], empid=[$t1], name=[$t3])\n"
+ " EnumerableCorrelate(correlation=[$cor1], joinType=[inner], requiredColumns=[{0}])\n"
+ " EnumerableAggregate(group=[{0}])\n"
+ " EnumerableTableScan(table=[[s, depts]])\n"
- + " EnumerableCalc(expr#0..4=[{inputs}], expr#5=[$cor1], expr#6=[$t5.deptno], expr#7=[=($t1, $t6)], proj#0..2=[{exprs}], $condition=[$t7])\n"
+ + " EnumerableCalc(expr#0..4=[{inputs}], expr#5=[$cor1], expr#6=[$t5.deptno], expr#7=[=($t6, $t1)], proj#0..2=[{exprs}], $condition=[$t7])\n"
+ " EnumerableTableScan(table=[[s, emps]])")
.returnsUnordered(
"empid=100; name=Bill",
@@ -126,11 +126,11 @@ class EnumerableCorrelateTest {
planner.removeRule(EnumerableRules.ENUMERABLE_MERGE_JOIN_RULE);
})
.explainContains(""
- + "EnumerableCalc(expr#0..3=[{inputs}], empid=[$t1], name=[$t3])\n"
+ + "PLAN=EnumerableCalc(expr#0..3=[{inputs}], empid=[$t1], name=[$t3])\n"
+ " EnumerableCorrelate(correlation=[$cor1], joinType=[inner], requiredColumns=[{0}])\n"
+ " EnumerableAggregate(group=[{0}])\n"
+ " EnumerableTableScan(table=[[s, depts]])\n"
- + " EnumerableCalc(expr#0..4=[{inputs}], expr#5=[$cor1], expr#6=[$t5.deptno], expr#7=[=($t1, $t6)], expr#8=[100], expr#9=[>($t0, $t8)], expr#10=[AND($t7, $t9)], proj#0..2=[{exprs}], $condition=[$t10])\n"
+ + " EnumerableCalc(expr#0..4=[{inputs}], expr#5=[$cor1], expr#6=[$t5.deptno], expr#7=[=($t6, $t1)], expr#8=[100], expr#9=[>($t0, $t8)], expr#10=[AND($t7, $t9)], proj#0..2=[{exprs}], $condition=[$t10])\n"
+ " EnumerableTableScan(table=[[s, emps]])")
.returnsUnordered(
"empid=110; name=Theodore",
diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index 57fd8c4..e8c29b6 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -638,7 +638,7 @@ LogicalProject(MGR=[$3])
</Resource>
<Resource name="planMid">
<![CDATA[
-LogicalProject(DEPTNO=[$0], EXPR$1=[OR(AND(IS NOT NULL($5), <>($2, 0)), AND(<($3, $2), null, <>($2, 0), IS NULL($5)))])
+LogicalProject(DEPTNO=[$0], EXPR$1=[OR(AND(IS NOT NULL($5), <>($2, 0)), AND(>($2, $3), null, <>($2, 0), IS NULL($5)))])
LogicalJoin(condition=[=($1, $4)], joinType=[left])
LogicalJoin(condition=[true], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
@@ -652,7 +652,7 @@ LogicalProject(DEPTNO=[$0], EXPR$1=[OR(AND(IS NOT NULL($5), <>($2, 0)), AND(<($3
</Resource>
<Resource name="planAfter">
<![CDATA[
-LogicalProject(DEPTNO=[$0], EXPR$1=[OR(AND(IS NOT NULL($5), <>($2, 0)), AND(<($3, $2), null, <>($2, 0), IS NULL($5)))])
+LogicalProject(DEPTNO=[$0], EXPR$1=[OR(AND(IS NOT NULL($5), <>($2, 0)), AND(>($2, $3), null, <>($2, 0), IS NULL($5)))])
LogicalJoin(condition=[=($1, $4)], joinType=[left])
LogicalJoin(condition=[true], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
@@ -1837,7 +1837,7 @@ group by case when e.sal < 11 then 11 else -1 * e.sal end]]>
LogicalProject(EXPR$0=[$1], EXPR$1=[$0])
LogicalAggregate(group=[{0}], EXPR$0=[COUNT()])
LogicalProject(EXPR$1=[CASE(<($9, 11), 11, *(-1, $9))])
- LogicalJoin(condition=[=($5, $0)], joinType=[left])
+ LogicalJoin(condition=[=($0, $5)], joinType=[left])
LogicalTableScan(table=[[CATALOG, SALES, BONUS]])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
@@ -1847,7 +1847,7 @@ LogicalProject(EXPR$0=[$1], EXPR$1=[$0])
LogicalProject(EXPR$0=[$1], EXPR$1=[$0])
LogicalAggregate(group=[{0}], EXPR$0=[COUNT()])
LogicalProject(EXPR$1=[CASE($2, 11, $3)])
- LogicalJoin(condition=[=($1, $0)], joinType=[left])
+ LogicalJoin(condition=[=($0, $1)], joinType=[left])
LogicalProject(ENAME=[$0])
LogicalTableScan(table=[[CATALOG, SALES, BONUS]])
LogicalProject(ENAME=[$1], <=[<($5, 11)], *=[*(-1, $5)])
@@ -1866,7 +1866,7 @@ group by case when e.sal < 11 then -1 * e.sal else e.sal end]]>
LogicalProject(EXPR$0=[$1], EXPR$1=[$0])
LogicalAggregate(group=[{0}], EXPR$0=[COUNT()])
LogicalProject(EXPR$1=[CASE(<($9, 11), *(-1, $9), $9)])
- LogicalJoin(condition=[=($5, $0)], joinType=[left])
+ LogicalJoin(condition=[=($0, $5)], joinType=[left])
LogicalTableScan(table=[[CATALOG, SALES, BONUS]])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
@@ -1876,7 +1876,7 @@ LogicalProject(EXPR$0=[$1], EXPR$1=[$0])
LogicalProject(EXPR$0=[$1], EXPR$1=[$0])
LogicalAggregate(group=[{0}], EXPR$0=[COUNT()])
LogicalProject(EXPR$1=[$2])
- LogicalJoin(condition=[=($1, $0)], joinType=[left])
+ LogicalJoin(condition=[=($0, $1)], joinType=[left])
LogicalProject(ENAME=[$0])
LogicalTableScan(table=[[CATALOG, SALES, BONUS]])
LogicalProject(ENAME=[$1], CASE=[CASE(<($5, 11), *(-1, $5), $5)])
@@ -1983,7 +1983,7 @@ group by case when e.sal < 11 then 11 else -1 * e.sal end]]>
LogicalProject(EXPR$0=[$1], EXPR$1=[$0])
LogicalAggregate(group=[{0}], EXPR$0=[COUNT()])
LogicalProject(EXPR$1=[CASE(<($9, 11), 11, *(-1, $9))])
- LogicalJoin(condition=[=($5, $0)], joinType=[right])
+ LogicalJoin(condition=[=($0, $5)], joinType=[right])
LogicalTableScan(table=[[CATALOG, SALES, BONUS]])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
@@ -1993,7 +1993,7 @@ LogicalProject(EXPR$0=[$1], EXPR$1=[$0])
LogicalProject(EXPR$0=[$1], EXPR$1=[$0])
LogicalAggregate(group=[{0}], EXPR$0=[COUNT()])
LogicalProject(EXPR$1=[$2])
- LogicalJoin(condition=[=($1, $0)], joinType=[right])
+ LogicalJoin(condition=[=($0, $1)], joinType=[right])
LogicalProject(ENAME=[$0])
LogicalTableScan(table=[[CATALOG, SALES, BONUS]])
LogicalProject(ENAME=[$1], CASE=[CASE(<($5, 11), 11, *(-1, $5))])
@@ -2012,7 +2012,7 @@ group by case when e.sal < 11 then -1 * e.sal else e.sal end]]>
LogicalProject(EXPR$0=[$1], EXPR$1=[$0])
LogicalAggregate(group=[{0}], EXPR$0=[COUNT()])
LogicalProject(EXPR$1=[CASE(<($9, 11), *(-1, $9), $9)])
- LogicalJoin(condition=[=($5, $0)], joinType=[right])
+ LogicalJoin(condition=[=($0, $5)], joinType=[right])
LogicalTableScan(table=[[CATALOG, SALES, BONUS]])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
@@ -2022,7 +2022,7 @@ LogicalProject(EXPR$0=[$1], EXPR$1=[$0])
LogicalProject(EXPR$0=[$1], EXPR$1=[$0])
LogicalAggregate(group=[{0}], EXPR$0=[COUNT()])
LogicalProject(EXPR$1=[$2])
- LogicalJoin(condition=[=($1, $0)], joinType=[right])
+ LogicalJoin(condition=[=($0, $1)], joinType=[right])
LogicalProject(ENAME=[$0])
LogicalTableScan(table=[[CATALOG, SALES, BONUS]])
LogicalProject(ENAME=[$1], CASE=[CASE(<($5, 11), *(-1, $5), $5)])
@@ -3582,7 +3582,7 @@ join sales.emp e on e.deptno = d.deptno and d.deptno not in (4, 6)]]>
<Resource name="planBefore">
<![CDATA[
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], EMPNO0=[$9], ENAME0=[$10], JOB0=[$11], MGR0=[$12], HIREDATE0=[$13], SAL0=[$14], COMM0=[$15], DEPTNO0=[$16], SLACKER0=[$17])
- LogicalJoin(condition=[AND(=($16, $7), NOT(OR(=($7, 4), =($7, 6))))], joinType=[inner])
+ LogicalJoin(condition=[AND(=($7, $16), NOT(OR(=($7, 4), =($7, 6))))], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
@@ -3590,7 +3590,7 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$
<Resource name="planAfter">
<![CDATA[
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], EMPNO0=[$9], ENAME0=[$10], JOB0=[$11], MGR0=[$12], HIREDATE0=[$13], SAL0=[$14], COMM0=[$15], DEPTNO0=[$16], SLACKER0=[$17])
- LogicalJoin(condition=[=($16, $7)], joinType=[inner])
+ LogicalJoin(condition=[=($7, $16)], joinType=[inner])
LogicalFilter(condition=[AND(<>($7, 4), <>($7, 6))])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalFilter(condition=[AND(<>($7, 4), <>($7, 6))])
@@ -3750,10 +3750,10 @@ LogicalProject(SAL=[$5])
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], SLACKER=[$8])
LogicalFilter(condition=[AND(=($7, 20), >($5, 1000))])
LogicalTableScan(table=[[CATALOG, SALES, EMPNULLABLES]])
- LogicalFilter(condition=[=($1, $0)])
+ LogicalFilter(condition=[=($0, $1)])
LogicalAggregate(group=[{0, 1}])
LogicalProject(SAL=[$5], SAL0=[$8])
- LogicalJoin(condition=[OR(=($8, $5), =($8, 4))], joinType=[inner])
+ LogicalJoin(condition=[OR(=($5, $8), =($8, 4))], joinType=[inner])
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], SLACKER=[$8])
LogicalFilter(condition=[AND(=($7, 20), >($5, 1000))])
LogicalTableScan(table=[[CATALOG, SALES, EMPNULLABLES]])
@@ -6414,7 +6414,7 @@ group by e.job]]>
<![CDATA[
LogicalAggregate(group=[{2}])
LogicalJoin(condition=[AND(=($2, $11), =($9, $12))], joinType=[full])
- LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, $0)])
+ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($0, $7)])
LogicalFilter(condition=[=($1, 'A')])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalProject(DEPTNO=[$0], NAME=[$1], $f2=[+($0, 5)])
@@ -6426,7 +6426,7 @@ LogicalAggregate(group=[{2}])
LogicalAggregate(group=[{0}])
LogicalJoin(condition=[AND(=($0, $2), =($1, $3))], joinType=[full])
LogicalAggregate(group=[{2, 9}])
- LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, $0)])
+ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($0, $7)])
LogicalFilter(condition=[=($1, 'A')])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalAggregate(group=[{1, 2}])
@@ -6596,7 +6596,7 @@ group by e.job]]>
<![CDATA[
LogicalAggregate(group=[{2}])
LogicalJoin(condition=[AND(=($2, $11), =($9, $12))], joinType=[left])
- LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, $0)])
+ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($0, $7)])
LogicalFilter(condition=[=($1, 'A')])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalProject(DEPTNO=[$0], NAME=[$1], $f2=[+($0, 5)])
@@ -6608,7 +6608,7 @@ LogicalAggregate(group=[{2}])
LogicalAggregate(group=[{0}])
LogicalJoin(condition=[AND(=($0, $2), =($1, $3))], joinType=[left])
LogicalAggregate(group=[{2, 9}])
- LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, $0)])
+ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($0, $7)])
LogicalFilter(condition=[=($1, 'A')])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalAggregate(group=[{1, 2}])
@@ -6629,7 +6629,7 @@ group by d.name]]>
<![CDATA[
LogicalAggregate(group=[{11}])
LogicalJoin(condition=[AND(=($2, $11), =($9, $12))], joinType=[left])
- LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, $0)])
+ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($0, $7)])
LogicalFilter(condition=[=($1, 'A')])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalProject(DEPTNO=[$0], NAME=[$1], $f2=[+($0, 5)])
@@ -6641,7 +6641,7 @@ LogicalAggregate(group=[{11}])
LogicalAggregate(group=[{2}])
LogicalJoin(condition=[AND(=($0, $2), =($1, $3))], joinType=[left])
LogicalAggregate(group=[{2, 9}])
- LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, $0)])
+ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($0, $7)])
LogicalFilter(condition=[=($1, 'A')])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalAggregate(group=[{1, 2}])
@@ -6662,7 +6662,7 @@ group by e.job, d.name]]>
<![CDATA[
LogicalAggregate(group=[{2, 11}])
LogicalJoin(condition=[AND(=($2, $11), =($9, $12))], joinType=[left])
- LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, $0)])
+ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($0, $7)])
LogicalFilter(condition=[=($1, 'A')])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalProject(DEPTNO=[$0], NAME=[$1], $f2=[+($0, 5)])
@@ -6674,7 +6674,7 @@ LogicalAggregate(group=[{2, 11}])
LogicalAggregate(group=[{0, 2}])
LogicalJoin(condition=[AND(=($0, $2), =($1, $3))], joinType=[left])
LogicalAggregate(group=[{2, 9}])
- LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, $0)])
+ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($0, $7)])
LogicalFilter(condition=[=($1, 'A')])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalAggregate(group=[{1, 2}])
@@ -6743,7 +6743,7 @@ join sales.dept as d on e.empno = d.deptno and e.deptno + e.empno = d.deptno + 5
<![CDATA[
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$10], NAME=[$11])
LogicalJoin(condition=[AND(=($0, $10), =($9, $12))], joinType=[inner])
- LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, $0)])
+ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($0, $7)])
LogicalFilter(condition=[=($0, 10)])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalProject(DEPTNO=[$0], NAME=[$1], $f2=[+($0, 5)])
@@ -6754,7 +6754,7 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$
<![CDATA[
LogicalProject(EMPNO=[10], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[10], NAME=[$11])
LogicalJoin(condition=[=($9, 15)], joinType=[inner])
- LogicalProject(EMPNO=[10], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, 10)])
+ LogicalProject(EMPNO=[10], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+(10, $7)])
LogicalFilter(condition=[=($0, 10)])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalProject(DEPTNO=[10], NAME=[$1], $f2=[15])
@@ -7868,13 +7868,13 @@ from emp]]>
<![CDATA[
LogicalProject($0=[$3], $1=[$4])
LogicalWindow(window#0=[window(partition {1} order by [0] aggs [SUM($1), SUM($2)])])
- LogicalProject(SAL=[$5], DEPTNO=[$7], $2=[+($7, $5)])
+ LogicalProject(SAL=[$5], DEPTNO=[$7], $2=[+($5, $7)])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
<Resource name="planBefore">
<![CDATA[
-LogicalProject(SUM1=[SUM($7) OVER (PARTITION BY $7 ORDER BY $5)], SUM2=[SUM(+($7, $5)) OVER (PARTITION BY $7 ORDER BY $5)])
+LogicalProject(SUM1=[SUM($7) OVER (PARTITION BY $7 ORDER BY $5)], SUM2=[SUM(+($5, $7)) OVER (PARTITION BY $7 ORDER BY $5)])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
@@ -7920,7 +7920,7 @@ group by e.job,d.name]]>
<![CDATA[
LogicalAggregate(group=[{2, 11}])
LogicalJoin(condition=[AND(=($2, $11), =($9, $12))], joinType=[inner])
- LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, $0)])
+ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($0, $7)])
LogicalFilter(condition=[=($1, 'A')])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalProject(DEPTNO=[$0], NAME=[$1], $f2=[+($0, 5)])
@@ -7932,7 +7932,7 @@ LogicalAggregate(group=[{2, 11}])
LogicalAggregate(group=[{0, 2}])
LogicalJoin(condition=[AND(=($0, $2), =($1, $3))], joinType=[inner])
LogicalAggregate(group=[{2, 9}])
- LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, $0)])
+ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($0, $7)])
LogicalFilter(condition=[=($1, 'A')])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalAggregate(group=[{1, 2}])
@@ -8466,7 +8466,7 @@ LogicalProject(EXPR$0=[1])
<![CDATA[
LogicalProject(EXPR$0=[1])
LogicalProject(DEPTNO=[$9], NAME=[$10], EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO0=[$7], SLACKER=[$8])
- LogicalJoin(condition=[=($9, $7)], joinType=[right])
+ LogicalJoin(condition=[=($7, $9)], joinType=[right])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
]]>
@@ -9742,7 +9742,7 @@ RIGHT JOIN sales.emp e ON e.deptno = d.deptno]]>
<Resource name="planBefore">
<![CDATA[
LogicalProject(DEPTNO=[$9])
- LogicalJoin(condition=[=($9, $0)], joinType=[right])
+ LogicalJoin(condition=[=($0, $9)], joinType=[right])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
@@ -9786,7 +9786,7 @@ RIGHT JOIN sales.emp e ON e.deptno = d.deptno]]>
<Resource name="planBefore">
<![CDATA[
LogicalProject(DEPTNO=[$9], NAME=[$1])
- LogicalJoin(condition=[=($9, $0)], joinType=[right])
+ LogicalJoin(condition=[=($0, $9)], joinType=[right])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
@@ -11289,7 +11289,7 @@ LogicalProject(DEPTNO=[$1])
</Resource>
<Resource name="planAfter">
<![CDATA[
-LogicalProject(EMPNO=[$0], D=[CASE(=($9, 0), false, IS NULL(CASE(true, CAST($7):INTEGER, null:INTEGER)), null:BOOLEAN, IS NOT NULL($12), true, <($10, $9), null:BOOLEAN, false)])
+LogicalProject(EMPNO=[$0], D=[CASE(=($9, 0), false, IS NULL(CASE(true, CAST($7):INTEGER, null:INTEGER)), null:BOOLEAN, IS NOT NULL($12), true, >($9, $10), null:BOOLEAN, false)])
LogicalJoin(condition=[=(CASE(true, CAST($7):INTEGER, null:INTEGER), $11)], joinType=[left])
LogicalJoin(condition=[true], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
@@ -11337,7 +11337,7 @@ LogicalProject(EXPR$0=[CASE(true, CAST($7):INTEGER, null:INTEGER)])
<![CDATA[
LogicalProject(EMPNO=[$0])
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
- LogicalFilter(condition=[<($0, CASE(OR(AND(IS NOT NULL($12), <>($9, 0)), AND(<($10, $9), null, <>($9, 0), IS NULL($12))), 10, AND(OR(IS NULL($12), =($9, 0)), OR(>=($10, $9), =($9, 0), IS NOT NULL($12))), 20, 30))])
+ LogicalFilter(condition=[<($0, CASE(OR(AND(IS NOT NULL($12), <>($9, 0)), AND(>($9, $10), null, <>($9, 0), IS NULL($12))), 10, AND(OR(IS NULL($12), =($9, 0)), OR(<=($9, $10), =($9, 0), IS NOT NULL($12))), 20, 30))])
LogicalJoin(condition=[=($7, $11)], joinType=[left])
LogicalJoin(condition=[true], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
@@ -11764,7 +11764,7 @@ LogicalProject(DEPTNO=[$0])
<Resource name="planAfter">
<![CDATA[
LogicalProject(SAL=[$5])
- LogicalFilter(condition=[OR(=($10, 0), IS NOT TRUE(OR(IS NOT NULL($13), <($11, $10))))])
+ LogicalFilter(condition=[OR(=($10, 0), IS NOT TRUE(OR(IS NOT NULL($13), >($10, $11))))])
LogicalJoin(condition=[AND(=($0, $12), =($2, $14))], joinType=[left])
LogicalJoin(condition=[=($2, $9)], joinType=[left])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
@@ -11779,7 +11779,7 @@ LogicalProject(SAL=[$5])
<![CDATA[
LogicalProject(SAL=[$5])
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
- LogicalFilter(condition=[OR(=($9, 0), IS NOT TRUE(OR(IS NOT NULL($12), <($10, $9))))])
+ LogicalFilter(condition=[OR(=($9, 0), IS NOT TRUE(OR(IS NOT NULL($12), >($9, $10))))])
LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{2}])
LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{2}])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
@@ -11856,7 +11856,7 @@ LogicalProject(EMPNO=[$1])
<![CDATA[
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
- LogicalFilter(condition=[OR(=($9, 0), IS NOT TRUE(OR(IS NOT NULL($12), <($10, $9))))])
+ LogicalFilter(condition=[OR(=($9, 0), IS NOT TRUE(OR(IS NOT NULL($12), >($9, $10))))])
LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{1}])
LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{1}])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
@@ -11875,7 +11875,7 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$
<Resource name="planAfter">
<![CDATA[
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
- LogicalFilter(condition=[OR(=($10, 0), IS NOT TRUE(OR(IS NOT NULL($13), <($11, $10))))])
+ LogicalFilter(condition=[OR(=($10, 0), IS NOT TRUE(OR(IS NOT NULL($13), >($10, $11))))])
LogicalJoin(condition=[AND(=($0, $12), =($1, $14))], joinType=[left])
LogicalJoin(condition=[=($1, $9)], joinType=[left])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
diff --git a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
index bff936c..2473830 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -104,7 +104,7 @@ LogicalAggregate(group=[{0, 1}])
<![CDATA[
LogicalProject(D=[$0], EXPR$1=[+($0, $1)])
LogicalAggregate(group=[{0, 1}])
- LogicalProject(D=[+($7, $0)], MGR=[$3])
+ LogicalProject(D=[+($0, $7)], MGR=[$3])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
@@ -1565,7 +1565,7 @@ order by sal + empno desc, sal * empno, sal + empno desc]]>
<![CDATA[
LogicalProject(EMPNO=[$0])
LogicalSort(sort0=[$1], sort1=[$2], dir0=[DESC], dir1=[ASC])
- LogicalProject(EMPNO=[$0], EXPR$1=[+($5, $0)], EXPR$2=[*($5, $0)])
+ LogicalProject(EMPNO=[$0], EXPR$1=[+($0, $5)], EXPR$2=[*($0, $5)])
LogicalJoin(condition=[true], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
@@ -1879,8 +1879,8 @@ order by c + a]]>
<![CDATA[
LogicalProject(A=[$0], B=[$1], C=[$2], DEPTNO=[$3], NAME=[$4])
LogicalSort(sort0=[$5], dir0=[ASC])
- LogicalProject(A=[$0], B=[$1], C=[$2], DEPTNO=[$3], NAME=[$4], EXPR$5=[+($2, $0)])
- LogicalJoin(condition=[=($3, $2)], joinType=[inner])
+ LogicalProject(A=[$0], B=[$1], C=[$2], DEPTNO=[$3], NAME=[$4], EXPR$5=[+($0, $2)])
+ LogicalJoin(condition=[=($2, $3)], joinType=[inner])
LogicalProject(A=[$2], B=[$1], C=[$0])
LogicalValues(tuples=[[{ 1, 2, 3 }]])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
@@ -2317,7 +2317,7 @@ JOIN dept on dept.deptno = emp.deptno + 0]]>
<Resource name="plan">
<![CDATA[
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$10], NAME=[$11])
- LogicalJoin(condition=[=($10, $9)], joinType=[inner])
+ LogicalJoin(condition=[=($9, $10)], joinType=[inner])
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, 0)])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
@@ -2407,7 +2407,7 @@ LogicalProject(D2=[$0], D3=[$1])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
LogicalAggregate(group=[{0, 1}], agg#0=[MIN($2)])
LogicalProject(D4=[$0], D6=[$2], $f0=[true])
- LogicalFilter(condition=[=($1, $0)])
+ LogicalFilter(condition=[=($0, $1)])
LogicalProject(D4=[+($0, 4)], D5=[+($0, 5)], D6=[+($0, 6)])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
]]>
@@ -2590,7 +2590,7 @@ from dept]]>
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(NAME=[$1], EXPR$1=[OR(AND(IS NOT NULL($6), <>($2, 0)), AND(<($3, $2), null, <>($2, 0), IS NULL($6)))])
+LogicalProject(NAME=[$1], EXPR$1=[OR(AND(IS NOT NULL($6), <>($2, 0)), AND(>($2, $3), null, <>($2, 0), IS NULL($6)))])
LogicalJoin(condition=[=($4, $5)], joinType=[left])
LogicalProject(DEPTNO=[$0], NAME=[$1], $f0=[$2], $f1=[$3], DEPTNO0=[$0])
LogicalJoin(condition=[true], joinType=[inner])
@@ -2612,7 +2612,7 @@ from emp]]>
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(EMPNO=[$0], EXPR$1=[OR(=($9, 0), AND(<($10, $9), null, <>($9, 0), IS NULL($13)), AND(<>($9, 0), IS NULL($13), >=($10, $9)))])
+LogicalProject(EMPNO=[$0], EXPR$1=[OR(=($9, 0), AND(>($9, $10), null, <>($9, 0), IS NULL($13)), AND(<>($9, 0), IS NULL($13), <=($9, $10)))])
LogicalJoin(condition=[=($11, $12)], joinType=[left])
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f0=[$9], $f1=[$10], DEPTNO0=[$7])
LogicalJoin(condition=[true], joinType=[inner])
@@ -2756,7 +2756,7 @@ from emp]]>
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(EMPNO=[$0], EXPR$1=[OR(=($9, 0), AND(<($10, $9), null, <>($9, 0), IS NULL($13)), AND(<>($9, 0), IS NULL($13), >=($10, $9)))])
+LogicalProject(EMPNO=[$0], EXPR$1=[OR(=($9, 0), AND(>($9, $10), null, <>($9, 0), IS NULL($13)), AND(<>($9, 0), IS NULL($13), <=($9, $10)))])
LogicalJoin(condition=[=($11, $12)], joinType=[left])
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f0=[$9], $f1=[$10], DEPTNO0=[$7])
LogicalJoin(condition=[true], joinType=[inner])
@@ -5711,7 +5711,7 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$
LogicalJoin(condition=[=($7, $11)], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalProject(DEPTNO=[$0], NAME=[$1], DEPTNO0=[$2])
- LogicalJoin(condition=[<($2, $0)], joinType=[inner])
+ LogicalJoin(condition=[>($0, $2)], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
LogicalAggregate(group=[{0}])
LogicalProject(DEPTNO=[$7])
@@ -5759,7 +5759,7 @@ LogicalProject(D2=[$0], D3=[$1])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
LogicalAggregate(group=[{0, 1}], agg#0=[MIN($2)])
LogicalProject(D4=[$0], D6=[$2], $f0=[true])
- LogicalFilter(condition=[=($1, $0)])
+ LogicalFilter(condition=[=($0, $1)])
LogicalProject(D4=[+($0, 4)], D5=[+($0, 5)], D6=[+($0, 6)])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
]]>
@@ -5883,7 +5883,7 @@ LogicalProject(EMPNO=[$0])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
LogicalAggregate(group=[{0}], agg#0=[MIN($1)])
LogicalProject(EMPNO0=[$9], $f0=[true])
- LogicalJoin(condition=[<($9, $0)], joinType=[inner])
+ LogicalJoin(condition=[>($0, $9)], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalAggregate(group=[{0}])
LogicalProject(EMPNO=[$0])
diff --git a/core/src/test/resources/org/apache/calcite/test/TopDownOptTest.xml b/core/src/test/resources/org/apache/calcite/test/TopDownOptTest.xml
index 3442857..f2507fa 100644
--- a/core/src/test/resources/org/apache/calcite/test/TopDownOptTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/TopDownOptTest.xml
@@ -579,7 +579,7 @@ on r.job=s.job and r.ename=s.ename]]>
<Resource name="planBefore">
<![CDATA[
LogicalProject(ENAME=[$0], JOB=[$1], SAL=[$2], COMM=[$3], ENAME0=[$4], JOB0=[$5], EXPR$2=[$6])
- LogicalJoin(condition=[AND(=($5, $1), =($4, $0))], joinType=[inner])
+ LogicalJoin(condition=[AND(=($1, $5), =($0, $4))], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, BONUS]])
LogicalAggregate(group=[{0, 1}], EXPR$2=[MAX($2)])
LogicalProject(ENAME=[$1], JOB=[$2], SAL=[$5])
@@ -606,7 +606,7 @@ on r.job=s.job and r.ename=s.ename]]>
<Resource name="planBefore">
<![CDATA[
LogicalProject(ENAME=[$0], JOB=[$1], SAL=[$2], COMM=[$3], ENAME0=[$4], JOB0=[$5], MGR=[$6], EXPR$3=[$7])
- LogicalJoin(condition=[AND(=($5, $1), =($4, $0))], joinType=[inner])
+ LogicalJoin(condition=[AND(=($1, $5), =($0, $4))], joinType=[inner])
LogicalTableScan(table=[[CATALOG, SALES, BONUS]])
LogicalAggregate(group=[{0, 1, 2}], EXPR$3=[MAX($3)])
LogicalProject(ENAME=[$1], JOB=[$2], MGR=[$3], SAL=[$5])
diff --git a/core/src/test/resources/sql/blank.iq b/core/src/test/resources/sql/blank.iq
index 2d69aaf..32d3bcb 100644
--- a/core/src/test/resources/sql/blank.iq
+++ b/core/src/test/resources/sql/blank.iq
@@ -89,7 +89,7 @@ insert into table2 values (NULL, 1), (2, 1);
# Checked on Oracle
!set lateDecorrelate true
select i, j from table1 where table1.j NOT IN (select i from table2 where table1.i=table2.j);
-EnumerableCalc(expr#0..7=[{inputs}], expr#8=[0], expr#9=[=($t3, $t8)], expr#10=[IS NULL($t1)], expr#11=[IS NOT NULL($t7)], expr#12=[<($t4, $t3)], expr#13=[OR($t10, $t11, $t12)], expr#14=[IS NOT TRUE($t13)], expr#15=[OR($t9, $t14)], proj#0..1=[{exprs}], $condition=[$t15])
+EnumerableCalc(expr#0..7=[{inputs}], expr#8=[0], expr#9=[=($t3, $t8)], expr#10=[IS NULL($t1)], expr#11=[IS NOT NULL($t7)], expr#12=[>($t3, $t4)], expr#13=[OR($t10, $t11, $t12)], expr#14=[IS NOT TRUE($t13)], expr#15=[OR($t9, $t14)], proj#0..1=[{exprs}], $condition=[$t15])
EnumerableHashJoin(condition=[AND(=($0, $6), =($1, $5))], joinType=[left])
EnumerableHashJoin(condition=[=($0, $2)], joinType=[left])
EnumerableTableScan(table=[[BLANK, TABLE1]])
diff --git a/core/src/test/resources/sql/sub-query.iq b/core/src/test/resources/sql/sub-query.iq
index 9a9df2f..254738d 100644
--- a/core/src/test/resources/sql/sub-query.iq
+++ b/core/src/test/resources/sql/sub-query.iq
@@ -32,7 +32,7 @@ where t1.x not in (select t2.x from t2);
(0 rows)
!ok
-EnumerableCalc(expr#0..4=[{inputs}], expr#5=[0], expr#6=[=($t1, $t5)], expr#7=[IS NULL($t4)], expr#8=[>=($t2, $t1)], expr#9=[IS NOT NULL($t0)], expr#10=[AND($t7, $t8, $t9)], expr#11=[OR($t6, $t10)], X=[$t0], $condition=[$t11])
+EnumerableCalc(expr#0..4=[{inputs}], expr#5=[0], expr#6=[=($t1, $t5)], expr#7=[IS NULL($t4)], expr#8=[<=($t1, $t2)], expr#9=[IS NOT NULL($t0)], expr#10=[AND($t7, $t8, $t9)], expr#11=[OR($t6, $t10)], X=[$t0], $condition=[$t11])
EnumerableHashJoin(condition=[=($0, $3)], joinType=[left])
EnumerableNestedLoopJoin(condition=[true], joinType=[inner])
EnumerableUnion(all=[true])
@@ -2048,7 +2048,7 @@ where sal + 100 not in (
!ok
EnumerableAggregate(group=[{}], C=[COUNT()])
- EnumerableCalc(expr#0..9=[{inputs}], expr#10=[0], expr#11=[=($t4, $t10)], expr#12=[IS NULL($t2)], expr#13=[IS NOT NULL($t7)], expr#14=[<($t5, $t4)], expr#15=[OR($t12, $t13, $t14)], expr#16=[IS NOT TRUE($t15)], expr#17=[OR($t11, $t16)], proj#0..9=[{exprs}], $condition=[$t17])
+ EnumerableCalc(expr#0..9=[{inputs}], expr#10=[0], expr#11=[=($t4, $t10)], expr#12=[IS NULL($t2)], expr#13=[IS NOT NULL($t7)], expr#14=[>($t4, $t5)], expr#15=[OR($t12, $t13, $t14)], expr#16=[IS NOT TRUE($t15)], expr#17=[OR($t11, $t16)], proj#0..9=[{exprs}], $condition=[$t17])
EnumerableHashJoin(condition=[AND(=($1, $8), =($2, $9))], joinType=[left])
EnumerableHashJoin(condition=[=($1, $3)], joinType=[left])
EnumerableCalc(expr#0..7=[{inputs}], proj#0..1=[{exprs}], SAL=[$t5])
diff --git a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidRules.java b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidRules.java
index c3b5d1d..9c4f4be 100644
--- a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidRules.java
+++ b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidRules.java
@@ -384,7 +384,7 @@ public class DruidRules {
return;
}
boolean hasRexCalls = false;
- for (RexNode rexNode : project.getChildExps()) {
+ for (RexNode rexNode : project.getProjects()) {
if (rexNode instanceof RexCall) {
hasRexCalls = true;
break;
diff --git a/piglet/src/main/java/org/apache/calcite/piglet/PigToSqlAggregateRule.java b/piglet/src/main/java/org/apache/calcite/piglet/PigToSqlAggregateRule.java
index bd94628..fb66415 100644
--- a/piglet/src/main/java/org/apache/calcite/piglet/PigToSqlAggregateRule.java
+++ b/piglet/src/main/java/org/apache/calcite/piglet/PigToSqlAggregateRule.java
@@ -200,7 +200,7 @@ public class PigToSqlAggregateRule extends RelOptRule {
relBuilder.push(oldBottomProject.getInput());
// First project all group keys, just copy from old one
for (int i = 0; i < oldAgg.getGroupCount(); i++) {
- newBottomProjects.add(oldBottomProject.getChildExps().get(i));
+ newBottomProjects.add(oldBottomProject.getProjects().get(i));
}
// If grouping aggregate is needed, project the whole ROW
if (needGoupingCol) {
@@ -235,8 +235,8 @@ public class PigToSqlAggregateRule extends RelOptRule {
} else {
// Add it to the projection list if we never project it before
// First get the ROW operator call
- final RexCall rowCall = (RexCall) oldBottomProject.getChildExps()
- .get(oldAgg.getGroupCount());
+ final RexCall rowCall = (RexCall) oldBottomProject.getProjects()
+ .get(oldAgg.getGroupCount());
// Get the corresponding column index in parent rel through the call operand list
final RexInputRef columRef = (RexInputRef) rowCall.getOperands().get(col);
final int newIndex = newBottomProjects.size();