Search in sources :

Example 6 with ValueTime

use of org.h2.value.ValueTime in project h2database by h2database.

the class Value method convertTo.

/**
 * Compare a value to the specified type.
 *
 * @param targetType the type of the returned value
 * @param precision the precision of the column to convert this value to.
 *        The special constant <code>-1</code> is used to indicate that
 *        the precision plays no role when converting the value
 * @param mode the conversion mode
 * @param column the column (if any), used for to improve the error message if conversion fails
 * @param enumerators the ENUM datatype enumerators (if any),
 *        for dealing with ENUM conversions
 * @return the converted value
 */
public Value convertTo(int targetType, int precision, Mode mode, Object column, String[] enumerators) {
    // converting BLOB to CLOB and vice versa is done in ValueLob
    if (getType() == targetType) {
        return this;
    }
    try {
        // decimal conversion
        switch(targetType) {
            case BOOLEAN:
                {
                    switch(getType()) {
                        case BYTE:
                        case SHORT:
                        case INT:
                        case LONG:
                        case DECIMAL:
                        case DOUBLE:
                        case FLOAT:
                            return ValueBoolean.get(getSignum() != 0);
                        case TIME:
                        case DATE:
                        case TIMESTAMP:
                        case TIMESTAMP_TZ:
                        case BYTES:
                        case JAVA_OBJECT:
                        case UUID:
                        case ENUM:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case BYTE:
                {
                    switch(getType()) {
                        case BOOLEAN:
                            return ValueByte.get(getBoolean() ? (byte) 1 : (byte) 0);
                        case SHORT:
                        case ENUM:
                        case INT:
                            return ValueByte.get(convertToByte(getInt(), column));
                        case LONG:
                            return ValueByte.get(convertToByte(getLong(), column));
                        case DECIMAL:
                            return ValueByte.get(convertToByte(convertToLong(getBigDecimal(), column), column));
                        case DOUBLE:
                            return ValueByte.get(convertToByte(convertToLong(getDouble(), column), column));
                        case FLOAT:
                            return ValueByte.get(convertToByte(convertToLong(getFloat(), column), column));
                        case BYTES:
                            return ValueByte.get((byte) Integer.parseInt(getString(), 16));
                        case TIMESTAMP_TZ:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case SHORT:
                {
                    switch(getType()) {
                        case BOOLEAN:
                            return ValueShort.get(getBoolean() ? (short) 1 : (short) 0);
                        case BYTE:
                            return ValueShort.get(getByte());
                        case ENUM:
                        case INT:
                            return ValueShort.get(convertToShort(getInt(), column));
                        case LONG:
                            return ValueShort.get(convertToShort(getLong(), column));
                        case DECIMAL:
                            return ValueShort.get(convertToShort(convertToLong(getBigDecimal(), column), column));
                        case DOUBLE:
                            return ValueShort.get(convertToShort(convertToLong(getDouble(), column), column));
                        case FLOAT:
                            return ValueShort.get(convertToShort(convertToLong(getFloat(), column), column));
                        case BYTES:
                            return ValueShort.get((short) Integer.parseInt(getString(), 16));
                        case TIMESTAMP_TZ:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case INT:
                {
                    switch(getType()) {
                        case BOOLEAN:
                            return ValueInt.get(getBoolean() ? 1 : 0);
                        case BYTE:
                        case ENUM:
                        case SHORT:
                            return ValueInt.get(getInt());
                        case LONG:
                            return ValueInt.get(convertToInt(getLong(), column));
                        case DECIMAL:
                            return ValueInt.get(convertToInt(convertToLong(getBigDecimal(), column), column));
                        case DOUBLE:
                            return ValueInt.get(convertToInt(convertToLong(getDouble(), column), column));
                        case FLOAT:
                            return ValueInt.get(convertToInt(convertToLong(getFloat(), column), column));
                        case BYTES:
                            return ValueInt.get((int) Long.parseLong(getString(), 16));
                        case TIMESTAMP_TZ:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case LONG:
                {
                    switch(getType()) {
                        case BOOLEAN:
                            return ValueLong.get(getBoolean() ? 1 : 0);
                        case BYTE:
                        case SHORT:
                        case ENUM:
                        case INT:
                            return ValueLong.get(getInt());
                        case DECIMAL:
                            return ValueLong.get(convertToLong(getBigDecimal(), column));
                        case DOUBLE:
                            return ValueLong.get(convertToLong(getDouble(), column));
                        case FLOAT:
                            return ValueLong.get(convertToLong(getFloat(), column));
                        case BYTES:
                            {
                                // parseLong doesn't work for ffffffffffffffff
                                byte[] d = getBytes();
                                if (d.length == 8) {
                                    return ValueLong.get(Bits.readLong(d, 0));
                                }
                                return ValueLong.get(Long.parseLong(getString(), 16));
                            }
                        case TIMESTAMP_TZ:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case DECIMAL:
                {
                    switch(getType()) {
                        case BOOLEAN:
                            return ValueDecimal.get(BigDecimal.valueOf(getBoolean() ? 1 : 0));
                        case BYTE:
                        case SHORT:
                        case ENUM:
                        case INT:
                            return ValueDecimal.get(BigDecimal.valueOf(getInt()));
                        case LONG:
                            return ValueDecimal.get(BigDecimal.valueOf(getLong()));
                        case DOUBLE:
                            {
                                double d = getDouble();
                                if (Double.isInfinite(d) || Double.isNaN(d)) {
                                    throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, "" + d);
                                }
                                return ValueDecimal.get(BigDecimal.valueOf(d));
                            }
                        case FLOAT:
                            {
                                float f = getFloat();
                                if (Float.isInfinite(f) || Float.isNaN(f)) {
                                    throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, "" + f);
                                }
                                // better rounding behavior than BigDecimal.valueOf(f)
                                return ValueDecimal.get(new BigDecimal(Float.toString(f)));
                            }
                        case TIMESTAMP_TZ:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case DOUBLE:
                {
                    switch(getType()) {
                        case BOOLEAN:
                            return ValueDouble.get(getBoolean() ? 1 : 0);
                        case BYTE:
                        case SHORT:
                        case INT:
                            return ValueDouble.get(getInt());
                        case LONG:
                            return ValueDouble.get(getLong());
                        case DECIMAL:
                            return ValueDouble.get(getBigDecimal().doubleValue());
                        case FLOAT:
                            return ValueDouble.get(getFloat());
                        case ENUM:
                        case TIMESTAMP_TZ:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case FLOAT:
                {
                    switch(getType()) {
                        case BOOLEAN:
                            return ValueFloat.get(getBoolean() ? 1 : 0);
                        case BYTE:
                        case SHORT:
                        case INT:
                            return ValueFloat.get(getInt());
                        case LONG:
                            return ValueFloat.get(getLong());
                        case DECIMAL:
                            return ValueFloat.get(getBigDecimal().floatValue());
                        case DOUBLE:
                            return ValueFloat.get((float) getDouble());
                        case ENUM:
                        case TIMESTAMP_TZ:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case DATE:
                {
                    switch(getType()) {
                        case TIME:
                            // this will be the result
                            return ValueDate.fromDateValue(DateTimeUtils.EPOCH_DATE_VALUE);
                        case TIMESTAMP:
                            return ValueDate.fromDateValue(((ValueTimestamp) this).getDateValue());
                        case TIMESTAMP_TZ:
                            {
                                ValueTimestampTimeZone ts = (ValueTimestampTimeZone) this;
                                long dateValue = ts.getDateValue(), timeNanos = ts.getTimeNanos();
                                long millis = DateTimeUtils.getMillis(dateValue, timeNanos, ts.getTimeZoneOffsetMins());
                                return ValueDate.fromMillis(millis);
                            }
                        case ENUM:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case TIME:
                {
                    switch(getType()) {
                        case DATE:
                            // has the time set to 0, the result will be 0
                            return ValueTime.fromNanos(0);
                        case TIMESTAMP:
                            return ValueTime.fromNanos(((ValueTimestamp) this).getTimeNanos());
                        case TIMESTAMP_TZ:
                            {
                                ValueTimestampTimeZone ts = (ValueTimestampTimeZone) this;
                                long dateValue = ts.getDateValue(), timeNanos = ts.getTimeNanos();
                                long millis = DateTimeUtils.getMillis(dateValue, timeNanos, ts.getTimeZoneOffsetMins());
                                return ValueTime.fromNanos(DateTimeUtils.nanosFromDate(millis) + timeNanos % 1_000_000);
                            }
                        case ENUM:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case TIMESTAMP:
                {
                    switch(getType()) {
                        case TIME:
                            return DateTimeUtils.normalizeTimestamp(0, ((ValueTime) this).getNanos());
                        case DATE:
                            return ValueTimestamp.fromDateValueAndNanos(((ValueDate) this).getDateValue(), 0);
                        case TIMESTAMP_TZ:
                            {
                                ValueTimestampTimeZone ts = (ValueTimestampTimeZone) this;
                                long dateValue = ts.getDateValue(), timeNanos = ts.getTimeNanos();
                                long millis = DateTimeUtils.getMillis(dateValue, timeNanos, ts.getTimeZoneOffsetMins());
                                return ValueTimestamp.fromMillisNanos(millis, (int) (timeNanos % 1_000_000));
                            }
                        case ENUM:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case TIMESTAMP_TZ:
                {
                    switch(getType()) {
                        case TIME:
                            {
                                ValueTimestamp ts = DateTimeUtils.normalizeTimestamp(0, ((ValueTime) this).getNanos());
                                return DateTimeUtils.timestampTimeZoneFromLocalDateValueAndNanos(ts.getDateValue(), ts.getTimeNanos());
                            }
                        case DATE:
                            return DateTimeUtils.timestampTimeZoneFromLocalDateValueAndNanos(((ValueDate) this).getDateValue(), 0);
                        case TIMESTAMP:
                            {
                                ValueTimestamp ts = (ValueTimestamp) this;
                                return DateTimeUtils.timestampTimeZoneFromLocalDateValueAndNanos(ts.getDateValue(), ts.getTimeNanos());
                            }
                        case ENUM:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case BYTES:
                {
                    switch(getType()) {
                        case JAVA_OBJECT:
                        case BLOB:
                            return ValueBytes.getNoCopy(getBytesNoCopy());
                        case UUID:
                        case GEOMETRY:
                            return ValueBytes.getNoCopy(getBytes());
                        case BYTE:
                            return ValueBytes.getNoCopy(new byte[] { getByte() });
                        case SHORT:
                            {
                                int x = getShort();
                                return ValueBytes.getNoCopy(new byte[] { (byte) (x >> 8), (byte) x });
                            }
                        case INT:
                            {
                                byte[] b = new byte[4];
                                Bits.writeInt(b, 0, getInt());
                                return ValueBytes.getNoCopy(b);
                            }
                        case LONG:
                            {
                                byte[] b = new byte[8];
                                Bits.writeLong(b, 0, getLong());
                                return ValueBytes.getNoCopy(b);
                            }
                        case ENUM:
                        case TIMESTAMP_TZ:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case JAVA_OBJECT:
                {
                    switch(getType()) {
                        case BYTES:
                        case BLOB:
                            return ValueJavaObject.getNoCopy(null, getBytesNoCopy(), getDataHandler());
                        case ENUM:
                        case TIMESTAMP_TZ:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case ENUM:
                {
                    switch(getType()) {
                        case BYTE:
                        case SHORT:
                        case INT:
                        case LONG:
                        case DECIMAL:
                            return ValueEnum.get(enumerators, getInt());
                        case STRING:
                        case STRING_IGNORECASE:
                        case STRING_FIXED:
                            return ValueEnum.get(enumerators, getString());
                        case JAVA_OBJECT:
                            Object object = JdbcUtils.deserialize(getBytesNoCopy(), getDataHandler());
                            if (object instanceof String) {
                                return ValueEnum.get(enumerators, (String) object);
                            } else if (object instanceof Integer) {
                                return ValueEnum.get(enumerators, (int) object);
                            }
                        // $FALL-THROUGH$
                        default:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                }
            case BLOB:
                {
                    switch(getType()) {
                        case BYTES:
                            return ValueLobDb.createSmallLob(Value.BLOB, getBytesNoCopy());
                        case TIMESTAMP_TZ:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case UUID:
                {
                    switch(getType()) {
                        case BYTES:
                            return ValueUuid.get(getBytesNoCopy());
                        case JAVA_OBJECT:
                            Object object = JdbcUtils.deserialize(getBytesNoCopy(), getDataHandler());
                            if (object instanceof java.util.UUID) {
                                return ValueUuid.get((java.util.UUID) object);
                            }
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                        case TIMESTAMP_TZ:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
            case GEOMETRY:
                {
                    switch(getType()) {
                        case BYTES:
                            return ValueGeometry.get(getBytesNoCopy());
                        case JAVA_OBJECT:
                            Object object = JdbcUtils.deserialize(getBytesNoCopy(), getDataHandler());
                            if (DataType.isGeometry(object)) {
                                return ValueGeometry.getFromGeometry(object);
                            }
                        // $FALL-THROUGH$
                        case TIMESTAMP_TZ:
                            throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
                    }
                    break;
                }
        }
        // conversion by parsing the string value
        String s = getString();
        switch(targetType) {
            case NULL:
                return ValueNull.INSTANCE;
            case BOOLEAN:
                {
                    if (s.equalsIgnoreCase("true") || s.equalsIgnoreCase("t") || s.equalsIgnoreCase("yes") || s.equalsIgnoreCase("y")) {
                        return ValueBoolean.TRUE;
                    } else if (s.equalsIgnoreCase("false") || s.equalsIgnoreCase("f") || s.equalsIgnoreCase("no") || s.equalsIgnoreCase("n")) {
                        return ValueBoolean.FALSE;
                    } else {
                        // convert to a number, and if it is not 0 then it is true
                        return ValueBoolean.get(new BigDecimal(s).signum() != 0);
                    }
                }
            case BYTE:
                return ValueByte.get(Byte.parseByte(s.trim()));
            case SHORT:
                return ValueShort.get(Short.parseShort(s.trim()));
            case INT:
                return ValueInt.get(Integer.parseInt(s.trim()));
            case LONG:
                return ValueLong.get(Long.parseLong(s.trim()));
            case DECIMAL:
                return ValueDecimal.get(new BigDecimal(s.trim()));
            case TIME:
                return ValueTime.parse(s.trim());
            case DATE:
                return ValueDate.parse(s.trim());
            case TIMESTAMP:
                return ValueTimestamp.parse(s.trim(), mode);
            case TIMESTAMP_TZ:
                return ValueTimestampTimeZone.parse(s.trim());
            case BYTES:
                return ValueBytes.getNoCopy(StringUtils.convertHexToBytes(s.trim()));
            case JAVA_OBJECT:
                return ValueJavaObject.getNoCopy(null, StringUtils.convertHexToBytes(s.trim()), getDataHandler());
            case STRING:
                return ValueString.get(s);
            case STRING_IGNORECASE:
                return ValueStringIgnoreCase.get(s);
            case STRING_FIXED:
                return ValueStringFixed.get(s, precision, mode);
            case DOUBLE:
                return ValueDouble.get(Double.parseDouble(s.trim()));
            case FLOAT:
                return ValueFloat.get(Float.parseFloat(s.trim()));
            case CLOB:
                return ValueLobDb.createSmallLob(CLOB, s.getBytes(StandardCharsets.UTF_8));
            case BLOB:
                return ValueLobDb.createSmallLob(BLOB, StringUtils.convertHexToBytes(s.trim()));
            case ARRAY:
                return ValueArray.get(new Value[] { ValueString.get(s) });
            case RESULT_SET:
                {
                    SimpleResultSet rs = new SimpleResultSet();
                    rs.setAutoClose(false);
                    rs.addColumn("X", Types.VARCHAR, s.length(), 0);
                    rs.addRow(s);
                    return ValueResultSet.get(rs);
                }
            case UUID:
                return ValueUuid.get(s);
            case GEOMETRY:
                return ValueGeometry.get(s);
            default:
                if (JdbcUtils.customDataTypesHandler != null) {
                    return JdbcUtils.customDataTypesHandler.convert(this, targetType);
                }
                throw DbException.throwInternalError("type=" + targetType);
        }
    } catch (NumberFormatException e) {
        throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, e, getString());
    }
}
Also used : SimpleResultSet(org.h2.tools.SimpleResultSet) BigDecimal(java.math.BigDecimal)

Example 7 with ValueTime

use of org.h2.value.ValueTime in project h2database by h2database.

the class DateTimeFunctions method extract.

/**
 * Extracts specified field from the specified date-time value.
 *
 * @param part
 *            the date part
 * @param value
 *            the date-time value
 * @return extracted field
 */
public static Value extract(String part, Value value) {
    Value result;
    int field = getDatePart(part);
    if (field != EPOCH) {
        result = ValueInt.get(getIntDatePart(value, field));
    } else {
        // Case where we retrieve the EPOCH time.
        // First we retrieve the dateValue and his time in nanoseconds.
        long[] a = DateTimeUtils.dateAndTimeFromValue(value);
        long dateValue = a[0];
        long timeNanos = a[1];
        // We compute the time in nanoseconds and the total number of days.
        BigDecimal timeNanosBigDecimal = new BigDecimal(timeNanos);
        BigDecimal numberOfDays = new BigDecimal(DateTimeUtils.absoluteDayFromDateValue(dateValue));
        BigDecimal nanosSeconds = new BigDecimal(1_000_000_000);
        BigDecimal secondsPerDay = new BigDecimal(DateTimeUtils.SECONDS_PER_DAY);
        // Case where the value is of type time e.g. '10:00:00'
        if (value instanceof ValueTime) {
            // In order to retrieve the EPOCH time we only have to convert the time
            // in nanoseconds (previously retrieved) in seconds.
            result = ValueDecimal.get(timeNanosBigDecimal.divide(nanosSeconds));
        } else if (value instanceof ValueDate) {
            // Case where the value is of type date '2000:01:01', we have to retrieve the
            // total number of days and multiply it by the number of seconds in a day.
            result = ValueDecimal.get(numberOfDays.multiply(secondsPerDay));
        } else if (value instanceof ValueTimestampTimeZone) {
            // Case where the value is a of type ValueTimestampTimeZone
            // ('2000:01:01 10:00:00+05').
            // We retrieve the time zone offset in minutes
            ValueTimestampTimeZone v = (ValueTimestampTimeZone) value;
            BigDecimal timeZoneOffsetSeconds = new BigDecimal(v.getTimeZoneOffsetMins() * 60);
            // Sum the time in nanoseconds and the total number of days in seconds
            // and adding the timeZone offset in seconds.
            result = ValueDecimal.get(timeNanosBigDecimal.divide(nanosSeconds).add(numberOfDays.multiply(secondsPerDay)).subtract(timeZoneOffsetSeconds));
        } else {
            // By default, we have the date and the time ('2000:01:01 10:00:00') if no type
            // is given.
            // We just have to sum the time in nanoseconds and the total number of days in
            // seconds.
            result = ValueDecimal.get(timeNanosBigDecimal.divide(nanosSeconds).add(numberOfDays.multiply(secondsPerDay)));
        }
    }
    return result;
}
Also used : ValueTime(org.h2.value.ValueTime) Value(org.h2.value.Value) ValueTimestampTimeZone(org.h2.value.ValueTimestampTimeZone) ValueDate(org.h2.value.ValueDate) BigDecimal(java.math.BigDecimal)

Example 8 with ValueTime

use of org.h2.value.ValueTime in project h2database by h2database.

the class DateTimeUtils method dateAndTimeFromValue.

/**
 * Extracts date value and nanos of day from the specified value.
 *
 * @param value
 *            value to extract fields from
 * @return array with date value and nanos of day
 */
public static long[] dateAndTimeFromValue(Value value) {
    long dateValue = EPOCH_DATE_VALUE;
    long timeNanos = 0;
    if (value instanceof ValueTimestamp) {
        ValueTimestamp v = (ValueTimestamp) value;
        dateValue = v.getDateValue();
        timeNanos = v.getTimeNanos();
    } else if (value instanceof ValueDate) {
        dateValue = ((ValueDate) value).getDateValue();
    } else if (value instanceof ValueTime) {
        timeNanos = ((ValueTime) value).getNanos();
    } else if (value instanceof ValueTimestampTimeZone) {
        ValueTimestampTimeZone v = (ValueTimestampTimeZone) value;
        dateValue = v.getDateValue();
        timeNanos = v.getTimeNanos();
    } else {
        ValueTimestamp v = (ValueTimestamp) value.convertTo(Value.TIMESTAMP);
        dateValue = v.getDateValue();
        timeNanos = v.getTimeNanos();
    }
    return new long[] { dateValue, timeNanos };
}
Also used : ValueTime(org.h2.value.ValueTime) ValueTimestamp(org.h2.value.ValueTimestamp) ValueTimestampTimeZone(org.h2.value.ValueTimestampTimeZone) ValueDate(org.h2.value.ValueDate)

Example 9 with ValueTime

use of org.h2.value.ValueTime in project h2database by h2database.

the class DateTimeUtils method convertTime.

/**
 * Convert the time to the specified time zone.
 *
 * @param value the time (might be ValueNull)
 * @param calendar the calendar
 * @return the time using the correct time zone
 */
public static Time convertTime(Value value, Calendar calendar) {
    if (value == ValueNull.INSTANCE) {
        return null;
    }
    ValueTime t = (ValueTime) value.convertTo(Value.TIME);
    Calendar cal = (Calendar) calendar.clone();
    cal.clear();
    cal.setLenient(true);
    long nanos = t.getNanos();
    long millis = nanos / 1_000_000;
    nanos -= millis * 1_000_000;
    long s = millis / 1_000;
    millis -= s * 1_000;
    long m = s / 60;
    s -= m * 60;
    long h = m / 60;
    m -= h * 60;
    return new Time(convertToMillis(cal, 1970, 1, 1, (int) h, (int) m, (int) s, (int) millis));
}
Also used : ValueTime(org.h2.value.ValueTime) GregorianCalendar(java.util.GregorianCalendar) Calendar(java.util.Calendar) Time(java.sql.Time) ValueTime(org.h2.value.ValueTime)

Example 10 with ValueTime

use of org.h2.value.ValueTime in project h2database by h2database.

the class ValueDataType method writeValue.

private void writeValue(WriteBuffer buff, Value v) {
    if (v == ValueNull.INSTANCE) {
        buff.put((byte) 0);
        return;
    }
    int type = v.getType();
    switch(type) {
        case Value.BOOLEAN:
            buff.put((byte) (v.getBoolean() ? BOOLEAN_TRUE : BOOLEAN_FALSE));
            break;
        case Value.BYTE:
            buff.put((byte) type).put(v.getByte());
            break;
        case Value.SHORT:
            buff.put((byte) type).putShort(v.getShort());
            break;
        case Value.ENUM:
        case Value.INT:
            {
                int x = v.getInt();
                if (x < 0) {
                    buff.put((byte) INT_NEG).putVarInt(-x);
                } else if (x < 16) {
                    buff.put((byte) (INT_0_15 + x));
                } else {
                    buff.put((byte) type).putVarInt(x);
                }
                break;
            }
        case Value.LONG:
            {
                long x = v.getLong();
                if (x < 0) {
                    buff.put((byte) LONG_NEG).putVarLong(-x);
                } else if (x < 8) {
                    buff.put((byte) (LONG_0_7 + x));
                } else {
                    buff.put((byte) type).putVarLong(x);
                }
                break;
            }
        case Value.DECIMAL:
            {
                BigDecimal x = v.getBigDecimal();
                if (BigDecimal.ZERO.equals(x)) {
                    buff.put((byte) DECIMAL_0_1);
                } else if (BigDecimal.ONE.equals(x)) {
                    buff.put((byte) (DECIMAL_0_1 + 1));
                } else {
                    int scale = x.scale();
                    BigInteger b = x.unscaledValue();
                    int bits = b.bitLength();
                    if (bits <= 63) {
                        if (scale == 0) {
                            buff.put((byte) DECIMAL_SMALL_0).putVarLong(b.longValue());
                        } else {
                            buff.put((byte) DECIMAL_SMALL).putVarInt(scale).putVarLong(b.longValue());
                        }
                    } else {
                        byte[] bytes = b.toByteArray();
                        buff.put((byte) type).putVarInt(scale).putVarInt(bytes.length).put(bytes);
                    }
                }
                break;
            }
        case Value.TIME:
            {
                ValueTime t = (ValueTime) v;
                long nanos = t.getNanos();
                long millis = nanos / 1000000;
                nanos -= millis * 1000000;
                buff.put((byte) type).putVarLong(millis).putVarLong(nanos);
                break;
            }
        case Value.DATE:
            {
                long x = ((ValueDate) v).getDateValue();
                buff.put((byte) type).putVarLong(x);
                break;
            }
        case Value.TIMESTAMP:
            {
                ValueTimestamp ts = (ValueTimestamp) v;
                long dateValue = ts.getDateValue();
                long nanos = ts.getTimeNanos();
                long millis = nanos / 1000000;
                nanos -= millis * 1000000;
                buff.put((byte) type).putVarLong(dateValue).putVarLong(millis).putVarLong(nanos);
                break;
            }
        case Value.TIMESTAMP_TZ:
            {
                ValueTimestampTimeZone ts = (ValueTimestampTimeZone) v;
                long dateValue = ts.getDateValue();
                long nanos = ts.getTimeNanos();
                long millis = nanos / 1000000;
                nanos -= millis * 1000000;
                buff.put((byte) type).putVarLong(dateValue).putVarLong(millis).putVarLong(nanos).putVarInt(ts.getTimeZoneOffsetMins());
                break;
            }
        case Value.JAVA_OBJECT:
            {
                byte[] b = v.getBytesNoCopy();
                buff.put((byte) type).putVarInt(b.length).put(b);
                break;
            }
        case Value.BYTES:
            {
                byte[] b = v.getBytesNoCopy();
                int len = b.length;
                if (len < 32) {
                    buff.put((byte) (BYTES_0_31 + len)).put(b);
                } else {
                    buff.put((byte) type).putVarInt(b.length).put(b);
                }
                break;
            }
        case Value.UUID:
            {
                ValueUuid uuid = (ValueUuid) v;
                buff.put((byte) type).putLong(uuid.getHigh()).putLong(uuid.getLow());
                break;
            }
        case Value.STRING:
            {
                String s = v.getString();
                int len = s.length();
                if (len < 32) {
                    buff.put((byte) (STRING_0_31 + len)).putStringData(s, len);
                } else {
                    buff.put((byte) type);
                    writeString(buff, s);
                }
                break;
            }
        case Value.STRING_IGNORECASE:
        case Value.STRING_FIXED:
            buff.put((byte) type);
            writeString(buff, v.getString());
            break;
        case Value.DOUBLE:
            {
                double x = v.getDouble();
                if (x == 1.0d) {
                    buff.put((byte) (DOUBLE_0_1 + 1));
                } else {
                    long d = Double.doubleToLongBits(x);
                    if (d == ValueDouble.ZERO_BITS) {
                        buff.put((byte) DOUBLE_0_1);
                    } else {
                        buff.put((byte) type).putVarLong(Long.reverse(d));
                    }
                }
                break;
            }
        case Value.FLOAT:
            {
                float x = v.getFloat();
                if (x == 1.0f) {
                    buff.put((byte) (FLOAT_0_1 + 1));
                } else {
                    int f = Float.floatToIntBits(x);
                    if (f == ValueFloat.ZERO_BITS) {
                        buff.put((byte) FLOAT_0_1);
                    } else {
                        buff.put((byte) type).putVarInt(Integer.reverse(f));
                    }
                }
                break;
            }
        case Value.BLOB:
        case Value.CLOB:
            {
                buff.put((byte) type);
                ValueLobDb lob = (ValueLobDb) v;
                byte[] small = lob.getSmall();
                if (small == null) {
                    buff.putVarInt(-3).putVarInt(lob.getTableId()).putVarLong(lob.getLobId()).putVarLong(lob.getPrecision());
                } else {
                    buff.putVarInt(small.length).put(small);
                }
                break;
            }
        case Value.ARRAY:
            {
                Value[] list = ((ValueArray) v).getList();
                buff.put((byte) type).putVarInt(list.length);
                for (Value x : list) {
                    writeValue(buff, x);
                }
                break;
            }
        case Value.RESULT_SET:
            {
                buff.put((byte) type);
                try {
                    ResultSet rs = ((ValueResultSet) v).getResultSet();
                    rs.beforeFirst();
                    ResultSetMetaData meta = rs.getMetaData();
                    int columnCount = meta.getColumnCount();
                    buff.putVarInt(columnCount);
                    for (int i = 0; i < columnCount; i++) {
                        writeString(buff, meta.getColumnName(i + 1));
                        buff.putVarInt(meta.getColumnType(i + 1)).putVarInt(meta.getPrecision(i + 1)).putVarInt(meta.getScale(i + 1));
                    }
                    while (rs.next()) {
                        buff.put((byte) 1);
                        for (int i = 0; i < columnCount; i++) {
                            int t = org.h2.value.DataType.getValueTypeFromResultSet(meta, i + 1);
                            Value val = org.h2.value.DataType.readValue(null, rs, i + 1, t);
                            writeValue(buff, val);
                        }
                    }
                    buff.put((byte) 0);
                    rs.beforeFirst();
                } catch (SQLException e) {
                    throw DbException.convert(e);
                }
                break;
            }
        case Value.GEOMETRY:
            {
                byte[] b = v.getBytes();
                int len = b.length;
                buff.put((byte) type).putVarInt(len).put(b);
                break;
            }
        default:
            if (JdbcUtils.customDataTypesHandler != null) {
                byte[] b = v.getBytesNoCopy();
                buff.put((byte) CUSTOM_DATA_TYPE).putVarInt(type).putVarInt(b.length).put(b);
                break;
            }
            DbException.throwInternalError("type=" + v.getType());
    }
}
Also used : ValueUuid(org.h2.value.ValueUuid) ValueLobDb(org.h2.value.ValueLobDb) SQLException(java.sql.SQLException) ValueTimestampTimeZone(org.h2.value.ValueTimestampTimeZone) ValueString(org.h2.value.ValueString) BigDecimal(java.math.BigDecimal) ValueTime(org.h2.value.ValueTime) ResultSetMetaData(java.sql.ResultSetMetaData) ValueTimestamp(org.h2.value.ValueTimestamp) Value(org.h2.value.Value) SimpleResultSet(org.h2.tools.SimpleResultSet) ResultSet(java.sql.ResultSet) ValueResultSet(org.h2.value.ValueResultSet) BigInteger(java.math.BigInteger)

Aggregations

ValueTime (org.h2.value.ValueTime)10 ValueTimestamp (org.h2.value.ValueTimestamp)7 ValueDate (org.h2.value.ValueDate)6 ValueTimestampTimeZone (org.h2.value.ValueTimestampTimeZone)5 BigDecimal (java.math.BigDecimal)4 Value (org.h2.value.Value)4 SimpleResultSet (org.h2.tools.SimpleResultSet)3 BigInteger (java.math.BigInteger)2 ResultSet (java.sql.ResultSet)2 ResultSetMetaData (java.sql.ResultSetMetaData)2 SQLException (java.sql.SQLException)2 ValueLobDb (org.h2.value.ValueLobDb)2 ValueResultSet (org.h2.value.ValueResultSet)2 ValueString (org.h2.value.ValueString)2 ValueUuid (org.h2.value.ValueUuid)2 Time (java.sql.Time)1 Timestamp (java.sql.Timestamp)1 Calendar (java.util.Calendar)1 GregorianCalendar (java.util.GregorianCalendar)1 JdbcResultSet (org.h2.jdbc.JdbcResultSet)1