/** * Generates a cast for a row type. * * @param rexBuilder RexBuilder to use for constructing casts * @param lhsRowType target row type * @param rhsExps expressions to be cast * @return cast expressions */ public static RexNode[] generateCastExpressions( RexBuilder rexBuilder, RelDataType lhsRowType, RexNode[] rhsExps) { RelDataTypeField[] lhsFields = lhsRowType.getFields(); final int fieldCount = lhsFields.length; RexNode[] castExps = new RexNode[fieldCount]; assert fieldCount == rhsExps.length; for (int i = 0; i < fieldCount; ++i) { RelDataTypeField lhsField = lhsFields[i]; RelDataType lhsType = lhsField.getType(); RelDataType rhsType = rhsExps[i].getType(); if (lhsType.equals(rhsType)) { castExps[i] = rhsExps[i]; } else { castExps[i] = rexBuilder.makeCast(lhsType, rhsExps[i]); } } return castExps; }
private static List<RelCollation> deduceMonotonicity(Prepare.PreparingTable table) { final List<RelCollation> collationList = new ArrayList<RelCollation>(); // Deduce which fields the table is sorted on. int i = -1; for (RelDataTypeField field : table.getRowType().getFieldList()) { ++i; final SqlMonotonicity monotonicity = table.getMonotonicity(field.getName()); if (monotonicity != SqlMonotonicity.NotMonotonic) { final RelFieldCollation.Direction direction = monotonicity.isDecreasing() ? RelFieldCollation.Direction.Descending : RelFieldCollation.Direction.Ascending; collationList.add( RelCollationImpl.of( new RelFieldCollation(i, direction, RelFieldCollation.NullDirection.UNSPECIFIED))); } } return collationList; }
private List<RelCollation> deduceMonotonicity(SqlValidatorTable table) { final RelDataType rowType = table.getRowType(); final List<RelCollation> collationList = new ArrayList<RelCollation>(); // Deduce which fields the table is sorted on. int i = -1; for (RelDataTypeField field : rowType.getFieldList()) { ++i; final SqlMonotonicity monotonicity = table.getMonotonicity(field.getName()); if (monotonicity != SqlMonotonicity.NOT_MONOTONIC) { final RelFieldCollation.Direction direction = monotonicity.isDecreasing() ? RelFieldCollation.Direction.DESCENDING : RelFieldCollation.Direction.ASCENDING; collationList.add( RelCollationImpl.of( new RelFieldCollation( i, direction, RelFieldCollation.NullDirection.UNSPECIFIED))); } } return collationList; }
/** * 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())); }