/** * Implement the cast expression. * * <p>TODO: check for overflow * * @return the rhs expression casted as the lhs type */ public Expression implement() { // Check for invalid null assignment. Code generated afterwards // can assume null will never be assigned to a not null value. checkNotNull(); // Check for an explicit rhs null value. Code generated // afterwards need never check for an explicit null. if (rhsType.getSqlTypeName() == SqlTypeName.NULL) { if (lhsType.isNullable()) { return castFromNull(); } else { // NOTE jvs 27-Jan-2005: this code will never actually // be executed do to previous checkNotNull test, but // it still has to compile! return rhsAsValue(); } } // Case when left hand side is a nullable primitive if (translator.isNullablePrimitive(lhsType)) { if (SqlTypeUtil.isJavaPrimitive(rhsType) && (!rhsType.isNullable() || translator.isNullablePrimitive(rhsType))) { return castPrimitiveToNullablePrimitive(); } return castToAssignableValue(); } // Case when left hand side is a not nullable primitive if (SqlTypeUtil.isJavaPrimitive(lhsType)) { return castToNotNullPrimitive(); } // Case when left hand side is a structure if (lhsType.isStruct()) { assert (rhsType.isStruct()); // TODO jvs 27-May-2004: relax this assert and deal with // conversions, null checks, etc. assert (lhsType.equals(rhsType)); return getDirectAssignment(); } // Default is to treat non-primitives as AssignableValue return castToAssignableValue(); }
/** * 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; }