You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by vl...@apache.org on 2019/01/04 17:18:13 UTC
[calcite] branch master updated: [CALCITE-2471] Shorten
AbstractRelNode#computeDigest() digest (Laurent Goujon)
This is an automated email from the ASF dual-hosted git repository.
vladimirsitnikov 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 9667f85 [CALCITE-2471] Shorten AbstractRelNode#computeDigest() digest (Laurent Goujon)
9667f85 is described below
commit 9667f8537010d21556a592bd0dfbf20f7d0a4411
Author: Laurent Goujon <la...@apache.org>
AuthorDate: Thu Aug 16 08:54:16 2018 -0700
[CALCITE-2471] Shorten AbstractRelNode#computeDigest() digest (Laurent Goujon)
Digest/description created by AbstractRelNode#computeDigest includes
the description of each of its inputs, causing the final string to
be excessively long (e.g. the top level node of a tree containing
the string representation of the whole tree).
Change the function to not use the input's description but instead
its original description which is <typeName>#<id>.
fixes #795
---
.../org/apache/calcite/rel/AbstractRelNode.java | 20 ++++++----
.../org/apache/calcite/test/HepPlannerTest.java | 44 ++++++++++++++++++++++
2 files changed, 57 insertions(+), 7 deletions(-)
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 6518067..59a9179 100644
--- a/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
+++ b/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java
@@ -354,13 +354,10 @@ public abstract class AbstractRelNode implements RelNode {
public String recomputeDigest() {
String tempDigest = computeDigest();
- assert tempDigest != null : "post: return != null";
- String prefix = "rel#" + id + ":";
+ assert tempDigest != null : "computeDigest() should be non-null";
- // Substring uses the same underlying array of chars, so saves a bit
- // of memory.
- this.desc = prefix + tempDigest;
- this.digest = this.desc.substring(prefix.length());
+ this.desc = "rel#" + id + ":" + tempDigest;
+ this.digest = tempDigest;
return this.digest;
}
@@ -412,7 +409,16 @@ public abstract class AbstractRelNode implements RelNode {
if (j++ > 0) {
pw.write(",");
}
- pw.write(value.left + "=" + value.right);
+ pw.write(value.left);
+ pw.write("=");
+ if (value.right instanceof RelNode) {
+ RelNode input = (RelNode) value.right;
+ pw.write(input.getRelTypeName());
+ pw.write("#");
+ pw.write(Integer.toString(input.getId()));
+ } else {
+ pw.write(String.valueOf(value.right));
+ }
}
pw.write(")");
}
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 8eb78d5..2e354e0 100644
--- a/core/src/test/java/org/apache/calcite/test/HepPlannerTest.java
+++ b/core/src/test/java/org/apache/calcite/test/HepPlannerTest.java
@@ -23,6 +23,7 @@ import org.apache.calcite.plan.hep.HepPlanner;
import org.apache.calcite.plan.hep.HepProgram;
import org.apache.calcite.plan.hep.HepProgramBuilder;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.RelRoot;
import org.apache.calcite.rel.core.RelFactories;
import org.apache.calcite.rel.logical.LogicalIntersect;
import org.apache.calcite.rel.logical.LogicalUnion;
@@ -125,6 +126,49 @@ public class HepPlannerTest extends RelOptTestBase {
"select name from sales.dept where deptno=12");
}
+ /**
+ * Ensures {@link org.apache.calcite.rel.AbstractRelNode} digest does not include
+ * full digest tree.
+ */
+ @Test public void relDigestLength() {
+ HepProgramBuilder programBuilder = HepProgram.builder();
+ HepPlanner planner =
+ new HepPlanner(
+ programBuilder.build());
+ StringBuilder sb = new StringBuilder();
+ final int n = 10;
+ sb.append("select * from (");
+ sb.append("select name from sales.dept");
+ for (int i = 0; i < n; i++) {
+ sb.append(" union all select name from sales.dept");
+ }
+ sb.append(")");
+ RelRoot root = tester.convertSqlToRel(sb.toString());
+ planner.setRoot(root.rel);
+ RelNode best = planner.findBestExp();
+
+ // Good digest should look like rel#66:LogicalProject(input=rel#64:LogicalUnion)
+ // 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.getDescription(), "LogicalUnion");
+ assertIncludesExactlyOnce("best.getDigest()", best.getDigest(), "LogicalUnion");
+ }
+
+ private void assertIncludesExactlyOnce(String message, String digest, String substring) {
+ int pos = 0;
+ int cnt = 0;
+ while (pos >= 0) {
+ pos = digest.indexOf(substring, pos + 1);
+ if (pos > 0) {
+ cnt++;
+ }
+ }
+ assertEquals(
+ message + " should include <<" + substring + ">> exactly once, actual value is " + digest,
+ 1, cnt);
+ }
+
@Test public void testMatchLimitOneTopDown() throws Exception {
// Verify that only the top union gets rewritten.