@Override
public Branch visitChild( Stack stack )
{
RelNode child = getChild();
Branch branch = ( (CascadingRelNode) child ).visitChild( stack );
Fields outgoingNamedFields = RelUtil.createTypedFieldsFor( this, false );
// assumption here is if aggCalls is empty, we are performing a DISTINCT on the group set
if( getAggCallList().isEmpty() )
{
Pipe current = new Unique( branch.current, outgoingNamedFields );
current = stack.addDebug( this, current );
return new Branch( current, branch );
}
if( getInputs().size() != 1 )
throw new UnsupportedOperationException( "multiple inputs not supported, found: " + getInputs().size() );
RelDataType inputRowType = getInput( 0 ).getRowType();
Pipe previous = branch.current;
Fields groupFields = RelUtil.createTypedFields( getCluster(), inputRowType, Util.toIter( getGroupSet() ), false );
List<AggregateCall> distincts = new ArrayList<AggregateCall>();
List<AggregateCall> concurrents = new ArrayList<AggregateCall>();
gatherAggregateCalls( distincts, concurrents );
AggregateBy concurrentAggregates = createConcurrentAggregates( inputRowType, previous, groupFields, concurrents );
Pipe[] distinctAggregates = createDistinctAggregates( stack, inputRowType, previous, groupFields, distincts );
if( concurrentAggregates == null && distinctAggregates == null )
throw new IllegalStateException( "concurrent and distinct aggregates are null" );
if( concurrentAggregates != null && distinctAggregates == null )
return new Branch( stack.addDebug( this, concurrentAggregates ), branch );
if( concurrentAggregates == null && distinctAggregates != null && distinctAggregates.length == 1 )
return new Branch( stack.addDebug( this, distinctAggregates[ 0 ] ), branch );
Pipe[] pipes = createPipes( concurrentAggregates, distinctAggregates );
Fields declaredFields = createDeclaredFields( groupFields, distincts, concurrentAggregates );
Fields declaredPosFields = Fields.size( declaredFields.size() ).applyTypes( declaredFields.getTypes() );
Fields[] groupFieldsArray = createGroupingFields( groupFields, pipes );
String name = stack.getNameFor( groupFields.isNone() ? HashJoin.class : CoGroup.class, pipes );
Pipe join;
if( groupFields.isNone() ) // not grouping, just appending tuples into a single row
join = new HashJoin( name, pipes, groupFieldsArray, declaredFields, new InnerJoin() );
else
join = new CoGroup( name, pipes, groupFieldsArray, declaredFields, new InnerJoin() );
join = new Retain( join, outgoingNamedFields );
join = stack.addDebug( this, join );
return new Branch( join, branch );
}