/** * Applies a mapping to a list. * * @param mapping Mapping * @param list List * @param <T> Element type * @return List with elements permuted according to mapping */ public static <T> List<T> apply(final Mapping mapping, final List<T> list) { if (mapping.getSourceCount() != list.size()) { // REVIEW: too strict? throw new IllegalArgumentException( "mapping source count " + mapping.getSourceCount() + " does not match list size " + list.size()); } final int targetCount = mapping.getTargetCount(); final List<T> list2 = new ArrayList<T>(targetCount); for (int target = 0; target < targetCount; ++target) { final int source = mapping.getSource(target); list2.add(list.get(source)); } return list2; }
/** * Creates a relational expression which projects the output fields of a relational expression * according to a partial mapping. * * <p>A partial mapping is weaker than a permutation: every target has one source, but a source * may have 0, 1 or more than one targets. Usually the result will have fewer fields than the * source, unless some source fields are projected multiple times. * * <p>This method could optimize the result as {@link #permute} does, but does not at present. * * @param rel Relational expression * @param mapping Mapping from source fields to target fields. The mapping type must obey the * constaints {@link MappingType#isMandatorySource()} and {@link * MappingType#isSingleSource()}, as does {@link MappingType#InverseFunction}. * @param fieldNames Field names; if null, or if a particular entry is null, the name of the * permuted field is used * @return relational expression which projects a subset of the input fields */ public static RelNode projectMapping(RelNode rel, Mapping mapping, List<String> fieldNames) { assert mapping.getMappingType().isSingleSource(); assert mapping.getMappingType().isMandatorySource(); if (mapping.isIdentity()) { return rel; } final List<RelDataType> outputTypeList = new ArrayList<RelDataType>(); final List<String> outputNameList = new ArrayList<String>(); final List<RexNode> exprList = new ArrayList<RexNode>(); final List<RexLocalRef> projectRefList = new ArrayList<RexLocalRef>(); final List<RelDataTypeField> fields = rel.getRowType().getFieldList(); for (int i = 0; i < fields.size(); i++) { final RelDataTypeField field = fields.get(i); exprList.add(rel.getCluster().getRexBuilder().makeInputRef(field.getType(), i)); } for (int i = 0; i < mapping.getTargetCount(); i++) { int source = mapping.getSource(i); final RelDataTypeField sourceField = fields.get(source); outputTypeList.add(sourceField.getType()); outputNameList.add( ((fieldNames == null) || (fieldNames.size() <= i) || (fieldNames.get(i) == null)) ? sourceField.getName() : fieldNames.get(i)); projectRefList.add(new RexLocalRef(source, sourceField.getType())); } final RexProgram program = new RexProgram( rel.getRowType(), exprList, projectRefList, null, rel.getCluster().getTypeFactory().createStructType(outputTypeList, outputNameList)); return new CalcRel( rel.getCluster(), rel.getTraitSet(), rel, program.getOutputRowType(), program, Collections.<RelCollation>emptyList()); }
public int getTarget(int source) { return parent.getSource(source); }