Permalink
Browse files

Clean up RelNode.explain, to make it easier to extend. A RelNode deri…

…ved class can now call super.explainTerms, so only needs to describe the attributes it adds over its base class.
  • Loading branch information...
julianhyde committed Feb 24, 2013
1 parent 02b1c86 commit 4737cbbafc4051d0d70a3887f40461df7f4e3d03
Showing with 389 additions and 510 deletions.
  1. +2 −3 src/main/java/net/hydromatic/optiq/rules/java/JavaRules.java
  2. +2 −3 src/main/java/org/eigenbase/oj/rel/IterCalcRel.java
  3. +27 −44 src/main/java/org/eigenbase/rel/AbstractRelNode.java
  4. +11 −29 src/main/java/org/eigenbase/rel/AggregateRelBase.java
  5. +2 −3 src/main/java/org/eigenbase/rel/CalcRelBase.java
  6. +3 −11 src/main/java/org/eigenbase/rel/CorrelatorRel.java
  7. +6 −10 src/main/java/org/eigenbase/rel/EmptyRel.java
  8. +3 −5 src/main/java/org/eigenbase/rel/FilterRelBase.java
  9. +5 −11 src/main/java/org/eigenbase/rel/JoinRel.java
  10. +10 −12 src/main/java/org/eigenbase/rel/JoinRelBase.java
  11. +10 −12 src/main/java/org/eigenbase/rel/ProjectRelBase.java
  12. +11 −0 src/main/java/org/eigenbase/rel/RelFieldCollation.java
  13. +9 −1 src/main/java/org/eigenbase/rel/RelNode.java
  14. +7 −10 src/main/java/org/eigenbase/rel/SamplingRel.java
  15. +7 −10 src/main/java/org/eigenbase/rel/SetOpRel.java
  16. +3 −7 src/main/java/org/eigenbase/rel/SingleRel.java
  17. +10 −21 src/main/java/org/eigenbase/rel/SortRel.java
  18. +3 −6 src/main/java/org/eigenbase/rel/TableAccessRelBase.java
  19. +7 −8 src/main/java/org/eigenbase/rel/TableFunctionRelBase.java
  20. +10 −14 src/main/java/org/eigenbase/rel/TableModificationRelBase.java
  21. +20 −13 src/main/java/org/eigenbase/rel/ValuesRelBase.java
  22. +2 −3 src/main/java/org/eigenbase/rel/WindowedAggregateRel.java
  23. +3 −6 src/main/java/org/eigenbase/rel/jdbc/JdbcQuery.java
  24. +13 −29 src/main/java/org/eigenbase/rel/rules/MultiJoinRel.java
  25. +116 −92 src/main/java/org/eigenbase/relopt/RelOptPlanWriter.java
  26. +0 −1 src/main/java/org/eigenbase/relopt/RelOptUtil.java
  27. +34 −57 src/main/java/org/eigenbase/relopt/RelOptXmlPlanWriter.java
  28. +1 −1 src/main/java/org/eigenbase/relopt/RelTraitDef.java
  29. +6 −2 src/main/java/org/eigenbase/relopt/RelTraitSet.java
  30. +6 −10 src/main/java/org/eigenbase/relopt/volcano/AbstractConverter.java
  31. +11 −8 src/main/java/org/eigenbase/relopt/volcano/RelSubset.java
  32. +23 −57 src/main/java/org/eigenbase/rex/RexProgram.java
  33. +3 −5 src/test/java/org/eigenbase/relopt/volcano/VolcanoPlannerTest.java
  34. +3 −6 src/test/java/org/eigenbase/relopt/volcano/VolcanoPlannerTraitTest.java
@@ -550,9 +550,8 @@ public PhysType getPhysType() {
return physType;
}
public void explain(RelOptPlanWriter pw)
{
program.explainCalc(this, pw);
public RelOptPlanWriter explainTerms(RelOptPlanWriter pw) {
return program.explainCalc(super.explainTerms(pw));
}
public double getRows() {
@@ -105,9 +105,8 @@ public IterCalcRel(
// TODO jvs 10-May-2004: need a computeSelfCost which takes condition into
// account; maybe inherit from CalcRelBase?
public void explain(RelOptPlanWriter pw)
{
program.explainCalc(this, pw);
public RelOptPlanWriter explainTerms(RelOptPlanWriter pw) {
return program.explainCalc(super.explainTerms(pw));
}
protected String computeDigest()
@@ -299,9 +299,20 @@ public RelOptCost computeSelfCost(RelOptPlanner planner)
0);
}
public void explain(RelOptPlanWriter pw)
{
pw.explain(this, Util.emptyStringArray, Util.emptyObjectArray);
public final void explain(RelOptPlanWriter pw) {
explainTerms(pw).done(this);
}
/** Describes the inputs and attributes of this relational expression.
* Each node should call {@code super.explainTerms}, then call the
* {@link RelOptPlanWriter#input(String, RelNode)}
* and {@link RelOptPlanWriter#item(String, Object)} methods for each input
* and attribute.
*
* @param pw Plan writer
*/
public RelOptPlanWriter explainTerms(RelOptPlanWriter pw) {
return pw;
}
public RelNode onRegister(RelOptPlanner planner)
@@ -380,8 +391,6 @@ public RelOptTable getTable()
/**
* Computes the digest. Does not modify this object.
*
* @post return != null
*/
protected String computeDigest()
{
@@ -391,54 +400,28 @@ protected String computeDigest()
new PrintWriter(sw),
SqlExplainLevel.DIGEST_ATTRIBUTES)
{
public void explain(
RelNode rel,
String [] terms,
Object [] values)
protected void explain_(
RelNode rel, List<Pair<String, Object>> values)
{
List<RelNode> inputs = rel.getInputs();
RexNode [] childExps = rel.getChildExps();
assert terms.length
== (inputs.size() + childExps.length + values.length)
: "terms.length="
+ terms.length
+ " inputs.length=" + inputs.size()
+ " childExps.length=" + childExps.length
+ " values.length=" + values.length;
write(getRelTypeName());
for (int i = 0; i < traitSet.size(); i++) {
write(".");
write(traitSet.getTrait(i).toString());
pw.write(getRelTypeName());
for (RelTrait trait : traitSet) {
pw.write(".");
pw.write(trait.toString());
}
write("(");
pw.write("(");
int j = 0;
for (int i = 0; i < inputs.size(); i++) {
if (j > 0) {
write(",");
}
write(terms[j++] + "=" + inputs.get(i).getDigest());
}
for (int i = 0; i < childExps.length; i++) {
if (j > 0) {
write(",");
}
RexNode childExp = childExps[i];
write(terms[j++] + "=" + childExp.toString());
}
for (int i = 0; i < values.length; i++) {
Object value = values[i];
if (j > 0) {
write(",");
for (Pair<String, Object> value : values) {
if (j++ > 0) {
pw.write(",");
}
write(terms[j++] + "=" + value);
pw.write(value.left + "=" + value.right);
}
write(")");
pw.write(")");
}
};
explain(pw);
pw.flush();
return sw.toString();
}
}
@@ -27,6 +27,8 @@
import org.eigenbase.sql.validate.*;
import org.eigenbase.util.*;
import net.hydromatic.linq4j.Ord;
/**
* <code>AggregateRelBase</code> is an abstract base class for implementations
@@ -120,39 +122,19 @@ public BitSet getGroupSet()
return groupSet;
}
public void explain(RelOptPlanWriter pw)
{
List<String> names = new ArrayList<String>();
List<Object> values = new ArrayList<Object>();
populateExplainAttributes(names, values);
pw.explain(this, names, values);
}
/**
* Populates attributes for EXPLAIN.
*
* @param names Names of attributes
* @param values Values of attributes
*/
protected void populateExplainAttributes(
List<String> names,
List<Object> values)
{
names.add("child");
names.add("group");
values.add(groupSet);
int i = -1;
for (AggregateCall aggCall : aggCalls) {
++i;
public RelOptPlanWriter explainTerms(RelOptPlanWriter pw) {
super.explainTerms(pw)
.item("group", groupSet);
for (Ord<AggregateCall> ord : Ord.zip(aggCalls)) {
final String name;
if (aggCall.getName() != null) {
name = aggCall.getName();
if (ord.e.getName() != null) {
name = ord.e.getName();
} else {
name = "agg#" + i;
name = "agg#" + ord.i;
}
names.add(name);
values.add(aggCall);
pw.item(name, ord.e);
}
return pw;
}
// implement RelNode
@@ -129,9 +129,8 @@ public RelOptCost computeSelfCost(RelOptPlanner planner)
return RexNode.EMPTY_ARRAY;
}
public void explain(RelOptPlanWriter pw)
{
program.explainCalc(this, pw);
public RelOptPlanWriter explainTerms(RelOptPlanWriter pw) {
return program.explainCalc(super.explainTerms(pw));
}
}
@@ -120,17 +120,9 @@ public CorrelatorRel copy(
joinType);
}
public void explain(RelOptPlanWriter pw)
{
pw.explain(
this,
new String[] {
"left", "right", "condition", "joinType", "correlations"
},
new Object[] {
joinType.name().toLowerCase(),
correlations
});
public RelOptPlanWriter explainTerms(RelOptPlanWriter pw) {
return super.explainTerms(pw)
.item("correlations", correlations);
}
/**
@@ -93,19 +93,15 @@ public double getRows()
}
// implement RelNode
public void explain(RelOptPlanWriter pw)
{
if (pw.getDetailLevel() == SqlExplainLevel.DIGEST_ATTRIBUTES) {
public RelOptPlanWriter explainTerms(RelOptPlanWriter pw) {
return super.explainTerms(pw)
// For rel digest, include the row type to discriminate
// this from other empties with different row types.
pw.explain(
this,
new String[] { "type", },
new Object[] { rowType });
} else {
// For normal EXPLAIN PLAN, omit the type.
super.explain(pw);
}
.itemIf(
"type",
rowType,
pw.getDetailLevel() == SqlExplainLevel.DIGEST_ATTRIBUTES);
}
}
@@ -107,11 +107,9 @@ public static double estimateFilteredRows(RelNode child, RexNode condition)
* RelMetadataQuery.getSelectivity(child, condition);
}
public void explain(RelOptPlanWriter pw)
{
pw.explain(
this,
new String[] { "child", "condition" });
public RelOptPlanWriter explainTerms(RelOptPlanWriter pw) {
return super.explainTerms(pw)
.item("condition", condition);
}
}
@@ -146,22 +146,16 @@ public JoinRel copy(
systemFieldList);
}
public void explain(RelOptPlanWriter pw)
public RelOptPlanWriter explainTerms(RelOptPlanWriter pw)
{
// NOTE jvs 14-Mar-2006: Do it this way so that semijoin state
// don't clutter things up in optimizers that don't use semijoins
if (!semiJoinDone) {
super.explain(pw);
return;
return super.explainTerms(pw);
}
pw.explain(
this,
new String[] {
"left", "right", "condition", "joinType", "semiJoinDone"
},
new Object[] {
joinType.name().toLowerCase(), semiJoinDone
});
return super.explainTerms(pw)
.item("joinType", joinType.name().toLowerCase())
.item("semiJoinDone", semiJoinDone);
}
/**
@@ -201,18 +201,16 @@ public void childrenAccept(RelVisitor visitor)
visitor.visit(right, 1, this);
}
public void explain(RelOptPlanWriter pw)
{
final List<String> nameList =
new ArrayList<String>(Arrays.asList("left", "right", "condition"));
final List<Object> valueList = new ArrayList<Object>();
nameList.add("joinType");
valueList.add(joinType.name().toLowerCase());
if (!getSystemFieldList().isEmpty()) {
nameList.add("systemFields");
valueList.add(getSystemFieldList());
}
pw.explain(this, nameList, valueList);
public RelOptPlanWriter explainTerms(RelOptPlanWriter pw) {
return super.explainTerms(pw)
.input("left", left)
.input("right", right)
.item("condition", condition)
.item("joinType", joinType.name().toLowerCase())
.itemIf(
"systemFields",
getSystemFieldList(),
!getSystemFieldList().isEmpty());
}
public void registerStoppedVariable(String name)
@@ -26,6 +26,8 @@
import org.eigenbase.rex.*;
import org.eigenbase.sql.*;
import net.hydromatic.linq4j.Ord;
/**
* <code>ProjectRelBase</code> is an abstract base class for implementations of
@@ -159,17 +161,14 @@ public RelOptCost computeSelfCost(RelOptPlanner planner)
return planner.makeCost(dRows, dCpu, dIo);
}
public void explain(RelOptPlanWriter pw)
{
List<String> terms = new ArrayList<String>();
List<Object> values = new ArrayList<Object>();
terms.add("child");
for (RelDataTypeField field : rowType.getFields()) {
String fieldName = field.getName();
public RelOptPlanWriter explainTerms(RelOptPlanWriter pw) {
super.explainTerms(pw);
for (Ord<RelDataTypeField> field : Ord.zip(rowType.getFields())) {
String fieldName = field.e.getName();
if (fieldName == null) {
fieldName = "field#" + (terms.size() - 1);
fieldName = "field#" + field.i;
}
terms.add(fieldName);
pw.item(fieldName, exps[field.i]);
}
// If we're generating a digest, include the rowtype. If two projects
@@ -179,11 +178,10 @@ public void explain(RelOptPlanWriter pw)
if ((pw.getDetailLevel() == SqlExplainLevel.DIGEST_ATTRIBUTES)
&& false)
{
terms.add("type");
values.add(rowType);
pw.item("type", rowType);
}
pw.explain(this, terms, values);
return pw;
}
/**
@@ -168,6 +168,17 @@ public String toString()
? ""
: " " + nullDirection);
}
public String shortString() {
switch (nullDirection) {
case FIRST:
return direction + "-nulls-first";
case LAST:
return direction + "-nulls-last";
default:
return direction.toString();
}
}
}
// End RelFieldCollation.java
Oops, something went wrong.

0 comments on commit 4737cbb

Please sign in to comment.