super(RelOptHelper.some(DrillWindowRel.class, DrillRel.DRILL_LOGICAL, RelOptHelper.any(RelNode.class)), "Prel.WindowPrule");
}
@Override
public void onMatch(RelOptRuleCall call) {
final DrillWindowRel window = call.rel(0);
RelNode input = call.rel(1);
// TODO: Order window based on existing partition by
//input.getTraitSet().subsumes()
for (final Ord<WindowRelBase.Window> w : Ord.zip(window.windows)) {
WindowRelBase.Window windowBase = w.getValue();
DrillDistributionTrait distOnAllKeys =
new DrillDistributionTrait(DrillDistributionTrait.DistributionType.HASH_DISTRIBUTED,
ImmutableList.copyOf(getDistributionFields(windowBase)));
RelCollation collation = getCollation(windowBase);
RelTraitSet traits = call.getPlanner().emptyTraitSet().plus(Prel.DRILL_PHYSICAL).plus(collation).plus(distOnAllKeys);
final RelNode convertedInput = convert(input, traits);
List<RelDataTypeField> newRowFields = Lists.newArrayList();
for(RelDataTypeField field : convertedInput.getRowType().getFieldList()) {
newRowFields.add(field);
}
Iterable<RelDataTypeField> newWindowFields = Iterables.filter(window.getRowType().getFieldList(), new Predicate<RelDataTypeField>() {
@Override
public boolean apply(RelDataTypeField relDataTypeField) {
return relDataTypeField.getName().startsWith("w" + w.i + "$");
}
});
for(RelDataTypeField newField : newWindowFields) {
newRowFields.add(newField);
}
RelDataType rowType = new RelRecordType(newRowFields);
List<WindowRelBase.RexWinAggCall> newWinAggCalls = Lists.newArrayList();
for(Ord<WindowRelBase.RexWinAggCall> aggOrd : Ord.zip(windowBase.aggCalls)) {
WindowRelBase.RexWinAggCall aggCall = aggOrd.getValue();
newWinAggCalls.add(new WindowRelBase.RexWinAggCall(
(SqlAggFunction)aggCall.getOperator(), aggCall.getType(), aggCall.getOperands(), aggOrd.i)
);
}
windowBase = new WindowRelBase.Window(
windowBase.groupSet,
windowBase.isRows,
windowBase.lowerBound,
windowBase.upperBound,
windowBase.orderKeys,
newWinAggCalls
);
input = new StreamingWindowPrel(
window.getCluster(),
window.getTraitSet().merge(traits),
convertedInput,
window.getConstants(),
rowType,
windowBase);
}
call.transformTo(input);