Object castOrConvertToType(SessionInterface session, Object a, Type otherType, boolean cast) { BlobData b; if (a == null) { return null; } switch (otherType.typeCode) { // non-SQL feature, for compatibility with previous versions case Types.SQL_VARCHAR: case Types.SQL_CHAR: { b = session.getScanner().convertToBinary((String) a); otherType = getBinaryType(Types.SQL_VARBINARY, b.length(session)); break; } case Types.SQL_BIT: { b = (BlobData) a; otherType = getBinaryType(Types.SQL_VARBINARY, b.length(session)); break; } case Types.SQL_BINARY: case Types.SQL_VARBINARY: case Types.SQL_BLOB: b = (BlobData) a; break; default: throw Error.error(ErrorCode.X_22501); } if (precision == 0) { return b; // never a blob } if (b.length(session) > precision && b.nonZeroLength(session) > precision) { if (!cast) { throw Error.error(ErrorCode.X_22001); } session.addWarning(Error.error(ErrorCode.W_01004)); } if (otherType.typeCode == Types.SQL_BLOB) { byte[] bytes = b.getBytes(session, 0, (int) precision); b = new BinaryData(bytes, false); } switch (typeCode) { case Types.SQL_BINARY: { if (b.length(session) > precision) { byte[] data = b.getBytes(session, 0, (int) precision); b = new BinaryData(data, false); } else if (b.length(session) < precision) { byte[] data = (byte[]) ArrayUtil.resizeArray(b.getBytes(), (int) precision); b = new BinaryData(data, false); } return b; } case Types.SQL_VARBINARY: { if (b.length(session) > precision) { byte[] data = b.getBytes(session, 0, (int) precision); b = new BinaryData(data, false); } return b; } default: } throw Error.error(ErrorCode.X_22501); }
@Override public Object convertToType(SessionInterface session, Object a, Type otherType) { if (a == null) { return a; } if (otherType.typeCode == typeCode) { switch (typeCode) { case Types.SQL_NUMERIC: case Types.SQL_DECIMAL: if (otherType.scale == scale && otherType.precision <= precision) { return a; } break; default: return a; } } if (otherType.isIntervalType()) { int endType = ((IntervalType) otherType).endIntervalType; switch (endType) { case Types.SQL_INTERVAL_YEAR: case Types.SQL_INTERVAL_MONTH: case Types.SQL_INTERVAL_DAY: case Types.SQL_INTERVAL_HOUR: case Types.SQL_INTERVAL_MINUTE: { Long value = ValuePool.getLong(((IntervalType) otherType).convertToLong(a)); return convertToType(session, value, Type.SQL_BIGINT); } case Types.SQL_INTERVAL_SECOND: { long seconds = ((IntervalSecondData) a).units; long nanos = ((IntervalSecondData) a).nanos; BigDecimal value = ((DTIType) otherType).getSecondPart(seconds, nanos); return value; } } } switch (otherType.typeCode) { case Types.SQL_CLOB: a = ((ClobData) a).getSubString(session, 0L, (int) ((ClobData) a).length(session)); // fall through case Types.SQL_CHAR: case Types.SQL_VARCHAR: case Types.VARCHAR_IGNORECASE: { a = session.getScanner().convertToNumber((String) a, this); return convertToDefaultType(session, a); } case Types.TINYINT: case Types.SQL_SMALLINT: case Types.SQL_INTEGER: case Types.SQL_BIGINT: case Types.SQL_REAL: case Types.SQL_FLOAT: case Types.SQL_DOUBLE: case Types.SQL_NUMERIC: case Types.SQL_DECIMAL: break; default: throw Error.error(ErrorCode.X_42561); } switch (this.typeCode) { case Types.TINYINT: case Types.SQL_SMALLINT: case Types.SQL_INTEGER: return convertToInt(a, this.typeCode); case Types.SQL_BIGINT: return convertToLong(a); case Types.SQL_REAL: case Types.SQL_FLOAT: case Types.SQL_DOUBLE: return convertToDouble(a); case Types.SQL_NUMERIC: case Types.SQL_DECIMAL: BigDecimal value = convertToDecimal(a); return convertToTypeLimits(session, value); default: throw Error.error(ErrorCode.X_42561); } }