/** * Generates a cast from one row type to another * * @param rexBuilder RexBuilder to use for constructing casts * @param lhsRowType target row type * @param rhsRowType source row type; fields must be 1-to-1 with lhsRowType, in same order * @return cast expressions */ public static RexNode[] generateCastExpressions( RexBuilder rexBuilder, RelDataType lhsRowType, RelDataType rhsRowType) { int n = rhsRowType.getFieldCount(); assert n == lhsRowType.getFieldCount() : "field count: lhs [" + lhsRowType + "] rhs [" + rhsRowType + "]"; RexNode[] rhsExps = new RexNode[n]; for (int i = 0; i < n; ++i) { rhsExps[i] = rexBuilder.makeInputRef(rhsRowType.getFields()[i].getType(), i); } return generateCastExpressions(rexBuilder, lhsRowType, rhsExps); }
/** * Trims a child relational expression, then adds back a dummy project to restore the fields that * were removed. * * <p>Sounds pointless? It causes unused fields to be removed further down the tree (towards the * leaves), but it ensure that the consuming relational expression continues to see the same * fields. * * @param rel Relational expression * @param input Input relational expression, whose fields to trim * @param fieldsUsed Bitmap of fields needed by the consumer * @return New relational expression and its field mapping */ protected TrimResult trimChildRestore( RelNode rel, RelNode input, BitSet fieldsUsed, Set<RelDataTypeField> extraFields) { TrimResult trimResult = trimChild(rel, input, fieldsUsed, extraFields); if (trimResult.right.isIdentity()) { return trimResult; } final RelDataType rowType = input.getRowType(); List<RelDataTypeField> fieldList = rowType.getFieldList(); final List<RexNode> exprList = new ArrayList<RexNode>(); final List<String> nameList = rowType.getFieldNames(); RexBuilder rexBuilder = rel.getCluster().getRexBuilder(); assert trimResult.right.getSourceCount() == fieldList.size(); for (int i = 0; i < fieldList.size(); i++) { int source = trimResult.right.getTargetOpt(i); RelDataTypeField field = fieldList.get(i); exprList.add( source < 0 ? rexBuilder.makeZeroLiteral(field.getType()) : rexBuilder.makeInputRef(field.getType(), source)); } RelNode project = CalcRel.createProject(trimResult.left, exprList, nameList); return new TrimResult(project, Mappings.createIdentity(fieldList.size())); }