if( analyze.permutation != null && !analyze.permutation.isIdentity() )
{
if( analyze.hasConstants || analyze.hasFunctions )
throw new IllegalStateException( "permutation projection has constant and function transforms" );
final RexProgramBuilder builder = new RexProgramBuilder( previous.getOutputRowType(), rexBuilder );
for( int i = 0; i < analyze.permutation.getTargetCount(); i++ )
{
final int target = analyze.permutation.getTarget( i );
builder.addProject( target, null );
}
previous = builder.getProgram();
list.add( Pair.of( Op.RENAME, previous ) );
break;
}
if( analyze.isFilter() )
{
// Build a program that has a condition (a possibly complex expression)
// but projects all inputs.
final RexProgramBuilder builder = new RexProgramBuilder( previous.getOutputRowType(), rexBuilder );
builder.addIdentity();
builder.addCondition( program.gatherExpr( program.getCondition() ) );
previous = builder.getProgram();
list.add( Pair.of( Op.FILTER, previous ) );
// Remove condition from the remaining program.
final RexProgramBuilder builder2 = RexProgramBuilder.forProgram( program, rexBuilder, false );
builder2.clearCondition();
program = builder2.getProgram( true );
continue;
}
// TODO: remove "|| analyze.hasConstants" and generate a CONSTANTS slice
if( analyze.isComplex || analyze.hasFunctions || analyze.hasConstants )
{
previous = program;
list.add( Pair.of( Op.FUNCTION, previous ) );
break;
}
if( analyze.hasConstants )
{
final RexProgramBuilder builder = new RexProgramBuilder( previous.getOutputRowType(), rexBuilder );
if( true )
throw new AssertionError(); // TODO:
previous = builder.getProgram();
list.add( Pair.of( Op.CONSTANT, previous ) );
continue;
}
if( analyze.isOnlyRename )
{
// Create a program that projects all of its inputs, in order, but with different names.
final RexProgramBuilder builder = new RexProgramBuilder( previous.getOutputRowType(), rexBuilder );
final List<String> outputFieldNames = new ArrayList<String>( program.getInputRowType().getFieldNames() );
for( Ord<String> name : Ord.zip( program.getOutputRowType().getFieldNames() ) )
{
final int source = program.getSourceField( name.i );
if( source >= 0 )
outputFieldNames.set( source, name.e );
}
for( int i = 0; i < outputFieldNames.size(); i++ )
builder.addProject( i, outputFieldNames.get( i ) );
previous = builder.getProgram();
list.add( Pair.of( Op.RENAME, previous ) );
// We're done. Remaining program would be the identity.
break;
}
if( analyze.isRetainWithRename() )
{
final RexProgramBuilder builder = new RexProgramBuilder( previous.getOutputRowType(), rexBuilder );
builder.addIdentity();
builder.clearProjects();
for( RexLocalRef pair : program.getProjectList() )
{
final int index = pair.getIndex();
builder.addProject( index, program.getInputRowType().getFieldNames().get( index ) );
}
previous = builder.getProgram();
list.add( Pair.of( Op.RETAIN, previous ) );
// There may or may not be renames left.
program = RexProgram.createIdentity( previous.getOutputRowType(), program.getOutputRowType() );