/** * 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(); }
/** * Gets the right hand expression as a valid value to be assigned to the left hand side. Usually * returns the original rhs. However, if the lhs is of a primitive type, and the rhs is an * explicit null, returns a primitive value instead. */ private Expression rhsAsValue() { if (SqlTypeUtil.isJavaPrimitive(lhsType) && (rhsType.getSqlTypeName() == SqlTypeName.NULL)) { if (lhsType.getSqlTypeName() == SqlTypeName.BOOLEAN) { return Literal.constantFalse(); } else { return Literal.constantZero(); } } return rhsExp; }