use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMdAllPredicates method getAllFilterPredicates.
/**
* Add the Filter condition to the list obtained from the input.
* The pred comes from the parent of rel.
*/
@Nullable
private static RelOptPredicateList getAllFilterPredicates(RelNode rel, RelMetadataQuery mq, RexNode pred) {
final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
final RelOptPredicateList predsBelow = mq.getAllPredicates(rel);
if (predsBelow == null) {
// Safety check
return null;
}
// Extract input fields referenced by Filter condition
final Set<RelDataTypeField> inputExtraFields = new LinkedHashSet<>();
final RelOptUtil.InputFinder inputFinder = new RelOptUtil.InputFinder(inputExtraFields);
pred.accept(inputFinder);
final ImmutableBitSet inputFieldsUsed = inputFinder.build();
// Infer column origin expressions for given references
final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>();
for (int idx : inputFieldsUsed) {
final RexInputRef ref = RexInputRef.of(idx, rel.getRowType().getFieldList());
final Set<RexNode> originalExprs = mq.getExpressionLineage(rel, ref);
if (originalExprs == null) {
// Bail out
return null;
}
mapping.put(ref, originalExprs);
}
// Replace with new expressions and return union of predicates
final Set<RexNode> allExprs = RelMdExpressionLineage.createAllPossibleExpressions(rexBuilder, pred, mapping);
if (allExprs == null) {
return null;
}
return predsBelow.union(rexBuilder, RelOptPredicateList.of(rexBuilder, allExprs));
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMdPredicates method getPredicates.
/**
* Infers predicates for an Aggregate.
*
* <p>Pulls up predicates that only contains references to columns in the
* GroupSet. For e.g.
*
* <blockquote><pre>
* inputPullUpExprs : { a > 7, b + c < 10, a + e = 9}
* groupSet : { a, b}
* pulledUpExprs : { a > 7}
* </pre></blockquote>
*/
public RelOptPredicateList getPredicates(Aggregate agg, RelMetadataQuery mq) {
final RelNode input = agg.getInput();
final RexBuilder rexBuilder = agg.getCluster().getRexBuilder();
final RelOptPredicateList inputInfo = mq.getPulledUpPredicates(input);
final List<RexNode> aggPullUpPredicates = new ArrayList<>();
ImmutableBitSet groupKeys = agg.getGroupSet();
if (groupKeys.isEmpty()) {
// no rows!) but not on the output (there is one row).
return RelOptPredicateList.EMPTY;
}
Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION, input.getRowType().getFieldCount(), agg.getRowType().getFieldCount());
int i = 0;
for (int j : groupKeys) {
m.set(j, i++);
}
for (RexNode r : inputInfo.pulledUpPredicates) {
ImmutableBitSet rCols = RelOptUtil.InputFinder.bits(r);
if (groupKeys.contains(rCols)) {
r = r.accept(new RexPermuteInputsShuttle(m, input));
aggPullUpPredicates.add(r);
}
}
return RelOptPredicateList.of(rexBuilder, aggPullUpPredicates);
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMetadataQuery method areRowsUnique.
/**
* Returns whether the rows of a given relational expression are distinct,
* optionally ignoring NULL values.
*
* <p>This is derived by applying the
* {@link BuiltInMetadata.ColumnUniqueness#areColumnsUnique(org.apache.calcite.util.ImmutableBitSet, boolean)}
* statistic over all columns. If
* {@link BuiltInMetadata.MaxRowCount#getMaxRowCount()}
* is less than or equal to one, we shortcut the process and declare the rows
* unique.
*
* @param rel the relational expression
* @param ignoreNulls if true, ignore null values when determining column
* uniqueness
*
* @return whether the rows are unique, or
* null if not enough information is available to make that determination
*/
@Nullable
public Boolean areRowsUnique(RelNode rel, boolean ignoreNulls) {
Double maxRowCount = this.getMaxRowCount(rel);
if (maxRowCount != null && maxRowCount <= 1D) {
return true;
}
final ImmutableBitSet columns = ImmutableBitSet.range(rel.getRowType().getFieldCount());
return areColumnsUnique(rel, columns, ignoreNulls);
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMdPopulationSize method getPopulationSize.
@Nullable
public Double getPopulationSize(Project rel, RelMetadataQuery mq, ImmutableBitSet groupKey) {
// try to remove const columns from the group keys, as they do not
// affect the population size
ImmutableBitSet nonConstCols = RexUtil.getNonConstColumns(groupKey, rel.getProjects());
if (nonConstCols.cardinality() == 0) {
// all columns are constants, the population size should be 1
return 1D;
}
if (nonConstCols.cardinality() < groupKey.cardinality()) {
// with the trimmed columns
return getPopulationSize(rel, mq, nonConstCols);
}
ImmutableBitSet.Builder baseCols = ImmutableBitSet.builder();
ImmutableBitSet.Builder projCols = ImmutableBitSet.builder();
List<RexNode> projExprs = rel.getProjects();
RelMdUtil.splitCols(projExprs, groupKey, baseCols, projCols);
Double population = mq.getPopulationSize(rel.getInput(), baseCols.build());
if (population == null) {
return null;
}
// all column references
if (projCols.cardinality() == 0) {
return population;
}
for (int bit : projCols.build()) {
Double subRowCount = RelMdUtil.cardOfProjExpr(mq, rel, projExprs.get(bit));
if (subRowCount == null) {
return null;
}
population *= subRowCount;
}
// larger than the number of rows in the RelNode.
return RelMdUtil.numDistinctVals(population, mq.getRowCount(rel));
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMdRowCount method getRowCount.
public Double getRowCount(Aggregate rel, RelMetadataQuery mq) {
ImmutableBitSet groupKey = rel.getGroupSet();
// rowCount is the cardinality of the group by columns
Double distinctRowCount = mq.getDistinctRowCount(rel.getInput(), groupKey, null);
if (distinctRowCount == null) {
distinctRowCount = mq.getRowCount(rel.getInput()) / 10;
}
// Grouping sets multiply
distinctRowCount *= rel.getGroupSets().size();
return distinctRowCount;
}
Aggregations