/** Creates an array of {@link RexLocalRef} objects, one for each field of a given rowtype. */ public static RexLocalRef[] toLocalRefs(RelDataType rowType) { final RelDataTypeField[] fields = rowType.getFields(); final RexLocalRef[] refs = new RexLocalRef[fields.length]; for (int i = 0; i < refs.length; i++) { refs[i] = new RexLocalRef(i, fields[i].getType()); } return refs; }
/** * Creates an array of {@link RexInputRef} objects, one for each field of a given rowtype, * according to a permutation. * * @param args Permutation * @param rowType Input row type * @return Array of input refs */ public static RexInputRef[] toInputRefs(int[] args, RelDataType rowType) { final RelDataTypeField[] fields = rowType.getFields(); final RexInputRef[] rexNodes = new RexInputRef[args.length]; for (int i = 0; i < args.length; i++) { int fieldOrdinal = args[i]; rexNodes[i] = new RexInputRef(fieldOrdinal, fields[fieldOrdinal].getType()); } return rexNodes; }
/** * 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); }
/** * Returns whether the type of an array of expressions is compatible with a struct type. * * @param exprs Array of expressions * @param type Type * @param fail Whether to fail if there is a mismatch * @return Whether every expression has the same type as the corresponding member of the struct * type * @see RelOptUtil#eq(String, RelDataType, String, RelDataType, boolean) */ public static boolean compatibleTypes(RexNode[] exprs, RelDataType type, boolean fail) { final RelDataTypeField[] fields = type.getFields(); if (exprs.length != fields.length) { assert !fail : "rowtype mismatches expressions"; return false; } for (int i = 0; i < fields.length; i++) { final RelDataType exprType = exprs[i].getType(); final RelDataType fieldType = fields[i].getType(); if (!RelOptUtil.eq("type1", exprType, "type2", fieldType, fail)) { return false; } } return true; }
/** * 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; }
/** * Returns whether the leading edge of a given array of expressions is wholly {@link RexInputRef} * objects with types corresponding to the underlying datatype. */ public static boolean containIdentity(RexNode[] exprs, RelDataType rowType, boolean fail) { final RelDataTypeField[] fields = rowType.getFields(); if (exprs.length < fields.length) { assert !fail : "exprs/rowType length mismatch"; return false; } for (int i = 0; i < fields.length; i++) { if (!(exprs[i] instanceof RexInputRef)) { assert !fail : "expr[" + i + "] is not a RexInputRef"; return false; } RexInputRef inputRef = (RexInputRef) exprs[i]; if (inputRef.getIndex() != i) { assert !fail : "expr[" + i + "] has ordinal " + inputRef.getIndex(); return false; } if (!RelOptUtil.eq("type1", exprs[i].getType(), "type2", fields[i].getType(), fail)) { return false; } } return true; }