use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class EnumerableMergeJoin method deriveTraits.
@Override
@Nullable
public Pair<RelTraitSet, List<RelTraitSet>> deriveTraits(final RelTraitSet childTraits, final int childId) {
final int keyCount = joinInfo.leftKeys.size();
RelCollation collation = getCollation(childTraits);
final int colCount = collation.getFieldCollations().size();
if (colCount < keyCount || keyCount == 0) {
return null;
}
if (colCount > keyCount) {
collation = RelCollations.of(collation.getFieldCollations().subList(0, keyCount));
}
ImmutableIntList sourceKeys = childId == 0 ? joinInfo.leftKeys : joinInfo.rightKeys;
ImmutableBitSet keySet = ImmutableBitSet.of(sourceKeys);
ImmutableBitSet childCollationKeys = ImmutableBitSet.of(RelCollations.ordinals(collation));
if (!childCollationKeys.equals(keySet)) {
return null;
}
Mappings.TargetMapping mapping = buildMapping(childId == 0);
RelCollation targetCollation = collation.apply(mapping);
if (childId == 0) {
// traits from left child
RelTraitSet joinTraits = getTraitSet().replace(collation);
// Forget about the equiv keys for the moment
return Pair.of(joinTraits, ImmutableList.of(childTraits, right.getTraitSet().replace(targetCollation)));
} else {
// traits from right child
assert childId == 1;
RelTraitSet joinTraits = getTraitSet().replace(targetCollation);
// Forget about the equiv keys for the moment
return Pair.of(joinTraits, ImmutableList.of(joinTraits, childTraits.replace(collation)));
}
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class EnumerableMergeJoin method extendCollation.
/**
* This function extends collation by appending new collation fields defined on keys.
*/
private static RelCollation extendCollation(RelCollation collation, List<Integer> keys) {
List<RelFieldCollation> fieldsForNewCollation = new ArrayList<>(keys.size());
fieldsForNewCollation.addAll(collation.getFieldCollations());
ImmutableBitSet keysBitset = ImmutableBitSet.of(keys);
ImmutableBitSet colKeysBitset = ImmutableBitSet.of(collation.getKeys());
ImmutableBitSet exceptBitset = keysBitset.except(colKeysBitset);
for (Integer i : exceptBitset) {
fieldsForNewCollation.add(new RelFieldCollation(i));
}
return RelCollations.of(fieldsForNewCollation);
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class LatticeSuggester method frame.
@Nullable
private static Frame frame(final Query q, RelNode r) {
if (r instanceof Sort) {
final Sort sort = (Sort) r;
return frame(q, sort.getInput());
} else if (r instanceof Filter) {
final Filter filter = (Filter) r;
return frame(q, filter.getInput());
} else if (r instanceof Aggregate) {
final Aggregate aggregate = (Aggregate) r;
final Frame h = frame(q, aggregate.getInput());
if (h == null) {
return null;
}
final List<MutableMeasure> measures = new ArrayList<>();
for (AggregateCall call : aggregate.getAggCallList()) {
measures.add(new MutableMeasure(call.getAggregation(), call.isDistinct(), Util.<Integer, @Nullable ColRef>transform(call.getArgList(), h::column), call.name));
}
final int fieldCount = r.getRowType().getFieldCount();
return new Frame(fieldCount, h.hops, measures, ImmutableList.of(h)) {
@Override
@Nullable
ColRef column(int offset) {
if (offset < aggregate.getGroupSet().cardinality()) {
return h.column(aggregate.getGroupSet().nth(offset));
}
// an aggregate function; no direct mapping
return null;
}
};
} else if (r instanceof Project) {
final Project project = (Project) r;
final Frame h = frame(q, project.getInput());
if (h == null) {
return null;
}
final int fieldCount = r.getRowType().getFieldCount();
return new Frame(fieldCount, h.hops, h.measures, ImmutableList.of(h)) {
final List<@Nullable ColRef> columns;
{
final ImmutableNullableList.Builder<@Nullable ColRef> columnBuilder = ImmutableNullableList.builder();
for (Pair<RexNode, String> p : project.getNamedProjects()) {
@SuppressWarnings("method.invocation.invalid") ColRef colRef = toColRef(p.left, p.right);
columnBuilder.add(colRef);
}
columns = columnBuilder.build();
}
@Override
@Nullable
ColRef column(int offset) {
return columns.get(offset);
}
/**
* Converts an expression to a base or derived column reference.
* The alias is optional, but if the derived column reference becomes
* a dimension or measure, the alias will be used to choose a name.
*/
@Nullable
private ColRef toColRef(RexNode e, String alias) {
if (e instanceof RexInputRef) {
return h.column(((RexInputRef) e).getIndex());
}
final ImmutableBitSet bits = RelOptUtil.InputFinder.bits(e);
final ImmutableList.Builder<TableRef> tableRefs = ImmutableList.builder();
// offset within lattice of first column in a table
int c = 0;
for (TableRef tableRef : h.tableRefs) {
final int prev = c;
c += tableRef.table.t.getRowType().getFieldCount();
if (bits.intersects(ImmutableBitSet.range(prev, c))) {
tableRefs.add(tableRef);
}
}
final List<TableRef> tableRefList = tableRefs.build();
switch(tableRefList.size()) {
case 1:
return new SingleTableDerivedColRef(tableRefList.get(0), e, alias);
default:
return new DerivedColRef(tableRefList, e, alias);
}
}
};
} else if (r instanceof Join) {
final Join join = (Join) r;
final int leftCount = join.getLeft().getRowType().getFieldCount();
final Frame left = frame(q, join.getLeft());
final Frame right = frame(q, join.getRight());
if (left == null || right == null) {
return null;
}
final ImmutableList.Builder<Hop> builder = ImmutableList.builder();
builder.addAll(left.hops);
for (IntPair p : join.analyzeCondition().pairs()) {
final ColRef source = left.column(p.source);
final ColRef target = right.column(p.target);
assert source instanceof SingleTableColRef;
assert target instanceof SingleTableColRef;
builder.add(new Hop((SingleTableColRef) source, (SingleTableColRef) target));
}
builder.addAll(right.hops);
final int fieldCount = r.getRowType().getFieldCount();
return new Frame(fieldCount, builder.build(), CompositeList.of(left.measures, right.measures), ImmutableList.of(left, right)) {
@Override
@Nullable
ColRef column(int offset) {
if (offset < leftCount) {
return left.column(offset);
} else {
return right.column(offset - leftCount);
}
}
};
} else if (r instanceof TableScan) {
final TableScan scan = (TableScan) r;
final TableRef tableRef = q.tableRef(scan);
final int fieldCount = r.getRowType().getFieldCount();
return new Frame(fieldCount, ImmutableList.of(), ImmutableList.of(), ImmutableSet.of(tableRef)) {
@Override
ColRef column(int offset) {
if (offset >= scan.getTable().getRowType().getFieldCount()) {
throw new IndexOutOfBoundsException("field " + offset + " out of range in " + scan.getTable().getRowType());
}
return new BaseColRef(tableRef, offset);
}
};
} else {
return null;
}
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class TableScanNode method createProjectableFilterable.
private static TableScanNode createProjectableFilterable(Compiler compiler, TableScan rel, ImmutableList<RexNode> filters, @Nullable ImmutableIntList projects, ProjectableFilterableTable pfTable) {
final DataContext root = compiler.getDataContext();
final ImmutableIntList originalProjects = projects;
for (; ; ) {
final List<RexNode> mutableFilters = Lists.newArrayList(filters);
final int[] projectInts;
if (projects == null || projects.equals(TableScan.identity(rel.getTable()))) {
projectInts = null;
} else {
projectInts = projects.toIntArray();
}
for (RexNode filter : mutableFilters) {
if (!filters.contains(filter)) {
throw RESOURCE.filterableTableInventedFilter(filter.toString()).ex();
}
}
final ImmutableBitSet usedFields = RelOptUtil.InputFinder.bits(mutableFilters, null);
if (projects != null) {
int changeCount = 0;
for (int usedField : usedFields) {
if (!projects.contains(usedField)) {
// A field that is not projected is used in a filter that the
// table rejected. We won't be able to apply the filter later.
// Try again without any projects.
projects = ImmutableIntList.copyOf(Iterables.concat(projects, ImmutableList.of(usedField)));
++changeCount;
}
}
if (changeCount > 0) {
continue;
}
}
final Enumerable<@Nullable Object[]> enumerable1 = pfTable.scan(root, mutableFilters, projectInts);
final Enumerable<Row> rowEnumerable = Enumerables.toRow(enumerable1);
final ImmutableIntList rejectedProjects;
if (originalProjects == null || originalProjects.equals(projects)) {
rejectedProjects = null;
} else {
// We projected extra columns because they were needed in filters. Now
// project the leading columns.
rejectedProjects = ImmutableIntList.identity(originalProjects.size());
}
return createEnumerable(compiler, rel, rowEnumerable, projects, mutableFilters, rejectedProjects);
}
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class ProfilerLatticeStatisticProvider method cardinality.
@Override
public double cardinality(List<Lattice.Column> columns) {
final ImmutableBitSet build = Lattice.Column.toBitSet(columns);
final double cardinality = profile.get().cardinality(build);
// System.out.println(columns + ": " + cardinality);
return cardinality;
}
Aggregations