You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2016/01/21 23:39:08 UTC
[31/50] [abbrv] calcite git commit: [CALCITE-794] Detect cycles when
computing statistics
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java
index 2a6431d..c872075 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdColumnUniqueness.java
@@ -44,7 +44,6 @@ import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.ImmutableBitSet;
-import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
@@ -67,55 +66,53 @@ public class RelMdColumnUniqueness {
//~ Methods ----------------------------------------------------------------
- public Boolean areColumnsUnique(
- TableScan rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
+ public Boolean areColumnsUnique(TableScan rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
return rel.getTable().isKey(columns);
}
- public Boolean areColumnsUnique(
- Filter rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
- return RelMetadataQuery.areColumnsUnique(
- rel.getInput(),
- columns,
- ignoreNulls);
+ public Boolean areColumnsUnique(Filter rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
+ return mq.areColumnsUnique(rel.getInput(), columns, ignoreNulls);
}
- public Boolean areColumnsUnique(
- Sort rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
- return RelMetadataQuery.areColumnsUnique(
- rel.getInput(),
- columns,
- ignoreNulls);
+ /** Catch-all implementation for
+ * {@link BuiltInMetadata.ColumnUniqueness#areColumnsUnique(ImmutableBitSet, boolean)},
+ * invoked using reflection, for any relational expression not
+ * handled by a more specific method.
+ *
+ * @param rel Relational expression
+ * @param mq Metadata query
+ * @param columns column mask representing the subset of columns for which
+ * uniqueness will be determined
+ * @param ignoreNulls if true, ignore null values when determining column
+ * uniqueness
+ * @return whether the columns are unique, or
+ * null if not enough information is available to make that determination
+ *
+ * @see org.apache.calcite.rel.metadata.RelMetadataQuery#areColumnsUnique(RelNode, ImmutableBitSet, boolean)
+ */
+ public Boolean areColumnsUnique(RelNode rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
+ // no information available
+ return null;
}
- public Boolean areColumnsUnique(
- SetOp rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
+ public Boolean areColumnsUnique(SetOp rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
// If not ALL then the rows are distinct.
// Therefore the set of all columns is a key.
return !rel.all
&& columns.nextClearBit(0) >= rel.getRowType().getFieldCount();
}
- public Boolean areColumnsUnique(
- Intersect rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
- if (areColumnsUnique((SetOp) rel, columns, ignoreNulls)) {
+ public Boolean areColumnsUnique(Intersect rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
+ if (areColumnsUnique((SetOp) rel, mq, columns, ignoreNulls)) {
return true;
}
for (RelNode input : rel.getInputs()) {
- Boolean b = RelMetadataQuery.areColumnsUnique(
- input,
- columns,
- ignoreNulls);
+ Boolean b = mq.areColumnsUnique(input, columns, ignoreNulls);
if (b != null && b) {
return true;
}
@@ -123,43 +120,31 @@ public class RelMdColumnUniqueness {
return false;
}
- public Boolean areColumnsUnique(
- Minus rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
- if (areColumnsUnique((SetOp) rel, columns, ignoreNulls)) {
+ public Boolean areColumnsUnique(Minus rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
+ if (areColumnsUnique((SetOp) rel, mq, columns, ignoreNulls)) {
return true;
}
- return RelMetadataQuery.areColumnsUnique(
- rel.getInput(0),
- columns,
- ignoreNulls);
+ return mq.areColumnsUnique(rel.getInput(0), columns, ignoreNulls);
}
- public Boolean areColumnsUnique(
- Exchange rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
- return RelMetadataQuery.areColumnsUnique(
- rel.getInput(),
- columns,
- ignoreNulls);
+ public Boolean areColumnsUnique(Sort rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
+ return mq.areColumnsUnique(rel.getInput(), columns, ignoreNulls);
}
- public Boolean areColumnsUnique(
- Correlate rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
- return RelMetadataQuery.areColumnsUnique(
- rel.getLeft(),
- columns,
- ignoreNulls);
+ public Boolean areColumnsUnique(Exchange rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
+ return mq.areColumnsUnique(rel.getInput(), columns, ignoreNulls);
+ }
+
+ public Boolean areColumnsUnique(Correlate rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
+ return mq.areColumnsUnique(rel.getLeft(), columns, ignoreNulls);
}
- public Boolean areColumnsUnique(
- Project rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
+ public Boolean areColumnsUnique(Project rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
// LogicalProject maps a set of rows to a different set;
// Without knowledge of the mapping function(whether it
// preserves uniqueness), it is only safe to derive uniqueness
@@ -211,16 +196,12 @@ public class RelMdColumnUniqueness {
return null;
}
- return RelMetadataQuery.areColumnsUnique(
- rel.getInput(),
- childColumns.build(),
+ return mq.areColumnsUnique(rel.getInput(), childColumns.build(),
ignoreNulls);
}
- public Boolean areColumnsUnique(
- Join rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
+ public Boolean areColumnsUnique(Join rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
if (columns.cardinality() == 0) {
return false;
}
@@ -245,11 +226,9 @@ public class RelMdColumnUniqueness {
// right hand side, then the columns are unique if and only if they're
// unique for their respective join inputs
final ImmutableBitSet leftColumns = leftBuilder.build();
- Boolean leftUnique =
- RelMetadataQuery.areColumnsUnique(left, leftColumns, ignoreNulls);
+ Boolean leftUnique = mq.areColumnsUnique(left, leftColumns, ignoreNulls);
final ImmutableBitSet rightColumns = rightBuilder.build();
- Boolean rightUnique =
- RelMetadataQuery.areColumnsUnique(right, rightColumns, ignoreNulls);
+ Boolean rightUnique = mq.areColumnsUnique(right, rightColumns, ignoreNulls);
if ((leftColumns.cardinality() > 0)
&& (rightColumns.cardinality() > 0)) {
if ((leftUnique == null) || (rightUnique == null)) {
@@ -271,8 +250,7 @@ public class RelMdColumnUniqueness {
return false;
}
Boolean rightJoinColsUnique =
- RelMetadataQuery.areColumnsUnique(right, joinInfo.rightSet(),
- ignoreNulls);
+ mq.areColumnsUnique(right, joinInfo.rightSet(), ignoreNulls);
if ((rightJoinColsUnique == null) || (leftUnique == null)) {
return null;
}
@@ -282,8 +260,7 @@ public class RelMdColumnUniqueness {
return false;
}
Boolean leftJoinColsUnique =
- RelMetadataQuery.areColumnsUnique(left, joinInfo.leftSet(),
- ignoreNulls);
+ mq.areColumnsUnique(left, joinInfo.leftSet(), ignoreNulls);
if ((leftJoinColsUnique == null) || (rightUnique == null)) {
return null;
}
@@ -293,56 +270,28 @@ public class RelMdColumnUniqueness {
throw new AssertionError();
}
- public Boolean areColumnsUnique(
- SemiJoin rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
+ public Boolean areColumnsUnique(SemiJoin rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
// only return the unique keys from the LHS since a semijoin only
// returns the LHS
- return RelMetadataQuery.areColumnsUnique(
- rel.getLeft(),
- columns,
- ignoreNulls);
+ return mq.areColumnsUnique(rel.getLeft(), columns, ignoreNulls);
}
- public Boolean areColumnsUnique(
- Aggregate rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
+ public Boolean areColumnsUnique(Aggregate rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
// group by keys form a unique key
ImmutableBitSet groupKey = ImmutableBitSet.range(rel.getGroupCount());
return columns.contains(groupKey);
}
- // Catch-all rule when none of the others apply.
- public Boolean areColumnsUnique(
- RelNode rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
- // no information available
- return null;
- }
-
- public Boolean areColumnsUnique(
- Converter rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
- return RelMetadataQuery.areColumnsUnique(
- rel.getInput(),
- columns,
- ignoreNulls);
- }
-
- public Boolean areColumnsUnique(
- Values rel,
- RelMetadataQuery query,
- boolean ignoreNulls) {
- if (rel.getTuples().size() < 2) {
+ public Boolean areColumnsUnique(Values rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
+ if (rel.tuples.size() < 2) {
return true;
}
final Set<List<Comparable>> set = new HashSet<>();
final List<Comparable> values = new ArrayList<>();
- for (ImmutableList<RexLiteral> tuple : rel.getTuples()) {
+ for (ImmutableList<RexLiteral> tuple : rel.tuples) {
for (RexLiteral literal : tuple) {
values.add(NullSentinel.mask(literal.getValue()));
}
@@ -354,36 +303,64 @@ public class RelMdColumnUniqueness {
return true;
}
- public Boolean areColumnsUnique(
+ public Boolean areColumnsUnique(Converter rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
+ return mq.areColumnsUnique(rel.getInput(), columns, ignoreNulls);
+ }
+
+ public Boolean areColumnsUnique(HepRelVertex rel, RelMetadataQuery mq,
boolean dummy, // prevent method from being used
- HepRelVertex rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
- return RelMetadataQuery.areColumnsUnique(
- rel.getCurrentRel(),
- columns,
- ignoreNulls);
+ ImmutableBitSet columns, boolean ignoreNulls) {
+ return mq.areColumnsUnique(rel.getCurrentRel(), columns, ignoreNulls);
}
- public Boolean areColumnsUnique(
- RelSubset rel,
- ImmutableBitSet columns,
- boolean ignoreNulls) {
- final RelNode best = rel.getBest();
- if (best == null) {
- return null;
- } else {
- return RelMetadataQuery.areColumnsUnique(best, columns, ignoreNulls);
+ public Boolean areColumnsUnique(RelSubset rel, RelMetadataQuery mq,
+ ImmutableBitSet columns, boolean ignoreNulls) {
+ int nullCount = 0;
+ for (RelNode rel2 : rel.getRels()) {
+ if (rel2 instanceof Aggregate
+ || rel2 instanceof Filter
+ || rel2 instanceof Values
+ || rel2 instanceof TableScan
+ || simplyProjects(rel2, columns)) {
+ try {
+ final Boolean unique = mq.areColumnsUnique(rel2, columns, ignoreNulls);
+ if (unique != null) {
+ if (unique) {
+ return true;
+ }
+ } else {
+ ++nullCount;
+ }
+ } catch (CyclicMetadataException e) {
+ // Ignore this relational expression; there will be non-cyclic ones
+ // in this set.
+ }
+ }
}
+ return nullCount == 0 ? false : null;
}
- /** Aggregate and Calc are "safe" children of a RelSubset to delve into. */
- private static final Predicate<RelNode> SAFE_REL =
- new Predicate<RelNode>() {
- public boolean apply(RelNode r) {
- return r instanceof Aggregate || r instanceof Project;
- }
- };
+ private boolean simplyProjects(RelNode rel, ImmutableBitSet columns) {
+ if (!(rel instanceof Project)) {
+ return false;
+ }
+ Project project = (Project) rel;
+ final List<RexNode> projects = project.getProjects();
+ for (int column : columns) {
+ if (column >= projects.size()) {
+ return false;
+ }
+ if (!(projects.get(column) instanceof RexInputRef)) {
+ return false;
+ }
+ final RexInputRef ref = (RexInputRef) projects.get(column);
+ if (ref.getIndex() != column) {
+ return false;
+ }
+ }
+ return true;
+ }
}
// End RelMdColumnUniqueness.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistinctRowCount.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistinctRowCount.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistinctRowCount.java
index 2fb2b25..eef245e 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistinctRowCount.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistinctRowCount.java
@@ -17,6 +17,7 @@
package org.apache.calcite.rel.metadata;
import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.plan.volcano.RelSubset;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.Exchange;
@@ -31,6 +32,7 @@ import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.util.Bug;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.NumberUtil;
@@ -54,10 +56,27 @@ public class RelMdDistinctRowCount {
//~ Methods ----------------------------------------------------------------
- public Double getDistinctRowCount(
- Union rel,
- ImmutableBitSet groupKey,
- RexNode predicate) {
+ /** Catch-all implementation for
+ * {@link BuiltInMetadata.DistinctRowCount#getDistinctRowCount(ImmutableBitSet, RexNode)},
+ * invoked using reflection.
+ *
+ * @see org.apache.calcite.rel.metadata.RelMetadataQuery#getDistinctRowCount(RelNode, ImmutableBitSet, RexNode)
+ */
+ public Double getDistinctRowCount(RelNode rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, RexNode predicate) {
+ // REVIEW zfong 4/19/06 - Broadbase code does not take into
+ // consideration selectivity of predicates passed in. Also, they
+ // assume the rows are unique even if the table is not
+ boolean uniq = RelMdUtil.areColumnsDefinitelyUnique(mq, rel, groupKey);
+ if (uniq) {
+ return NumberUtil.multiply(mq.getRowCount(rel),
+ mq.getSelectivity(rel, predicate));
+ }
+ return null;
+ }
+
+ public Double getDistinctRowCount(Union rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, RexNode predicate) {
Double rowCount = 0.0;
int[] adjustments = new int[rel.getRowType().getFieldCount()];
RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
@@ -76,10 +95,7 @@ public class RelMdDistinctRowCount {
adjustments));
}
Double partialRowCount =
- RelMetadataQuery.getDistinctRowCount(
- input,
- groupKey,
- modifiedPred);
+ mq.getDistinctRowCount(input, groupKey, modifiedPred);
if (partialRowCount == null) {
return null;
}
@@ -88,30 +104,18 @@ public class RelMdDistinctRowCount {
return rowCount;
}
- public Double getDistinctRowCount(
- Sort rel,
- ImmutableBitSet groupKey,
- RexNode predicate) {
- return RelMetadataQuery.getDistinctRowCount(
- rel.getInput(),
- groupKey,
- predicate);
+ public Double getDistinctRowCount(Sort rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, RexNode predicate) {
+ return mq.getDistinctRowCount(rel.getInput(), groupKey, predicate);
}
- public Double getDistinctRowCount(
- Exchange rel,
- ImmutableBitSet groupKey,
- RexNode predicate) {
- return RelMetadataQuery.getDistinctRowCount(
- rel.getInput(),
- groupKey,
- predicate);
+ public Double getDistinctRowCount(Exchange rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, RexNode predicate) {
+ return mq.getDistinctRowCount(rel.getInput(), groupKey, predicate);
}
- public Double getDistinctRowCount(
- Filter rel,
- ImmutableBitSet groupKey,
- RexNode predicate) {
+ public Double getDistinctRowCount(Filter rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, RexNode predicate) {
if (predicate == null || predicate.isAlwaysTrue()) {
if (groupKey.isEmpty()) {
return 1D;
@@ -126,33 +130,22 @@ public class RelMdDistinctRowCount {
predicate,
rel.getCondition());
- return RelMetadataQuery.getDistinctRowCount(
- rel.getInput(),
- groupKey,
- unionPreds);
+ return mq.getDistinctRowCount(rel.getInput(), groupKey, unionPreds);
}
- public Double getDistinctRowCount(
- Join rel,
- ImmutableBitSet groupKey,
- RexNode predicate) {
+ public Double getDistinctRowCount(Join rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, RexNode predicate) {
if (predicate == null || predicate.isAlwaysTrue()) {
if (groupKey.isEmpty()) {
return 1D;
}
}
- return RelMdUtil.getJoinDistinctRowCount(
- rel,
- rel.getJoinType(),
- groupKey,
- predicate,
- false);
+ return RelMdUtil.getJoinDistinctRowCount(mq, rel, rel.getJoinType(),
+ groupKey, predicate, false);
}
- public Double getDistinctRowCount(
- SemiJoin rel,
- ImmutableBitSet groupKey,
- RexNode predicate) {
+ public Double getDistinctRowCount(SemiJoin rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, RexNode predicate) {
if (predicate == null || predicate.isAlwaysTrue()) {
if (groupKey.isEmpty()) {
return 1D;
@@ -160,7 +153,7 @@ public class RelMdDistinctRowCount {
}
// create a RexNode representing the selectivity of the
// semijoin filter and pass it to getDistinctRowCount
- RexNode newPred = RelMdUtil.makeSemiJoinSelectivityRexNode(rel);
+ RexNode newPred = RelMdUtil.makeSemiJoinSelectivityRexNode(mq, rel);
if (predicate != null) {
RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
newPred =
@@ -170,16 +163,11 @@ public class RelMdDistinctRowCount {
predicate);
}
- return RelMetadataQuery.getDistinctRowCount(
- rel.getLeft(),
- groupKey,
- newPred);
+ return mq.getDistinctRowCount(rel.getLeft(), groupKey, newPred);
}
- public Double getDistinctRowCount(
- Aggregate rel,
- ImmutableBitSet groupKey,
- RexNode predicate) {
+ public Double getDistinctRowCount(Aggregate rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, RexNode predicate) {
if (predicate == null || predicate.isAlwaysTrue()) {
if (groupKey.isEmpty()) {
return 1D;
@@ -187,8 +175,8 @@ public class RelMdDistinctRowCount {
}
// determine which predicates can be applied on the child of the
// aggregate
- List<RexNode> notPushable = new ArrayList<RexNode>();
- List<RexNode> pushable = new ArrayList<RexNode>();
+ final List<RexNode> notPushable = new ArrayList<>();
+ final List<RexNode> pushable = new ArrayList<>();
RelOptUtil.splitFilters(
rel.getGroupSet(),
predicate,
@@ -203,10 +191,7 @@ public class RelMdDistinctRowCount {
RelMdUtil.setAggChildKeys(groupKey, rel, childKey);
Double distinctRowCount =
- RelMetadataQuery.getDistinctRowCount(
- rel.getInput(),
- childKey.build(),
- childPreds);
+ mq.getDistinctRowCount(rel.getInput(), childKey.build(), childPreds);
if (distinctRowCount == null) {
return null;
} else if (notPushable.isEmpty()) {
@@ -218,10 +203,8 @@ public class RelMdDistinctRowCount {
}
}
- public Double getDistinctRowCount(
- Values rel,
- ImmutableBitSet groupKey,
- RexNode predicate) {
+ public Double getDistinctRowCount(Values rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, RexNode predicate) {
if (predicate == null || predicate.isAlwaysTrue()) {
if (groupKey.isEmpty()) {
return 1D;
@@ -230,14 +213,12 @@ public class RelMdDistinctRowCount {
Double selectivity = RelMdUtil.guessSelectivity(predicate);
// assume half the rows are duplicates
- Double nRows = rel.getRows() / 2;
+ Double nRows = rel.estimateRowCount(mq) / 2;
return RelMdUtil.numDistinctVals(nRows, nRows * selectivity);
}
- public Double getDistinctRowCount(
- Project rel,
- ImmutableBitSet groupKey,
- RexNode predicate) {
+ public Double getDistinctRowCount(Project rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, RexNode predicate) {
if (predicate == null || predicate.isAlwaysTrue()) {
if (groupKey.isEmpty()) {
return 1D;
@@ -248,8 +229,8 @@ public class RelMdDistinctRowCount {
List<RexNode> projExprs = rel.getProjects();
RelMdUtil.splitCols(projExprs, groupKey, baseCols, projCols);
- List<RexNode> notPushable = new ArrayList<RexNode>();
- List<RexNode> pushable = new ArrayList<RexNode>();
+ final List<RexNode> notPushable = new ArrayList<>();
+ final List<RexNode> pushable = new ArrayList<>();
RelOptUtil.splitFilters(
ImmutableBitSet.range(rel.getRowType().getFieldCount()),
predicate,
@@ -269,9 +250,7 @@ public class RelMdDistinctRowCount {
modifiedPred = RelOptUtil.pushPastProject(childPred, rel);
}
Double distinctRowCount =
- RelMetadataQuery.getDistinctRowCount(
- rel.getInput(),
- baseCols.build(),
+ mq.getDistinctRowCount(rel.getInput(), baseCols.build(),
modifiedPred);
if (distinctRowCount == null) {
@@ -291,38 +270,36 @@ public class RelMdDistinctRowCount {
// multiply by the cardinality of the non-child projection expressions
for (int bit : projCols.build()) {
Double subRowCount =
- RelMdUtil.cardOfProjExpr(rel, projExprs.get(bit));
+ RelMdUtil.cardOfProjExpr(mq, rel, projExprs.get(bit));
if (subRowCount == null) {
return null;
}
distinctRowCount *= subRowCount;
}
- return RelMdUtil.numDistinctVals(
- distinctRowCount,
- RelMetadataQuery.getRowCount(rel));
+ return RelMdUtil.numDistinctVals(distinctRowCount, mq.getRowCount(rel));
}
- // Catch-all rule when none of the others apply.
- public Double getDistinctRowCount(
- RelNode rel,
- ImmutableBitSet groupKey,
- RexNode predicate) {
- if (predicate == null || predicate.isAlwaysTrue()) {
- if (groupKey.isEmpty()) {
- return 1D;
- }
+ public Double getDistinctRowCount(RelSubset rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey, RexNode predicate) {
+ final RelNode best = rel.getBest();
+ if (best != null) {
+ return mq.getDistinctRowCount(best, groupKey, predicate);
}
- // REVIEW zfong 4/19/06 - Broadbase code does not take into
- // consideration selectivity of predicates passed in. Also, they
- // assume the rows are unique even if the table is not
- boolean uniq = RelMdUtil.areColumnsDefinitelyUnique(rel, groupKey);
- if (uniq) {
- return NumberUtil.multiply(
- RelMetadataQuery.getRowCount(rel),
- RelMetadataQuery.getSelectivity(rel, predicate));
+ if (!Bug.CALCITE_1048_FIXED) {
+ return getDistinctRowCount((RelNode) rel, mq, groupKey, predicate);
}
- return null;
+ Double d = null;
+ for (RelNode r2 : rel.getRels()) {
+ try {
+ Double d2 = mq.getDistinctRowCount(r2, groupKey, predicate);
+ d = NumberUtil.min(d, d2);
+ } catch (CyclicMetadataException e) {
+ // Ignore this relational expression; there will be non-cyclic ones
+ // in this set.
+ }
+ }
+ return d;
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistribution.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistribution.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistribution.java
index 67ac6a2..f7b5c83 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistribution.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistribution.java
@@ -63,40 +63,40 @@ public class RelMdDistribution {
* @param rel Relational expression
* @return Relational expression's distribution
*/
- public RelDistribution distribution(RelNode rel) {
+ public RelDistribution distribution(RelMetadataQuery mq, RelNode rel) {
return RelDistributions.SINGLETON;
}
- public RelDistribution distribution(SingleRel rel) {
- return RelMetadataQuery.distribution(rel.getInput());
+ public RelDistribution distribution(RelMetadataQuery mq, SingleRel rel) {
+ return mq.distribution(rel.getInput());
}
- public RelDistribution distribution(BiRel rel) {
- return RelMetadataQuery.distribution(rel.getLeft());
+ public RelDistribution distribution(RelMetadataQuery mq, BiRel rel) {
+ return mq.distribution(rel.getLeft());
}
- public RelDistribution distribution(SetOp rel) {
- return RelMetadataQuery.distribution(rel.getInputs().get(0));
+ public RelDistribution distribution(RelMetadataQuery mq, SetOp rel) {
+ return mq.distribution(rel.getInputs().get(0));
}
- public RelDistribution distribution(TableScan scan) {
+ public RelDistribution distribution(RelMetadataQuery mq, TableScan scan) {
return table(scan.getTable());
}
- public RelDistribution distribution(Project project) {
- return project(project.getInput(), project.getProjects());
+ public RelDistribution distribution(RelMetadataQuery mq, Project project) {
+ return project(mq, project.getInput(), project.getProjects());
}
- public RelDistribution distribution(Values values) {
+ public RelDistribution distribution(RelMetadataQuery mq, Values values) {
return values(values.getRowType(), values.getTuples());
}
- public RelDistribution distribution(Exchange exchange) {
+ public RelDistribution distribution(RelMetadataQuery mq, Exchange exchange) {
return exchange(exchange.distribution);
}
- public RelDistribution distribution(HepRelVertex rel) {
- return RelMetadataQuery.distribution(rel.getCurrentRel());
+ public RelDistribution distribution(RelMetadataQuery mq, HepRelVertex rel) {
+ return mq.distribution(rel.getCurrentRel());
}
// Helper methods
@@ -109,34 +109,33 @@ public class RelMdDistribution {
/** Helper method to determine a
* {@link Sort}'s distribution. */
- public static RelDistribution sort(RelNode input) {
- return RelMetadataQuery.distribution(input);
+ public static RelDistribution sort(RelMetadataQuery mq, RelNode input) {
+ return mq.distribution(input);
}
/** Helper method to determine a
* {@link Filter}'s distribution. */
- public static RelDistribution filter(RelNode input) {
- return RelMetadataQuery.distribution(input);
+ public static RelDistribution filter(RelMetadataQuery mq, RelNode input) {
+ return mq.distribution(input);
}
/** Helper method to determine a
* limit's distribution. */
- public static RelDistribution limit(RelNode input) {
- return RelMetadataQuery.distribution(input);
+ public static RelDistribution limit(RelMetadataQuery mq, RelNode input) {
+ return mq.distribution(input);
}
/** Helper method to determine a
* {@link org.apache.calcite.rel.core.Calc}'s distribution. */
- public static RelDistribution calc(RelNode input,
+ public static RelDistribution calc(RelMetadataQuery mq, RelNode input,
RexProgram program) {
throw new AssertionError(); // TODO:
}
/** Helper method to determine a {@link Project}'s collation. */
- public static RelDistribution project(RelNode input,
+ public static RelDistribution project(RelMetadataQuery mq, RelNode input,
List<? extends RexNode> projects) {
- final RelDistribution inputDistribution =
- RelMetadataQuery.distribution(input);
+ final RelDistribution inputDistribution = mq.distribution(input);
final Mappings.TargetMapping mapping =
Project.getPartialMapping(input.getRowType().getFieldCount(),
projects);
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExplainVisibility.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExplainVisibility.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExplainVisibility.java
index b0d926e..bf51f2f 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExplainVisibility.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExplainVisibility.java
@@ -36,8 +36,14 @@ public class RelMdExplainVisibility {
//~ Methods ----------------------------------------------------------------
- // Catch-all rule when none of the others apply.
- public Boolean isVisibleInExplain(RelNode rel, SqlExplainLevel explainLevel) {
+ /** Catch-all implementation for
+ * {@link BuiltInMetadata.ExplainVisibility#isVisibleInExplain(SqlExplainLevel)},
+ * invoked using reflection.
+ *
+ * @see org.apache.calcite.rel.metadata.RelMetadataQuery#isVisibleInExplain(RelNode, SqlExplainLevel)
+ */
+ public Boolean isVisibleInExplain(RelNode rel, RelMetadataQuery mq,
+ SqlExplainLevel explainLevel) {
// no information available
return null;
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
index 1d2a378..ab9739f 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
@@ -16,6 +16,7 @@
*/
package org.apache.calcite.rel.metadata;
+import org.apache.calcite.adapter.enumerable.EnumerableLimit;
import org.apache.calcite.plan.volcano.RelSubset;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Aggregate;
@@ -29,7 +30,9 @@ import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.core.Union;
import org.apache.calcite.rel.core.Values;
import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.util.Bug;
import org.apache.calcite.util.BuiltInMethod;
+import org.apache.calcite.util.Util;
/**
* RelMdMaxRowCount supplies a default implementation of
@@ -42,10 +45,10 @@ public class RelMdMaxRowCount {
//~ Methods ----------------------------------------------------------------
- public Double getMaxRowCount(Union rel) {
+ public Double getMaxRowCount(Union rel, RelMetadataQuery mq) {
double rowCount = 0.0;
for (RelNode input : rel.getInputs()) {
- Double partialRowCount = RelMetadataQuery.getMaxRowCount(input);
+ Double partialRowCount = mq.getMaxRowCount(input);
if (partialRowCount == null) {
return null;
}
@@ -54,11 +57,11 @@ public class RelMdMaxRowCount {
return rowCount;
}
- public Double getMaxRowCount(Intersect rel) {
+ public Double getMaxRowCount(Intersect rel, RelMetadataQuery mq) {
// max row count is the smallest of the inputs
Double rowCount = null;
for (RelNode input : rel.getInputs()) {
- Double partialRowCount = RelMetadataQuery.getMaxRowCount(input);
+ Double partialRowCount = mq.getMaxRowCount(input);
if (rowCount == null
|| partialRowCount != null && partialRowCount < rowCount) {
rowCount = partialRowCount;
@@ -67,22 +70,39 @@ public class RelMdMaxRowCount {
return rowCount;
}
- public Double getMaxRowCount(Minus rel) {
- return RelMetadataQuery.getMaxRowCount(rel.getInput(0));
+ public Double getMaxRowCount(Minus rel, RelMetadataQuery mq) {
+ return mq.getMaxRowCount(rel.getInput(0));
}
- public Double getMaxRowCount(Filter rel) {
- return RelMetadataQuery.getMaxRowCount(rel.getInput());
+ public Double getMaxRowCount(Filter rel, RelMetadataQuery mq) {
+ return mq.getMaxRowCount(rel.getInput());
}
- public Double getMaxRowCount(Project rel) {
- return RelMetadataQuery.getMaxRowCount(rel.getInput());
+ public Double getMaxRowCount(Project rel, RelMetadataQuery mq) {
+ return mq.getMaxRowCount(rel.getInput());
}
- public Double getMaxRowCount(Sort rel) {
- Double rowCount = RelMetadataQuery.getMaxRowCount(rel.getInput());
+ public Double getMaxRowCount(Sort rel, RelMetadataQuery mq) {
+ Double rowCount = mq.getMaxRowCount(rel.getInput());
if (rowCount == null) {
- return null;
+ rowCount = Double.POSITIVE_INFINITY;
+ }
+ final int offset = rel.offset == null ? 0 : RexLiteral.intValue(rel.offset);
+ rowCount = Math.max(rowCount - offset, 0D);
+
+ if (rel.fetch != null) {
+ final int limit = RexLiteral.intValue(rel.fetch);
+ if (limit < rowCount) {
+ return (double) limit;
+ }
+ }
+ return rowCount;
+ }
+
+ public Double getMaxRowCount(EnumerableLimit rel, RelMetadataQuery mq) {
+ Double rowCount = mq.getMaxRowCount(rel.getInput());
+ if (rowCount == null) {
+ rowCount = Double.POSITIVE_INFINITY;
}
final int offset = rel.offset == null ? 0 : RexLiteral.intValue(rel.offset);
rowCount = Math.max(rowCount - offset, 0D);
@@ -96,21 +116,21 @@ public class RelMdMaxRowCount {
return rowCount;
}
- public Double getMaxRowCount(Aggregate rel) {
+ public Double getMaxRowCount(Aggregate rel, RelMetadataQuery mq) {
if (rel.getGroupSet().isEmpty()) {
// Aggregate with no GROUP BY always returns 1 row (even on empty table).
return 1D;
}
- final Double rowCount = RelMetadataQuery.getMaxRowCount(rel.getInput());
+ final Double rowCount = mq.getMaxRowCount(rel.getInput());
if (rowCount == null) {
return null;
}
return rowCount * rel.getGroupSets().size();
}
- public Double getMaxRowCount(Join rel) {
- Double left = RelMetadataQuery.getMaxRowCount(rel.getLeft());
- Double right = RelMetadataQuery.getMaxRowCount(rel.getRight());
+ public Double getMaxRowCount(Join rel, RelMetadataQuery mq) {
+ Double left = mq.getMaxRowCount(rel.getLeft());
+ Double right = mq.getMaxRowCount(rel.getRight());
if (left == null || right == null) {
return null;
}
@@ -123,20 +143,21 @@ public class RelMdMaxRowCount {
return left * right;
}
- public Double getMaxRowCount(TableScan rel) {
+ public Double getMaxRowCount(TableScan rel, RelMetadataQuery mq) {
// For typical tables, there is no upper bound to the number of rows.
return Double.POSITIVE_INFINITY;
}
- public Double getMaxRowCount(Values values) {
+ public Double getMaxRowCount(Values values, RelMetadataQuery mq) {
// For Values, the maximum row count is the actual row count.
// This is especially useful if Values is empty.
return (double) values.getTuples().size();
}
- public Double getMaxRowCount(RelSubset rel) {
- // FIXME This is a short-term fix for CALCITE-1018. A complete
- // solution will come with CALCITE-794.
+ public Double getMaxRowCount(RelSubset rel, RelMetadataQuery mq) {
+ // FIXME This is a short-term fix for [CALCITE-1018]. A complete
+ // solution will come with [CALCITE-1048].
+ Util.discard(Bug.CALCITE_1048_FIXED);
for (RelNode node : rel.getRels()) {
if (node instanceof Sort) {
Sort sort = (Sort) node;
@@ -150,7 +171,7 @@ public class RelMdMaxRowCount {
}
// Catch-all rule when none of the others apply.
- public Double getMaxRowCount(RelNode rel) {
+ public Double getMaxRowCount(RelNode rel, RelMetadataQuery mq) {
return null;
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMemory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMemory.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMemory.java
index be53b5c..c760b0e 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMemory.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMemory.java
@@ -43,34 +43,34 @@ public class RelMdMemory {
//~ Methods ----------------------------------------------------------------
/** Catch-all implementation for
- * {@link org.apache.calcite.rel.metadata.BuiltInMetadata.Memory#memory()},
+ * {@link BuiltInMetadata.Memory#memory()},
* invoked using reflection.
*
* @see org.apache.calcite.rel.metadata.RelMetadataQuery#memory
*/
- public Double memory(RelNode rel) {
+ public Double memory(RelNode rel, RelMetadataQuery mq) {
return null;
}
/** Catch-all implementation for
- * {@link org.apache.calcite.rel.metadata.BuiltInMetadata.Memory#cumulativeMemoryWithinPhase()},
+ * {@link BuiltInMetadata.Memory#cumulativeMemoryWithinPhase()},
* invoked using reflection.
*
* @see org.apache.calcite.rel.metadata.RelMetadataQuery#memory
*/
- public Double cumulativeMemoryWithinPhase(RelNode rel) {
- Double nullable = RelMetadataQuery.memory(rel);
+ public Double cumulativeMemoryWithinPhase(RelNode rel, RelMetadataQuery mq) {
+ Double nullable = mq.memory(rel);
if (nullable == null) {
return null;
}
- Boolean isPhaseTransition = RelMetadataQuery.isPhaseTransition(rel);
+ Boolean isPhaseTransition = mq.isPhaseTransition(rel);
if (isPhaseTransition == null) {
return null;
}
double d = nullable;
if (!isPhaseTransition) {
for (RelNode input : rel.getInputs()) {
- nullable = RelMetadataQuery.cumulativeMemoryWithinPhase(input);
+ nullable = mq.cumulativeMemoryWithinPhase(input);
if (nullable == null) {
return null;
}
@@ -81,15 +81,15 @@ public class RelMdMemory {
}
/** Catch-all implementation for
- * {@link org.apache.calcite.rel.metadata.BuiltInMetadata.Memory#cumulativeMemoryWithinPhaseSplit()},
+ * {@link BuiltInMetadata.Memory#cumulativeMemoryWithinPhaseSplit()},
* invoked using reflection.
*
* @see org.apache.calcite.rel.metadata.RelMetadataQuery#cumulativeMemoryWithinPhaseSplit
*/
- public Double cumulativeMemoryWithinPhaseSplit(RelNode rel) {
- final Double memoryWithinPhase =
- RelMetadataQuery.cumulativeMemoryWithinPhase(rel);
- final Integer splitCount = RelMetadataQuery.splitCount(rel);
+ public Double cumulativeMemoryWithinPhaseSplit(RelNode rel,
+ RelMetadataQuery mq) {
+ final Double memoryWithinPhase = mq.cumulativeMemoryWithinPhase(rel);
+ final Integer splitCount = mq.splitCount(rel);
if (memoryWithinPhase == null || splitCount == null) {
return null;
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdParallelism.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdParallelism.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdParallelism.java
index ca9c244..dcd69f1 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdParallelism.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdParallelism.java
@@ -45,34 +45,34 @@ public class RelMdParallelism {
//~ Methods ----------------------------------------------------------------
/** Catch-all implementation for
- * {@link org.apache.calcite.rel.metadata.BuiltInMetadata.Parallelism#isPhaseTransition()},
+ * {@link BuiltInMetadata.Parallelism#isPhaseTransition()},
* invoked using reflection.
*
* @see org.apache.calcite.rel.metadata.RelMetadataQuery#isPhaseTransition
*/
- public Boolean isPhaseTransition(RelNode rel) {
+ public Boolean isPhaseTransition(RelNode rel, RelMetadataQuery mq) {
return false;
}
- public Boolean isPhaseTransition(TableScan rel) {
+ public Boolean isPhaseTransition(TableScan rel, RelMetadataQuery mq) {
return true;
}
- public Boolean isPhaseTransition(Values rel) {
+ public Boolean isPhaseTransition(Values rel, RelMetadataQuery mq) {
return true;
}
- public Boolean isPhaseTransition(Exchange rel) {
+ public Boolean isPhaseTransition(Exchange rel, RelMetadataQuery mq) {
return true;
}
/** Catch-all implementation for
- * {@link org.apache.calcite.rel.metadata.BuiltInMetadata.Parallelism#splitCount()},
+ * {@link BuiltInMetadata.Parallelism#splitCount()},
* invoked using reflection.
*
* @see org.apache.calcite.rel.metadata.RelMetadataQuery#splitCount
*/
- public Integer splitCount(RelNode rel) {
+ public Integer splitCount(RelNode rel, RelMetadataQuery mq) {
return 1;
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPercentageOriginalRows.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPercentageOriginalRows.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPercentageOriginalRows.java
index 991a488..bde07a9 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPercentageOriginalRows.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPercentageOriginalRows.java
@@ -53,16 +53,14 @@ public class RelMdPercentageOriginalRows {
private RelMdPercentageOriginalRows() {}
- public Double getPercentageOriginalRows(Aggregate rel) {
+ public Double getPercentageOriginalRows(Aggregate rel, RelMetadataQuery mq) {
// REVIEW jvs 28-Mar-2006: The assumption here seems to be that
// aggregation does not apply any filtering, so it does not modify the
// percentage. That's very much oversimplified.
-
- return RelMetadataQuery.getPercentageOriginalRows(
- rel.getInput());
+ return mq.getPercentageOriginalRows(rel.getInput());
}
- public Double getPercentageOriginalRows(Union rel) {
+ public Double getPercentageOriginalRows(Union rel, RelMetadataQuery mq) {
double numerator = 0.0;
double denominator = 0.0;
@@ -77,9 +75,8 @@ public class RelMdPercentageOriginalRows {
// case where a huge table has been completely filtered away.
for (RelNode input : rel.getInputs()) {
- double rowCount = RelMetadataQuery.getRowCount(input);
- double percentage =
- RelMetadataQuery.getPercentageOriginalRows(input);
+ double rowCount = mq.getRowCount(input);
+ double percentage = mq.getPercentageOriginalRows(input);
if (percentage != 0.0) {
denominator += rowCount / percentage;
numerator += rowCount;
@@ -89,7 +86,7 @@ public class RelMdPercentageOriginalRows {
return quotientForPercentage(numerator, denominator);
}
- public Double getPercentageOriginalRows(Join rel) {
+ public Double getPercentageOriginalRows(Join rel, RelMetadataQuery mq) {
// Assume any single-table filter conditions have already
// been pushed down.
@@ -98,16 +95,13 @@ public class RelMdPercentageOriginalRows {
// REVIEW jvs 28-Mar-2006: need any special casing for SemiJoin?
- double left = RelMetadataQuery.getPercentageOriginalRows(rel.getLeft());
-
- double right =
- RelMetadataQuery.getPercentageOriginalRows(rel.getRight());
-
+ double left = mq.getPercentageOriginalRows(rel.getLeft());
+ double right = mq.getPercentageOriginalRows(rel.getRight());
return left * right;
}
// Catch-all rule when none of the others apply.
- public Double getPercentageOriginalRows(RelNode rel) {
+ public Double getPercentageOriginalRows(RelNode rel, RelMetadataQuery mq) {
if (rel.getInputs().size() > 1) {
// No generic formula available for multiple inputs.
return null;
@@ -120,8 +114,7 @@ public class RelMdPercentageOriginalRows {
RelNode child = rel.getInputs().get(0);
- Double childPercentage =
- RelMetadataQuery.getPercentageOriginalRows(child);
+ Double childPercentage = mq.getPercentageOriginalRows(child);
if (childPercentage == null) {
return null;
}
@@ -130,9 +123,7 @@ public class RelMdPercentageOriginalRows {
// filtering is the effect of single-table filters) with the percentage
// filtering performed by the child.
Double relPercentage =
- quotientForPercentage(
- RelMetadataQuery.getRowCount(rel),
- RelMetadataQuery.getRowCount(child));
+ quotientForPercentage(mq.getRowCount(rel), mq.getRowCount(child));
if (relPercentage == null) {
return null;
}
@@ -147,22 +138,23 @@ public class RelMdPercentageOriginalRows {
}
// Ditto for getNonCumulativeCost
- public RelOptCost getCumulativeCost(RelNode rel) {
- RelOptCost cost = RelMetadataQuery.getNonCumulativeCost(rel);
+ public RelOptCost getCumulativeCost(RelNode rel, RelMetadataQuery mq) {
+ RelOptCost cost = mq.getNonCumulativeCost(rel);
List<RelNode> inputs = rel.getInputs();
for (RelNode input : inputs) {
- cost = cost.plus(RelMetadataQuery.getCumulativeCost(input));
+ cost = cost.plus(mq.getCumulativeCost(input));
}
return cost;
}
- public RelOptCost getCumulativeCost(EnumerableInterpreter rel) {
- return RelMetadataQuery.getNonCumulativeCost(rel);
+ public RelOptCost getCumulativeCost(EnumerableInterpreter rel,
+ RelMetadataQuery mq) {
+ return mq.getNonCumulativeCost(rel);
}
// Ditto for getNonCumulativeCost
- public RelOptCost getNonCumulativeCost(RelNode rel) {
- return rel.computeSelfCost(rel.getCluster().getPlanner());
+ public RelOptCost getNonCumulativeCost(RelNode rel, RelMetadataQuery mq) {
+ return rel.computeSelfCost(rel.getCluster().getPlanner(), mq);
}
private static Double quotientForPercentage(
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java
index 47c0fcc..180883f 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPopulationSize.java
@@ -47,28 +47,26 @@ public class RelMdPopulationSize {
//~ Methods ----------------------------------------------------------------
- public Double getPopulationSize(Filter rel, ImmutableBitSet groupKey) {
- return RelMetadataQuery.getPopulationSize(
- rel.getInput(),
- groupKey);
+ public Double getPopulationSize(Filter rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey) {
+ return mq.getPopulationSize(rel.getInput(), groupKey);
}
- public Double getPopulationSize(Sort rel, ImmutableBitSet groupKey) {
- return RelMetadataQuery.getPopulationSize(
- rel.getInput(),
- groupKey);
+ public Double getPopulationSize(Sort rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey) {
+ return mq.getPopulationSize(rel.getInput(), groupKey);
}
- public Double getPopulationSize(Exchange rel, ImmutableBitSet groupKey) {
- return RelMetadataQuery.getPopulationSize(
- rel.getInput(),
- groupKey);
+ public Double getPopulationSize(Exchange rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey) {
+ return mq.getPopulationSize(rel.getInput(), groupKey);
}
- public Double getPopulationSize(Union rel, ImmutableBitSet groupKey) {
+ public Double getPopulationSize(Union rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey) {
Double population = 0.0;
for (RelNode input : rel.getInputs()) {
- Double subPop = RelMetadataQuery.getPopulationSize(input, groupKey);
+ Double subPop = mq.getPopulationSize(input, groupKey);
if (subPop == null) {
return null;
}
@@ -77,35 +75,38 @@ public class RelMdPopulationSize {
return population;
}
- public Double getPopulationSize(Join rel, ImmutableBitSet groupKey) {
- return RelMdUtil.getJoinPopulationSize(rel, groupKey);
+ public Double getPopulationSize(Join rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey) {
+ return RelMdUtil.getJoinPopulationSize(mq, rel, groupKey);
}
- public Double getPopulationSize(SemiJoin rel, ImmutableBitSet groupKey) {
- return RelMetadataQuery.getPopulationSize(rel.getLeft(), groupKey);
+ public Double getPopulationSize(SemiJoin rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey) {
+ return mq.getPopulationSize(rel.getLeft(), groupKey);
}
- public Double getPopulationSize(Aggregate rel, ImmutableBitSet groupKey) {
+ public Double getPopulationSize(Aggregate rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey) {
ImmutableBitSet.Builder childKey = ImmutableBitSet.builder();
RelMdUtil.setAggChildKeys(groupKey, rel, childKey);
- return RelMetadataQuery.getPopulationSize(rel.getInput(), childKey.build());
+ return mq.getPopulationSize(rel.getInput(), childKey.build());
}
- public Double getPopulationSize(Values rel, ImmutableBitSet groupKey) {
+ public Double getPopulationSize(Values rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey) {
// assume half the rows are duplicates
- return rel.getRows() / 2;
+ return rel.estimateRowCount(mq) / 2;
}
- public Double getPopulationSize(Project rel, ImmutableBitSet groupKey) {
+ public Double getPopulationSize(Project rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey) {
ImmutableBitSet.Builder baseCols = ImmutableBitSet.builder();
ImmutableBitSet.Builder projCols = ImmutableBitSet.builder();
List<RexNode> projExprs = rel.getProjects();
RelMdUtil.splitCols(projExprs, groupKey, baseCols, projCols);
Double population =
- RelMetadataQuery.getPopulationSize(
- rel.getInput(),
- baseCols.build());
+ mq.getPopulationSize(rel.getInput(), baseCols.build());
if (population == null) {
return null;
}
@@ -118,7 +119,7 @@ public class RelMdPopulationSize {
for (int bit : projCols.build()) {
Double subRowCount =
- RelMdUtil.cardOfProjExpr(rel, projExprs.get(bit));
+ RelMdUtil.cardOfProjExpr(mq, rel, projExprs.get(bit));
if (subRowCount == null) {
return null;
}
@@ -128,22 +129,26 @@ public class RelMdPopulationSize {
// REVIEW zfong 6/22/06 - Broadbase did not have the call to
// numDistinctVals. This is needed; otherwise, population can be
// larger than the number of rows in the RelNode.
- return RelMdUtil.numDistinctVals(
- population,
- RelMetadataQuery.getRowCount(rel));
+ return RelMdUtil.numDistinctVals(population, mq.getRowCount(rel));
}
- // Catch-all rule when none of the others apply.
- public Double getPopulationSize(RelNode rel, ImmutableBitSet groupKey) {
+ /** Catch-all implementation for
+ * {@link BuiltInMetadata.PopulationSize#getPopulationSize(ImmutableBitSet)},
+ * invoked using reflection.
+ *
+ * @see org.apache.calcite.rel.metadata.RelMetadataQuery#getPopulationSize(RelNode, ImmutableBitSet)
+ */
+ public Double getPopulationSize(RelNode rel, RelMetadataQuery mq,
+ ImmutableBitSet groupKey) {
// if the keys are unique, return the row count; otherwise, we have
// no further information on which to return any legitimate value
// REVIEW zfong 4/11/06 - Broadbase code returns the product of each
// unique key, which would result in the population being larger
// than the total rows in the relnode
- boolean uniq = RelMdUtil.areColumnsDefinitelyUnique(rel, groupKey);
+ boolean uniq = RelMdUtil.areColumnsDefinitelyUnique(mq, rel, groupKey);
if (uniq) {
- return RelMetadataQuery.getRowCount(rel);
+ return mq.getRowCount(rel);
}
return null;
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
index 2119abf..4b1a894 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
@@ -21,6 +21,7 @@ import org.apache.calcite.linq4j.Ord;
import org.apache.calcite.linq4j.function.Predicate1;
import org.apache.calcite.plan.RelOptPredicateList;
import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.plan.hep.HepRelVertex;
import org.apache.calcite.plan.volcano.RelSubset;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Aggregate;
@@ -120,15 +121,26 @@ public class RelMdPredicates {
private static final List<RexNode> EMPTY_LIST = ImmutableList.of();
- // Catch-all rule when none of the others apply.
- public RelOptPredicateList getPredicates(RelNode rel) {
+ /** Catch-all implementation for
+ * {@link BuiltInMetadata.Predicates#getPredicates()},
+ * invoked using reflection.
+ *
+ * @see org.apache.calcite.rel.metadata.RelMetadataQuery#getPulledUpPredicates(RelNode)
+ */
+ public RelOptPredicateList getPredicates(RelNode rel, RelMetadataQuery mq) {
return RelOptPredicateList.EMPTY;
}
+ public RelOptPredicateList getPredicates(HepRelVertex rel,
+ RelMetadataQuery mq) {
+ return mq.getPulledUpPredicates(rel.getCurrentRel());
+ }
+
/**
* Infers predicates for a table scan.
*/
- public RelOptPredicateList getPredicates(TableScan table) {
+ public RelOptPredicateList getPredicates(TableScan table,
+ RelMetadataQuery mq) {
return RelOptPredicateList.EMPTY;
}
@@ -144,24 +156,23 @@ public class RelMdPredicates {
* is not in the projection list.
*
* <pre>
- * childPullUpExprs: {a > 7, b + c < 10, a + e = 9}
+ * inputPullUpExprs: {a > 7, b + c < 10, a + e = 9}
* projectionExprs: {a, b, c, e / 2}
* projectionPullupExprs: {a > 7, b + c < 10}
* </pre>
*
* </ol>
*/
- public RelOptPredicateList getPredicates(Project project) {
- RelNode child = project.getInput();
+ public RelOptPredicateList getPredicates(Project project,
+ RelMetadataQuery mq) {
+ final RelNode input = project.getInput();
final RexBuilder rexBuilder = project.getCluster().getRexBuilder();
- RelOptPredicateList childInfo =
- RelMetadataQuery.getPulledUpPredicates(child);
-
- List<RexNode> projectPullUpPredicates = new ArrayList<RexNode>();
+ final RelOptPredicateList inputInfo = mq.getPulledUpPredicates(input);
+ final List<RexNode> projectPullUpPredicates = new ArrayList<>();
ImmutableBitSet.Builder columnsMappedBuilder = ImmutableBitSet.builder();
Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION,
- child.getRowType().getFieldCount(),
+ input.getRowType().getFieldCount(),
project.getRowType().getFieldCount());
for (Ord<RexNode> o : Ord.zip(project.getProjects())) {
@@ -175,10 +186,10 @@ public class RelMdPredicates {
// Go over childPullUpPredicates. If a predicate only contains columns in
// 'columnsMapped' construct a new predicate based on mapping.
final ImmutableBitSet columnsMapped = columnsMappedBuilder.build();
- for (RexNode r : childInfo.pulledUpPredicates) {
+ for (RexNode r : inputInfo.pulledUpPredicates) {
ImmutableBitSet rCols = RelOptUtil.InputFinder.bits(r);
if (columnsMapped.contains(rCols)) {
- r = r.accept(new RexPermuteInputsShuttle(m, child));
+ r = r.accept(new RexPermuteInputsShuttle(m, input));
projectPullUpPredicates.add(r);
}
}
@@ -203,29 +214,27 @@ public class RelMdPredicates {
}
/**
- * Add the Filter condition to the pulledPredicates list from the child.
+ * Add the Filter condition to the pulledPredicates list from the input.
*/
- public RelOptPredicateList getPredicates(Filter filter) {
- RelNode child = filter.getInput();
- RelOptPredicateList childInfo =
- RelMetadataQuery.getPulledUpPredicates(child);
+ public RelOptPredicateList getPredicates(Filter filter, RelMetadataQuery mq) {
+ final RelNode input = filter.getInput();
+ final RelOptPredicateList inputInfo = mq.getPulledUpPredicates(input);
- return Util.first(childInfo, RelOptPredicateList.EMPTY)
+ return Util.first(inputInfo, RelOptPredicateList.EMPTY)
.union(
RelOptPredicateList.of(
RelOptUtil.conjunctions(filter.getCondition())));
}
/** Infers predicates for a {@link org.apache.calcite.rel.core.SemiJoin}. */
- public RelOptPredicateList getPredicates(SemiJoin semiJoin) {
+ public RelOptPredicateList getPredicates(SemiJoin semiJoin,
+ RelMetadataQuery mq) {
RexBuilder rB = semiJoin.getCluster().getRexBuilder();
- RelNode left = semiJoin.getInput(0);
- RelNode right = semiJoin.getInput(1);
+ final RelNode left = semiJoin.getInput(0);
+ final RelNode right = semiJoin.getInput(1);
- RelOptPredicateList leftInfo =
- RelMetadataQuery.getPulledUpPredicates(left);
- RelOptPredicateList rightInfo =
- RelMetadataQuery.getPulledUpPredicates(right);
+ final RelOptPredicateList leftInfo = mq.getPulledUpPredicates(left);
+ final RelOptPredicateList rightInfo = mq.getPulledUpPredicates(right);
JoinConditionBasedPredicateInference jI =
new JoinConditionBasedPredicateInference(semiJoin,
@@ -236,15 +245,13 @@ public class RelMdPredicates {
}
/** Infers predicates for a {@link org.apache.calcite.rel.core.Join}. */
- public RelOptPredicateList getPredicates(Join join) {
+ public RelOptPredicateList getPredicates(Join join, RelMetadataQuery mq) {
RexBuilder rB = join.getCluster().getRexBuilder();
RelNode left = join.getInput(0);
RelNode right = join.getInput(1);
- RelOptPredicateList leftInfo =
- RelMetadataQuery.getPulledUpPredicates(left);
- RelOptPredicateList rightInfo =
- RelMetadataQuery.getPulledUpPredicates(right);
+ final RelOptPredicateList leftInfo = mq.getPulledUpPredicates(left);
+ final RelOptPredicateList rightInfo = mq.getPulledUpPredicates(right);
JoinConditionBasedPredicateInference jI =
new JoinConditionBasedPredicateInference(join,
@@ -262,31 +269,29 @@ public class RelMdPredicates {
* GroupSet. For e.g.
*
* <pre>
- * childPullUpExprs : { a > 7, b + c < 10, a + e = 9}
+ * inputPullUpExprs : { a > 7, b + c < 10, a + e = 9}
* groupSet : { a, b}
* pulledUpExprs : { a > 7}
* </pre>
*/
- public RelOptPredicateList getPredicates(Aggregate agg) {
- RelNode child = agg.getInput();
- RelOptPredicateList childInfo =
- RelMetadataQuery.getPulledUpPredicates(child);
-
- List<RexNode> aggPullUpPredicates = new ArrayList<RexNode>();
+ public RelOptPredicateList getPredicates(Aggregate agg, RelMetadataQuery mq) {
+ final RelNode input = agg.getInput();
+ final RelOptPredicateList inputInfo = mq.getPulledUpPredicates(input);
+ final List<RexNode> aggPullUpPredicates = new ArrayList<>();
ImmutableBitSet groupKeys = agg.getGroupSet();
Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION,
- child.getRowType().getFieldCount(), agg.getRowType().getFieldCount());
+ input.getRowType().getFieldCount(), agg.getRowType().getFieldCount());
int i = 0;
for (int j : groupKeys) {
m.set(j, i++);
}
- for (RexNode r : childInfo.pulledUpPredicates) {
+ for (RexNode r : inputInfo.pulledUpPredicates) {
ImmutableBitSet rCols = RelOptUtil.InputFinder.bits(r);
if (groupKeys.contains(rCols)) {
- r = r.accept(new RexPermuteInputsShuttle(m, child));
+ r = r.accept(new RexPermuteInputsShuttle(m, input));
aggPullUpPredicates.add(r);
}
}
@@ -298,11 +303,11 @@ public class RelMdPredicates {
*
* <p>The pulled up expression is a disjunction of its children's predicates.
*/
- public RelOptPredicateList getPredicates(Union union) {
+ public RelOptPredicateList getPredicates(Union union, RelMetadataQuery mq) {
RexBuilder rB = union.getCluster().getRexBuilder();
List<RexNode> orList = Lists.newArrayList();
for (RelNode input : union.getInputs()) {
- RelOptPredicateList info = RelMetadataQuery.getPulledUpPredicates(input);
+ RelOptPredicateList info = mq.getPulledUpPredicates(input);
if (info.pulledUpPredicates.isEmpty()) {
return RelOptPredicateList.EMPTY;
}
@@ -321,27 +326,29 @@ public class RelMdPredicates {
/**
* Infers predicates for a Sort.
*/
- public RelOptPredicateList getPredicates(Sort sort) {
- RelNode child = sort.getInput();
- return RelMetadataQuery.getPulledUpPredicates(child);
+ public RelOptPredicateList getPredicates(Sort sort, RelMetadataQuery mq) {
+ RelNode input = sort.getInput();
+ return mq.getPulledUpPredicates(input);
}
/**
* Infers predicates for an Exchange.
*/
- public RelOptPredicateList getPredicates(Exchange exchange) {
- RelNode child = exchange.getInput();
- return RelMetadataQuery.getPulledUpPredicates(child);
+ public RelOptPredicateList getPredicates(Exchange exchange,
+ RelMetadataQuery mq) {
+ RelNode input = exchange.getInput();
+ return mq.getPulledUpPredicates(input);
}
/** @see RelMetadataQuery#getPulledUpPredicates(RelNode) */
- public RelOptPredicateList getPredicates(RelSubset r) {
- if (!Bug.CALCITE_794_FIXED) {
+ public RelOptPredicateList getPredicates(RelSubset r,
+ RelMetadataQuery mq) {
+ if (!Bug.CALCITE_1048_FIXED) {
return RelOptPredicateList.EMPTY;
}
RelOptPredicateList list = null;
for (RelNode r2 : r.getRels()) {
- RelOptPredicateList list2 = RelMetadataQuery.getPulledUpPredicates(r2);
+ RelOptPredicateList list2 = mq.getPulledUpPredicates(r2);
if (list2 != null) {
list = list == null ? list2 : list.union(list2);
}
@@ -409,7 +416,7 @@ public class RelMdPredicates {
nSysFields + nFieldsLeft + nFieldsRight);
exprFields = Maps.newHashMap();
- allExprsDigests = new HashSet<String>();
+ allExprsDigests = new HashSet<>();
if (lPreds == null) {
leftChildPredicates = null;
@@ -440,7 +447,7 @@ public class RelMdPredicates {
}
equivalence = Maps.newTreeMap();
- equalityPredicates = new HashSet<String>();
+ equalityPredicates = new HashSet<>();
for (int i = 0; i < nSysFields + nFieldsLeft + nFieldsRight; i++) {
equivalence.put(i, BitSets.of(i));
}
@@ -454,11 +461,13 @@ public class RelMdPredicates {
compose(rexBuilder, ImmutableList.of(joinRel.getCondition())));
final EquivalenceFinder eF = new EquivalenceFinder();
- new ArrayList<Void>(Lists.transform(exprs, new Function<RexNode, Void>() {
- public Void apply(RexNode input) {
- return input.accept(eF);
- }
- }));
+ new ArrayList<>(
+ Lists.transform(exprs,
+ new Function<RexNode, Void>() {
+ public Void apply(RexNode input) {
+ return input.accept(eF);
+ }
+ }));
equivalence = BitSets.closure(equivalence);
}
@@ -478,8 +487,8 @@ public class RelMdPredicates {
*/
public RelOptPredicateList inferPredicates(
boolean includeEqualityInference) {
- List<RexNode> inferredPredicates = new ArrayList<RexNode>();
- Set<String> allExprsDigests = new HashSet<String>(this.allExprsDigests);
+ final List<RexNode> inferredPredicates = new ArrayList<>();
+ final Set<String> allExprsDigests = new HashSet<>(this.allExprsDigests);
final JoinRelType joinType = joinRel.getJoinType();
switch (joinType) {
case INNER:
@@ -509,9 +518,8 @@ public class RelMdPredicates {
nSysFields + nFieldsLeft, 0, nSysFields, nFieldsLeft);
final RexPermuteInputsShuttle leftPermute =
new RexPermuteInputsShuttle(leftMapping, joinRel);
-
- List<RexNode> leftInferredPredicates = new ArrayList<RexNode>();
- List<RexNode> rightInferredPredicates = new ArrayList<RexNode>();
+ final List<RexNode> leftInferredPredicates = new ArrayList<>();
+ final List<RexNode> rightInferredPredicates = new ArrayList<>();
for (RexNode iP : inferredPredicates) {
ImmutableBitSet iPBitSet = RelOptUtil.InputFinder.bits(iP);
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
index aac3aae..ea647a6 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
@@ -16,20 +16,29 @@
*/
package org.apache.calcite.rel.metadata;
+import org.apache.calcite.adapter.enumerable.EnumerableLimit;
+import org.apache.calcite.plan.volcano.RelSubset;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.SingleRel;
import org.apache.calcite.rel.core.Aggregate;
+import org.apache.calcite.rel.core.Calc;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.core.Intersect;
+import org.apache.calcite.rel.core.Join;
import org.apache.calcite.rel.core.Minus;
import org.apache.calcite.rel.core.Project;
import org.apache.calcite.rel.core.SemiJoin;
import org.apache.calcite.rel.core.Sort;
+import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.core.Union;
+import org.apache.calcite.rel.core.Values;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.util.Bug;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.NumberUtil;
+import org.apache.calcite.util.Util;
/**
* RelMdRowCount supplies a default implementation of
@@ -42,10 +51,37 @@ public class RelMdRowCount {
//~ Methods ----------------------------------------------------------------
- public Double getRowCount(Union rel) {
- double rowCount = 0D;
+ /** Catch-all implementation for
+ * {@link BuiltInMetadata.RowCount#getRowCount()},
+ * invoked using reflection.
+ *
+ * @see org.apache.calcite.rel.metadata.RelMetadataQuery#getRowCount(RelNode)
+ */
+ public Double getRowCount(RelNode rel, RelMetadataQuery mq) {
+ return rel.estimateRowCount(mq);
+ }
+
+ public Double getRowCount(RelSubset subset, RelMetadataQuery mq) {
+ if (!Bug.CALCITE_1048_FIXED) {
+ return mq.getRowCount(Util.first(subset.getBest(), subset.getOriginal()));
+ }
+ Double v = null;
+ for (RelNode r : subset.getRels()) {
+ try {
+ v = NumberUtil.min(v, mq.getRowCount(r));
+ } catch (CyclicMetadataException e) {
+ // ignore this rel; there will be other, non-cyclic ones
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ return Util.first(v, 1e6d); // if set is empty, estimate large
+ }
+
+ public Double getRowCount(Union rel, RelMetadataQuery mq) {
+ double rowCount = 0.0;
for (RelNode input : rel.getInputs()) {
- Double partialRowCount = RelMetadataQuery.getRowCount(input);
+ Double partialRowCount = mq.getRowCount(input);
if (partialRowCount == null) {
return null;
}
@@ -54,10 +90,10 @@ public class RelMdRowCount {
return rowCount;
}
- public Double getRowCount(Intersect rel) {
+ public Double getRowCount(Intersect rel, RelMetadataQuery mq) {
Double rowCount = null;
for (RelNode input : rel.getInputs()) {
- Double partialRowCount = RelMetadataQuery.getRowCount(input);
+ Double partialRowCount = mq.getRowCount(input);
if (rowCount == null
|| partialRowCount != null && partialRowCount < rowCount) {
rowCount = partialRowCount;
@@ -66,10 +102,10 @@ public class RelMdRowCount {
return rowCount;
}
- public Double getRowCount(Minus rel) {
+ public Double getRowCount(Minus rel, RelMetadataQuery mq) {
Double rowCount = null;
for (RelNode input : rel.getInputs()) {
- Double partialRowCount = RelMetadataQuery.getRowCount(input);
+ Double partialRowCount = mq.getRowCount(input);
if (rowCount == null
|| partialRowCount != null && partialRowCount < rowCount) {
rowCount = partialRowCount;
@@ -78,20 +114,21 @@ public class RelMdRowCount {
return rowCount;
}
- public Double getRowCount(Filter rel) {
- return NumberUtil.multiply(
- RelMetadataQuery.getSelectivity(
- rel.getInput(),
- rel.getCondition()),
- RelMetadataQuery.getRowCount(rel.getInput()));
+ public Double getRowCount(Filter rel, RelMetadataQuery mq) {
+ return RelMdUtil.estimateFilteredRows(rel.getInput(), rel.getCondition(),
+ mq);
}
- public Double getRowCount(Project rel) {
- return RelMetadataQuery.getRowCount(rel.getInput());
+ public Double getRowCount(Calc rel, RelMetadataQuery mq) {
+ return RelMdUtil.estimateFilteredRows(rel.getInput(), rel.getProgram(), mq);
}
- public Double getRowCount(Sort rel) {
- Double rowCount = RelMetadataQuery.getRowCount(rel.getInput());
+ public Double getRowCount(Project rel, RelMetadataQuery mq) {
+ return mq.getRowCount(rel.getInput());
+ }
+
+ public Double getRowCount(Sort rel, RelMetadataQuery mq) {
+ Double rowCount = mq.getRowCount(rel.getInput());
if (rowCount == null) {
return null;
}
@@ -107,30 +144,51 @@ public class RelMdRowCount {
return rowCount;
}
- public Double getRowCount(SemiJoin rel) {
+ public Double getRowCount(EnumerableLimit rel, RelMetadataQuery mq) {
+ Double rowCount = mq.getRowCount(rel.getInput());
+ if (rowCount == null) {
+ return null;
+ }
+ final int offset = rel.offset == null ? 0 : RexLiteral.intValue(rel.offset);
+ rowCount = Math.max(rowCount - offset, 0D);
+
+ if (rel.fetch != null) {
+ final int limit = RexLiteral.intValue(rel.fetch);
+ if (limit < rowCount) {
+ return (double) limit;
+ }
+ }
+ return rowCount;
+ }
+
+ // Covers Converter, Interpreter
+ public Double getRowCount(SingleRel rel, RelMetadataQuery mq) {
+ return mq.getRowCount(rel.getInput());
+ }
+
+ public Double getRowCount(Join rel, RelMetadataQuery mq) {
+ return RelMdUtil.getJoinRowCount(mq, rel, rel.getCondition());
+ }
+
+ public Double getRowCount(SemiJoin rel, RelMetadataQuery mq) {
// create a RexNode representing the selectivity of the
// semijoin filter and pass it to getSelectivity
RexNode semiJoinSelectivity =
- RelMdUtil.makeSemiJoinSelectivityRexNode(rel);
+ RelMdUtil.makeSemiJoinSelectivityRexNode(mq, rel);
return NumberUtil.multiply(
- RelMetadataQuery.getSelectivity(
- rel.getLeft(),
- semiJoinSelectivity),
- RelMetadataQuery.getRowCount(rel.getLeft()));
+ mq.getSelectivity(rel.getLeft(), semiJoinSelectivity),
+ mq.getRowCount(rel.getLeft()));
}
- public Double getRowCount(Aggregate rel) {
- ImmutableBitSet groupKey = rel.getGroupSet();
+ public Double getRowCount(Aggregate rel, RelMetadataQuery mq) {
+ ImmutableBitSet groupKey = rel.getGroupSet(); // .range(rel.getGroupCount());
- // rowcount is the cardinality of the group by columns
+ // rowCount is the cardinality of the group by columns
Double distinctRowCount =
- RelMetadataQuery.getDistinctRowCount(
- rel.getInput(),
- groupKey,
- null);
+ mq.getDistinctRowCount(rel.getInput(), groupKey, null);
if (distinctRowCount == null) {
- distinctRowCount = RelMetadataQuery.getRowCount(rel.getInput()) / 10D;
+ distinctRowCount = mq.getRowCount(rel.getInput()) / 10;
}
// Grouping sets multiply
@@ -139,9 +197,12 @@ public class RelMdRowCount {
return distinctRowCount;
}
- // Catch-all rule when none of the others apply.
- public Double getRowCount(RelNode rel) {
- return rel.getRows();
+ public Double getRowCount(TableScan rel, RelMetadataQuery mq) {
+ return rel.estimateRowCount(mq);
+ }
+
+ public Double getRowCount(Values rel, RelMetadataQuery mq) {
+ return rel.estimateRowCount(mq);
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSelectivity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSelectivity.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSelectivity.java
index c59a005..b7ffcdd 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSelectivity.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSelectivity.java
@@ -50,7 +50,8 @@ public class RelMdSelectivity {
//~ Methods ----------------------------------------------------------------
- public Double getSelectivity(Union rel, RexNode predicate) {
+ public Double getSelectivity(Union rel, RelMetadataQuery mq,
+ RexNode predicate) {
if ((rel.getInputs().size() == 0) || (predicate == null)) {
return 1.0;
}
@@ -60,7 +61,7 @@ public class RelMdSelectivity {
int[] adjustments = new int[rel.getRowType().getFieldCount()];
RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
for (RelNode input : rel.getInputs()) {
- Double nRows = RelMetadataQuery.getRowCount(input);
+ Double nRows = mq.getRowCount(input);
if (nRows == null) {
return null;
}
@@ -73,7 +74,7 @@ public class RelMdSelectivity {
null,
input.getRowType().getFieldList(),
adjustments));
- double sel = RelMetadataQuery.getSelectivity(input, modifiedPred);
+ double sel = mq.getSelectivity(input, modifiedPred);
sumRows += nRows;
sumSelectedRows += nRows * sel;
@@ -85,36 +86,34 @@ public class RelMdSelectivity {
return sumSelectedRows / sumRows;
}
- public Double getSelectivity(Sort rel, RexNode predicate) {
- return RelMetadataQuery.getSelectivity(
- rel.getInput(),
- predicate);
+ public Double getSelectivity(Sort rel, RelMetadataQuery mq,
+ RexNode predicate) {
+ return mq.getSelectivity(rel.getInput(), predicate);
}
- public Double getSelectivity(Filter rel, RexNode predicate) {
+ public Double getSelectivity(Filter rel, RelMetadataQuery mq,
+ RexNode predicate) {
// Take the difference between the predicate passed in and the
// predicate in the filter's condition, so we don't apply the
// selectivity of the filter twice. If no predicate is passed in,
// use the filter's condition.
if (predicate != null) {
- return RelMetadataQuery.getSelectivity(
- rel.getInput(),
+ return mq.getSelectivity(rel.getInput(),
RelMdUtil.minusPreds(
rel.getCluster().getRexBuilder(),
predicate,
rel.getCondition()));
} else {
- return RelMetadataQuery.getSelectivity(
- rel.getInput(),
- rel.getCondition());
+ return mq.getSelectivity(rel.getInput(), rel.getCondition());
}
}
- public Double getSelectivity(SemiJoin rel, RexNode predicate) {
+ public Double getSelectivity(SemiJoin rel, RelMetadataQuery mq,
+ RexNode predicate) {
// create a RexNode representing the selectivity of the
// semijoin filter and pass it to getSelectivity
RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
- RexNode newPred = RelMdUtil.makeSemiJoinSelectivityRexNode(rel);
+ RexNode newPred = RelMdUtil.makeSemiJoinSelectivityRexNode(mq, rel);
if (predicate != null) {
newPred =
rexBuilder.makeCall(
@@ -123,14 +122,13 @@ public class RelMdSelectivity {
predicate);
}
- return RelMetadataQuery.getSelectivity(
- rel.getLeft(),
- newPred);
+ return mq.getSelectivity(rel.getLeft(), newPred);
}
- public Double getSelectivity(Aggregate rel, RexNode predicate) {
- List<RexNode> notPushable = new ArrayList<RexNode>();
- List<RexNode> pushable = new ArrayList<RexNode>();
+ public Double getSelectivity(Aggregate rel, RelMetadataQuery mq,
+ RexNode predicate) {
+ final List<RexNode> notPushable = new ArrayList<>();
+ final List<RexNode> pushable = new ArrayList<>();
RelOptUtil.splitFilters(
rel.getGroupSet(),
predicate,
@@ -140,10 +138,7 @@ public class RelMdSelectivity {
RexNode childPred =
RexUtil.composeConjunction(rexBuilder, pushable, true);
- Double selectivity =
- RelMetadataQuery.getSelectivity(
- rel.getInput(),
- childPred);
+ Double selectivity = mq.getSelectivity(rel.getInput(), childPred);
if (selectivity == null) {
return null;
} else {
@@ -153,9 +148,10 @@ public class RelMdSelectivity {
}
}
- public Double getSelectivity(Project rel, RexNode predicate) {
- List<RexNode> notPushable = new ArrayList<RexNode>();
- List<RexNode> pushable = new ArrayList<RexNode>();
+ public Double getSelectivity(Project rel, RelMetadataQuery mq,
+ RexNode predicate) {
+ final List<RexNode> notPushable = new ArrayList<>();
+ final List<RexNode> pushable = new ArrayList<>();
RelOptUtil.splitFilters(
ImmutableBitSet.range(rel.getRowType().getFieldCount()),
predicate,
@@ -171,10 +167,7 @@ public class RelMdSelectivity {
} else {
modifiedPred = RelOptUtil.pushPastProject(childPred, rel);
}
- Double selectivity =
- RelMetadataQuery.getSelectivity(
- rel.getInput(),
- modifiedPred);
+ Double selectivity = mq.getSelectivity(rel.getInput(), modifiedPred);
if (selectivity == null) {
return null;
} else {
@@ -185,7 +178,8 @@ public class RelMdSelectivity {
}
// Catch-all rule when none of the others apply.
- public Double getSelectivity(RelNode rel, RexNode predicate) {
+ public Double getSelectivity(RelNode rel, RelMetadataQuery mq,
+ RexNode predicate) {
return RelMdUtil.guessSelectivity(predicate);
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/cabdcf44/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java
index af60e73..8c2502e 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java
@@ -74,14 +74,13 @@ public class RelMdSize {
//~ Methods ----------------------------------------------------------------
/** Catch-all implementation for
- * {@link org.apache.calcite.rel.metadata.BuiltInMetadata.Size#averageRowSize()},
+ * {@link BuiltInMetadata.Size#averageRowSize()},
* invoked using reflection.
*
* @see org.apache.calcite.rel.metadata.RelMetadataQuery#getAverageRowSize
*/
- public Double averageRowSize(RelNode rel) {
- final List<Double> averageColumnSizes =
- RelMetadataQuery.getAverageColumnSizes(rel);
+ public Double averageRowSize(RelNode rel, RelMetadataQuery mq) {
+ final List<Double> averageColumnSizes = mq.getAverageColumnSizes(rel);
if (averageColumnSizes == null) {
return null;
}
@@ -99,30 +98,30 @@ public class RelMdSize {
}
/** Catch-all implementation for
- * {@link org.apache.calcite.rel.metadata.BuiltInMetadata.Size#averageColumnSizes()},
+ * {@link BuiltInMetadata.Size#averageColumnSizes()},
* invoked using reflection.
*
* @see org.apache.calcite.rel.metadata.RelMetadataQuery#getAverageColumnSizes
*/
- public List<Double> averageColumnSizes(RelNode rel) {
+ public List<Double> averageColumnSizes(RelNode rel, RelMetadataQuery mq) {
return null; // absolutely no idea
}
- public List<Double> averageColumnSizes(Filter rel) {
- return RelMetadataQuery.getAverageColumnSizes(rel.getInput());
+ public List<Double> averageColumnSizes(Filter rel, RelMetadataQuery mq) {
+ return mq.getAverageColumnSizes(rel.getInput());
}
- public List<Double> averageColumnSizes(Sort rel) {
- return RelMetadataQuery.getAverageColumnSizes(rel.getInput());
+ public List<Double> averageColumnSizes(Sort rel, RelMetadataQuery mq) {
+ return mq.getAverageColumnSizes(rel.getInput());
}
- public List<Double> averageColumnSizes(Exchange rel) {
- return RelMetadataQuery.getAverageColumnSizes(rel.getInput());
+ public List<Double> averageColumnSizes(Exchange rel, RelMetadataQuery mq) {
+ return mq.getAverageColumnSizes(rel.getInput());
}
- public List<Double> averageColumnSizes(Project rel) {
+ public List<Double> averageColumnSizes(Project rel, RelMetadataQuery mq) {
final List<Double> inputColumnSizes =
- RelMetadataQuery.getAverageColumnSizesNotNull(rel.getInput());
+ mq.getAverageColumnSizesNotNull(rel.getInput());
final ImmutableNullableList.Builder<Double> sizes =
ImmutableNullableList.builder();
for (RexNode project : rel.getProjects()) {
@@ -131,7 +130,7 @@ public class RelMdSize {
return sizes.build();
}
- public List<Double> averageColumnSizes(Values rel) {
+ public List<Double> averageColumnSizes(Values rel, RelMetadataQuery mq) {
final List<RelDataTypeField> fields = rel.getRowType().getFieldList();
final ImmutableList.Builder<Double> list = ImmutableList.builder();
for (int i = 0; i < fields.size(); i++) {
@@ -151,7 +150,7 @@ public class RelMdSize {
return list.build();
}
- public List<Double> averageColumnSizes(TableScan rel) {
+ public List<Double> averageColumnSizes(TableScan rel, RelMetadataQuery mq) {
final List<RelDataTypeField> fields = rel.getRowType().getFieldList();
final ImmutableList.Builder<Double> list = ImmutableList.builder();
for (RelDataTypeField field : fields) {
@@ -160,9 +159,9 @@ public class RelMdSize {
return list.build();
}
- public List<Double> averageColumnSizes(Aggregate rel) {
+ public List<Double> averageColumnSizes(Aggregate rel, RelMetadataQuery mq) {
final List<Double> inputColumnSizes =
- RelMetadataQuery.getAverageColumnSizesNotNull(rel.getInput());
+ mq.getAverageColumnSizesNotNull(rel.getInput());
final ImmutableList.Builder<Double> list = ImmutableList.builder();
for (int key : rel.getGroupSet()) {
list.add(inputColumnSizes.get(key));
@@ -173,21 +172,21 @@ public class RelMdSize {
return list.build();
}
- public List<Double> averageColumnSizes(SemiJoin rel) {
- return averageJoinColumnSizes(rel, true);
+ public List<Double> averageColumnSizes(SemiJoin rel, RelMetadataQuery mq) {
+ return averageJoinColumnSizes(rel, mq, true);
}
- public List<Double> averageColumnSizes(Join rel) {
- return averageJoinColumnSizes(rel, false);
+ public List<Double> averageColumnSizes(Join rel, RelMetadataQuery mq) {
+ return averageJoinColumnSizes(rel, mq, false);
}
- private List<Double> averageJoinColumnSizes(Join rel, boolean semijoin) {
+ private List<Double> averageJoinColumnSizes(Join rel, RelMetadataQuery mq,
+ boolean semijoin) {
final RelNode left = rel.getLeft();
final RelNode right = rel.getRight();
- final List<Double> lefts =
- RelMetadataQuery.getAverageColumnSizes(left);
- final List<Double> rights = semijoin
- ? null : RelMetadataQuery.getAverageColumnSizes(right);
+ final List<Double> lefts = mq.getAverageColumnSizes(left);
+ final List<Double> rights =
+ semijoin ? null : mq.getAverageColumnSizes(right);
if (lefts == null && rights == null) {
return null;
}
@@ -205,20 +204,19 @@ public class RelMdSize {
return ImmutableNullableList.copyOf(sizes);
}
- public List<Double> averageColumnSizes(Intersect rel) {
- return RelMetadataQuery.getAverageColumnSizes(rel.getInput(0));
+ public List<Double> averageColumnSizes(Intersect rel, RelMetadataQuery mq) {
+ return mq.getAverageColumnSizes(rel.getInput(0));
}
- public List<Double> averageColumnSizes(Minus rel) {
- return RelMetadataQuery.getAverageColumnSizes(rel.getInput(0));
+ public List<Double> averageColumnSizes(Minus rel, RelMetadataQuery mq) {
+ return mq.getAverageColumnSizes(rel.getInput(0));
}
- public List<Double> averageColumnSizes(Union rel) {
+ public List<Double> averageColumnSizes(Union rel, RelMetadataQuery mq) {
final int fieldCount = rel.getRowType().getFieldCount();
List<List<Double>> inputColumnSizeList = Lists.newArrayList();
for (RelNode input : rel.getInputs()) {
- final List<Double> inputSizes =
- RelMetadataQuery.getAverageColumnSizes(input);
+ final List<Double> inputSizes = mq.getAverageColumnSizes(input);
if (inputSizes != null) {
inputColumnSizeList.add(inputSizes);
}