@Override
public PhysicalOperator visitCollapsingAggregate(CollapsingAggregate agg, Object value)
throws OptimizerException {
if( !(agg.getInput() instanceof Segment) ){
throw new OptimizerException(String.format("Currently, Drill only supports CollapsingAggregate immediately preceded by a Segment. The input of this operator is %s.", agg.getInput()));
}
Segment segment = (Segment) agg.getInput();
if(!agg.getWithin().equals(segment.getName())){
throw new OptimizerException(String.format("Currently, Drill only supports CollapsingAggregate immediately preceded by a Segment where the CollapsingAggregate works on the defined segments. In this case, the segment has been defined based on the name %s but the collapsing aggregate is working within the field %s.", segment.getName(), agg.getWithin()));
}
// a collapsing aggregate is a currently implemented as a sort followed by a streaming aggregate.
List<OrderDef> orderDefs = Lists.newArrayList();
List<NamedExpression> keys = Lists.newArrayList();
for(LogicalExpression e : segment.getExprs()){
if( !(e instanceof SchemaPath)) throw new OptimizerException("The basic optimizer doesn't currently support collapsing aggregate where the segment value is something other than a SchemaPath.");
keys.add(new NamedExpression(e, new FieldReference((SchemaPath) e)));
orderDefs.add(new OrderDef(Direction.ASC, e));
}
Sort sort = new Sort(segment.getInput().accept(this, value), orderDefs, false);