public Split( List<Pair<Op, RexProgram>> list ) { this.list = list; /* assert filter == null || analyze( filter ).isPureFilter(); assert function == null || analyze( function ).isPureFunction(); assert constant == null || analyze( constant ).isPureConstant(); assert discard == null || analyze( discard ).isPureDiscard(); assert rename == null || analyze( rename ).isPureRename(); assert retain == null || analyze( retain ).isPureRetain(); */ Pair<Op, RexProgram> previous = null; for( Pair<Op, RexProgram> pair : list ) { if( previous != null ) assert previous.right.getOutputRowType().equals( pair.right.getInputRowType() ); previous = pair; } }
private static boolean isOnlyRename( RexProgram program ) { final List<String> inputFieldNames = program.getInputRowType().getFieldNames(); final List<String> outputFieldNames = program.getOutputRowType().getFieldNames(); return inputFieldNames.size() == outputFieldNames.size() && unique( inputFieldNames ) && unique( outputFieldNames ) && !inputFieldNames.equals( outputFieldNames ); }
public boolean isIdentity() { if( program.getCondition() != null || !program.getInputRowType().equals( program.getOutputRowType() ) ) return false; for( int i = 0; i < program.getProjectList().size(); i++ ) { RexLocalRef ref = program.getProjectList().get( i ); if( ref.getIndex() != i ) return false; } return true; } }
/** * Returns whether a program returns a subset of its input fields. Fields * are in the same order, and no input field is output more than once. * There is no condition or non-trivial expressions. */ private static boolean isRetain( RexProgram program, boolean allowRename ) { if( program.getCondition() != null ) return false; if( program.getExprList().size() > program.getInputRowType().getFieldCount() ) return false; final HashSet<Integer> used = new HashSet<Integer>(); for( Pair<RexLocalRef, String> pair : program.getNamedProjects() ) { final int index = pair.left.getIndex(); if( !used.add( index ) ) return false; // field used more than once if( !allowRename && !program.getInputRowType().getFieldNames().get( index ).equals( pair.right ) ) return false; // field projected with different name } return true; }
private static boolean isStar(RexProgram program) { int i = 0; for (RexLocalRef ref : program.getProjectList()) { if (ref.getIndex() != i++) { return false; } } return i == program.getInputRowType().getFieldCount(); } }
private static boolean isComplex( RexProgram program ) { final List<String> inputFieldNames = program.getInputRowType().getFieldNames(); final List<String> outputFieldNames = program.getOutputRowType().getFieldNames(); return !( inputFieldNames.size() == outputFieldNames.size() && unique( inputFieldNames ) && unique( outputFieldNames ) ); }
private static boolean isStar(RexProgram program) { int i = 0; for (RexLocalRef ref : program.getProjectList()) { if (ref.getIndex() != i++) { return false; } } return i == program.getInputRowType().getFieldCount(); }
private static boolean hasFunctions( RexProgram program ) { List<RexLocalRef> projects = program.getProjectList(); RelDataType inputRowType = program.getInputRowType(); int fieldCount = inputRowType.getFieldCount(); for( RexLocalRef project : projects ) { if( !program.isConstant( project ) && project.getIndex() >= fieldCount ) return true; } return false; }
private static Pipe addRename( RelOptCluster cluster, RexProgram program, Pipe pipe ) { // We know that the input has unique field names, and the output has unique // field names. if( !unique( program.getInputRowType().getFieldNames() ) ) throw new AssertionError(); if( !unique( program.getOutputRowType().getFieldNames() ) ) throw new AssertionError(); final Permutation permutation = program.getPermutation(); if( permutation == null ) throw new AssertionError(); Fields incomingFields = createTypedFields( cluster, Mappings.apply( permutation.inverse(), program.getInputRowType().getFieldList() ), false ); Fields renameFields = createTypedFieldsSelector( cluster, program.getOutputRowType(), false ); return new Rename( pipe, incomingFields, renameFields ); }
private static Pipe addFunction( RelOptCluster cluster, RexProgram program, Pipe pipe ) { final Fields incomingFields = createTypedFields( cluster, program.getInputRowType(), false ); BlockBuilder statements = new BlockBuilder(); List<Expression> expressionList = RexToLixTranslator.translateProjects( program, (JavaTypeFactory) cluster.getTypeFactory(), statements, new RexToLixTranslator.InputGetter() { public Expression field( BlockBuilder list, int index ) { final Type type = incomingFields.getType( index ); final String name = incomingFields.get( index ).toString(); return Expressions.parameter( type, name ); } } ); Expression record = Expressions.newArrayInit( Object.class, expressionList ); record = Expressions.new_( getConstructor(), record ); statements.add( Expressions.return_( null, record ) ); BlockStatement block = statements.toBlock(); String expression = Expressions.toString( block ); Fields outgoingFields = createTypedFields( cluster, program.getOutputRowType(), false ); LOG.debug( "function parameters: {}", program.getInputRowType() ); LOG.debug( "function results: {}", outgoingFields ); LOG.debug( "function expression: {}", expression ); Function scriptFunction = new ScriptTupleFunction( outgoingFields, expression, incomingFields.getTypesClasses() ); return new Each( pipe, scriptFunction, Fields.RESULTS ); }
private static Pipe addFilter( RelOptCluster cluster, RexProgram program, Pipe pipe ) { final Fields incomingFields = createTypedFields( cluster, program.getInputRowType(), false ); BlockBuilder statements = new BlockBuilder(); Expression condition = RexToLixTranslator.translateCondition( program, (JavaTypeFactory) cluster.getTypeFactory(), statements, new RexToLixTranslator.InputGetter() { public Expression field( BlockBuilder list, int index ) { return Expressions.parameter( incomingFields.getTypeClass( index ), incomingFields.get( index ).toString() ); } } ); // if condition is constant and true, we don't need an expression filter to keep it around boolean keepsAllRecords = condition instanceof ConstantExpression && Boolean.TRUE.equals( ( (ConstantExpression) condition ).value ); if( keepsAllRecords ) return pipe; // create a filter to remove records that don't meet the expression Expression nullToFalse = Expressions.call( Functions.class, "falseIfNull", condition ); Expression not = Expressions.not( nullToFalse ); // matches #isRemove semantics in Filter statements.add( Expressions.return_( null, not ) ); BlockStatement block = statements.toBlock(); String expression = Expressions.toString( block ); LOG.debug( "filter parameters: {}", incomingFields ); LOG.debug( "filter expression: {}", expression ); Filter expressionFilter = new ScriptFilter( expression, incomingFields.getTypesClasses() ); // handles coercions return new Each( pipe, expressionFilter ); }
private static RexProgram renameInputs( RexProgram program, RexBuilder rexBuilder, List<String> names ) { final RelDataType inputRowType = program.getInputRowType(); if( inputRowType.getFieldNames().equals( names ) ) return program; final RexProgramBuilder builder = RexProgramBuilder.create( rexBuilder, rexBuilder.getTypeFactory().createStructType( Pair.zip( names, RelOptUtil.getFieldTypeList( inputRowType ) ) ), program.getExprList(), program.getProjectList(), program.getCondition(), program.getOutputRowType(), false ); return builder.getProgram(); }
boolean normalize) { assert program.isValid(true); final RelDataType inputRowType = program.getInputRowType(); final List<RexLocalRef> projectRefs = program.getProjectList(); final RexLocalRef conditionRef = program.getCondition();
final RelDataType inputRowType = program.getInputRowType(); final List<RexLocalRef> projectRefs = program.getProjectList(); final RexLocalRef conditionRef = program.getCondition();
static Branch resolveBranch( Stack stack, CascadingRelNode node, RexProgram program ) { final RelOptCluster cluster = node.getCluster(); CascadingRelNode child = (CascadingRelNode) ( (SingleRel) node ).getChild(); Branch branch = child.visitChild( stack ); Pipe pipe = branch.current; final List<String> names = getIncomingFieldNames( pipe ); if( names != null && !names.equals( program.getInputRowType().getFieldNames() ) ) program = renameInputs( program, cluster.getRexBuilder(), names ); Split split = Split.of( program, cluster.getRexBuilder() ); for( Pair<Op, RexProgram> pair : split.list ) pipe = addProgram( cluster, pipe, pair.left, pair.right ); pipe = stack.addDebug( node, pipe ); return new Branch( pipe, branch ); }
RexProgram previous = RexProgram.createIdentity( program.getInputRowType() ); if( !unique( program.getInputRowType().getFieldNames() ) ) throw new AssertionError(); final List<String> outputFieldNames = new ArrayList<String>( program.getInputRowType().getFieldNames() ); builder.addProject( index, program.getInputRowType().getFieldNames().get( index ) );
public boolean isValid(boolean fail) { if (!RelOptUtil.equal( "program's input type", program.getInputRowType(), "child's output type", getChild().getRowType(),
program.getInputRowType(), "child's output type", getChild().getRowType(),
final int inputFieldCount = program.getInputRowType().getFieldCount(); int[] inputExprOrdinals = identityArray(inputFieldCount); boolean doneCondition = false;
final int inputFieldCount = program.getInputRowType().getFieldCount(); int [] inputExprOrdinals = identityArray(inputFieldCount); boolean doneCondition = false;