}
protected void apply(RelOptRuleCall call, ProjectRelBase postProject,
final AggregateRelBase aggregate, StarTable.StarTableScan scan) {
final RelOptCluster cluster = scan.getCluster();
final RelOptTable table = scan.getTable();
final RelOptLattice lattice = call.getPlanner().getLattice(table);
final List<Lattice.Measure> measures =
lattice.lattice.toMeasures(aggregate.getAggCallList());
Pair<OptiqSchema.TableEntry, MaterializationService.TileKey> pair =
lattice.getAggregate(call.getPlanner(), aggregate.getGroupSet(),
measures);
if (pair == null) {
return;
}
final OptiqSchema.TableEntry tableEntry = pair.left;
final MaterializationService.TileKey tileKey = pair.right;
final double rowCount = aggregate.getRows();
final Table aggregateTable = tableEntry.getTable();
final RelDataType aggregateTableRowType =
aggregateTable.getRowType(cluster.getTypeFactory());
final RelOptTable aggregateRelOptTable =
RelOptTableImpl.create(table.getRelOptSchema(), aggregateTableRowType,
tableEntry, rowCount);
RelNode rel = aggregateRelOptTable.toRel(RelOptUtil.getContext(cluster));
if (tileKey == null) {
if (OptiqPrepareImpl.DEBUG) {
System.out.println("Using materialization "
+ aggregateRelOptTable.getQualifiedName()
+ " (exact match)");
}
} else if (!tileKey.dimensions.equals(aggregate.getGroupSet())) {
// Aggregate has finer granularity than we need. Roll up.
if (OptiqPrepareImpl.DEBUG) {
System.out.println("Using materialization "
+ aggregateRelOptTable.getQualifiedName()
+ ", rolling up " + tileKey.dimensions + " to "
+ aggregate.getGroupSet());
}
assert BitSets.contains(tileKey.dimensions, aggregate.getGroupSet());
final List<AggregateCall> aggCalls = Lists.newArrayList();
for (AggregateCall aggCall : aggregate.getAggCallList()) {
final AggregateCall copy = rollUp(aggCall, tileKey);
if (copy == null) {
return;
}
aggCalls.add(copy);
}
BitSet groupSet = new BitSet();
for (int key : BitSets.toIter(aggregate.getGroupSet())) {
groupSet.set(BitSets.toList(tileKey.dimensions).indexOf(key));
}
rel = aggregate.copy(aggregate.getTraitSet(), rel, groupSet, aggCalls);
} else if (!tileKey.measures.equals(measures)) {
System.out.println("Using materialization "
+ aggregateRelOptTable.getQualifiedName()
+ ", right granularity, but different measures "
+ aggregate.getAggCallList());
rel = RelOptUtil.project(rel,
new AbstractSourceMapping(
tileKey.dimensions.cardinality() + tileKey.measures.size(),