/** * Returns whether this program is in canonical form. * * @param fail Whether to throw an assertion error if not in canonical * form * @param rexBuilder Rex builder * @return whether in canonical form */ public boolean isNormalized(boolean fail, RexBuilder rexBuilder) { final RexProgram normalizedProgram = RexProgramBuilder.normalize(rexBuilder, this); String normalized = normalizedProgram.toString(); String string = toString(); if (!normalized.equals(string)) { assert !fail : "Program is not normalized:\n" + "program: " + string + "\n" + "normalized: " + normalized + "\n"; return false; } return true; }
/** * Creates a copy of this program. */ public RexProgram copy() { return new RexProgram( inputRowType, exprs, projects, (condition == null) ? null : condition.clone(), outputRowType); }
/** * Creates a program which calculates projections and filters rows based * upon a condition. Does not attempt to eliminate common sub-expressions. * * @param projectExprs Project expressions * @param conditionExpr Condition on which to filter rows, or null if rows * are not to be filtered * @param outputRowType Output row type * @param rexBuilder Builder of rex expressions * @return A program */ public static RexProgram create( RelDataType inputRowType, List<RexNode> projectExprs, RexNode conditionExpr, RelDataType outputRowType, RexBuilder rexBuilder) { return create( inputRowType, projectExprs, conditionExpr, outputRowType.getFieldNames(), rexBuilder); }
/** * Returns whether this program returns its input exactly. * * <p>This is a stronger condition than {@link #projectsIdentity(boolean)}. */ public boolean isTrivial() { return getCondition() == null && projectsOnlyIdentity(); }
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; } }
public static double estimateFilteredRows(RelNode child, RexProgram program) { // convert the program's RexLocalRef condition to an expanded RexNode RexLocalRef programCondition = program.getCondition(); RexNode condition; if (programCondition == null) { condition = null; } else { condition = program.expandLocalRef(programCondition); } return estimateFilteredRows( child, condition); }
RexProgram previous = RexProgram.createIdentity( program.getInputRowType() ); if( !unique( program.getInputRowType().getFieldNames() ) ) throw new AssertionError(); if( !unique( program.getOutputRowType().getFieldNames() ) ) throw new AssertionError(); final RexProgramBuilder builder = new RexProgramBuilder( previous.getOutputRowType(), rexBuilder ); 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 ) ); final RexProgramBuilder builder = new RexProgramBuilder( previous.getOutputRowType(), rexBuilder ); 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 ); final RexProgramBuilder builder = new RexProgramBuilder( previous.getOutputRowType(), rexBuilder ); builder.addIdentity(); builder.clearProjects();
RexProgram.create( joinChildrenRowType, Pair.left(projects), mergedProgram.expandLocalRef( mergedProgram.getCondition()); JoinRel newJoinRel = new JoinRel( List<RexLocalRef> projList = mergedProgram.getProjectList(); List<RelDataTypeField> newJoinFields = newJoinRel.getRowType().getFieldList(); int [] adjustments = new int[nJoinFields]; for (int i = 0; i < nProjExprs; i++) { RexNode newExpr = mergedProgram.expandLocalRef(projList.get(i)); if (joinType != JoinRelType.INNER) { newExpr =
public boolean isValid(boolean fail) { if (!RelOptUtil.equal( "program's input type", program.getInputRowType(), "child's output type", getChild().getRowType(), program.getOutputRowType(), "declared rowtype of rel", rowType, return false; if (!program.isValid(fail)) { return false; if (!program.isNormalized(fail, getCluster().getRexBuilder())) { return false;
private List<RexLocalRef> registerProjectsAndCondition(RexProgram program) { final List<RexNode> exprList = program.getExprList(); final List<RexLocalRef> projectRefList = new ArrayList<RexLocalRef>(); final RexShuttle shuttle = new RegisterOutputShuttle(exprList); // For each project, lookup the expr and expand it so it is in terms of // bottomCalc's input fields for (RexLocalRef topProject : program.getProjectList()) { final RexNode topExpr = exprList.get(topProject.getIndex()); final RexLocalRef expanded = (RexLocalRef) topExpr.accept(shuttle); // Remember the expr, but don't add to the project list yet. projectRefList.add(expanded); } // Similarly for the condition. final RexLocalRef topCondition = program.getCondition(); if (topCondition != null) { final RexNode topExpr = exprList.get(topCondition.getIndex()); final RexLocalRef expanded = (RexLocalRef) topExpr.accept(shuttle); addCondition(registerInput(expanded)); } return projectRefList; }
Permutation permutation1 = calcRel.getProgram().getPermutation(); if (permutation1 != null) { Permutation permutation2 = permutation.product(permutation1); new RexProgram( rel.getRowType(), exprList, rel.getTraitSet(), rel, program.getOutputRowType(), program, Collections.<RelCollation>emptyList());
RexProgram.create(child.getChild().getRowType(), child.getProjects(), null, child.getRowType(), child.getCluster().getRexBuilder()); Map<Integer, RexNode> constants = new HashMap<Integer, RexNode>(); for (int i : BitSets.toIter(aggregate.getGroupSet())) { final RexLocalRef ref = program.getProjectList().get(i); if (program.isConstant(ref)) { constantList.add(i); constants.put( i, program.gatherExpr(ref));
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; } }
/** * 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 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; }
public static List<RexLiteral> getOutputConstantsLiterals( RexProgram program ) { List<RexNode> exprList = program.getExprList(); List<RexLiteral> literals = new ArrayList<RexLiteral>(); List<RexLocalRef> projectList = program.getProjectList(); for( RexLocalRef ref : projectList ) { if( !program.isConstant( ref ) ) continue; literals.add( (RexLiteral) exprList.get( ref.getIndex() ) ); } return literals; }
RexProgram.create( projRel.getChild().getRowType(), projRel.getProjects(), rexBuilder); return mergedProgram.expandLocalRef( mergedProgram.getCondition());
RexProgram.create( bottomProject.getChild().getRowType(), bottomProject.getProjects(), RexProgram.create( bottomProject.getRowType(), projExprs, List<RexLocalRef> projList = mergedProgram.getProjectList(); for (int i = 0; i < nProjExprs; i++) { newProjExprs.add(mergedProgram.expandLocalRef(projList.get(i)));
public static RelDataType getOutputConstantsRowType( RexProgram program ) { RelDataType outputRowType = program.getOutputRowType(); List<RelDataTypeField> fields = new ArrayList<RelDataTypeField>(); List<RexLocalRef> projectList = program.getProjectList(); for( int i = 0; i < projectList.size(); i++ ) { RexLocalRef ref = projectList.get( i ); if( !program.isConstant( ref ) ) continue; fields.add( outputRowType.getFieldList().get( i ) ); } return new RelRecordType( fields ); }
/** * Returns whether a program contains a multiset. */ public static boolean containsMultiset(RexProgram program) { final boolean deep = true; for (RexNode expr : program.getExprList()) { if (containsMultiset(expr, deep)) { return true; } } return false; }