/* * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, * Version 1.0, and under the Eclipse Public License, Version 1.0 * (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.test.unit; import java.math.BigDecimal; import java.sql.Connection; import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; import java.sql.Types; import java.util.UUID; import org.h2.constant.ErrorCode; import org.h2.test.TestBase; import org.h2.test.utils.AssertThrows; import org.h2.tools.SimpleResultSet; import org.h2.value.DataType; import org.h2.value.Value; import org.h2.value.ValueArray; import org.h2.value.ValueBytes; import org.h2.value.ValueDecimal; import org.h2.value.ValueDouble; import org.h2.value.ValueFloat; import org.h2.value.ValueLobDb; import org.h2.value.ValueResultSet; import org.h2.value.ValueString; import org.h2.value.ValueUuid; /** * Tests features of values. */ public class TestValue extends TestBase { /** * Run just this test. * * @param a ignored */ public static void main(String... a) throws Exception { TestBase.createCaller().init().test(); } public void test() throws SQLException { testCastTrim(); testValueResultSet(); testDataType(); testUUID(); testDouble(false); testDouble(true); testModulusDouble(); testModulusDecimal(); testModulusOperator(); } private void testCastTrim() { Value v; String spaces = new String(new char[100]).replace((char) 0, ' '); v = ValueArray.get(new Value[]{ValueString.get("hello"), ValueString.get("world")}); assertEquals(10, v.getPrecision()); assertEquals(5, v.convertPrecision(5, true).getPrecision()); v = ValueArray.get(new Value[]{ValueString.get(""), ValueString.get("")}); assertEquals(0, v.getPrecision()); assertEquals("('')", v.convertPrecision(1, true).toString()); v = ValueBytes.get(spaces.getBytes()); assertEquals(100, v.getPrecision()); assertEquals(10, v.convertPrecision(10, false).getPrecision()); assertEquals(10, v.convertPrecision(10, false).getBytes().length); assertEquals(32, v.convertPrecision(10, false).getBytes()[9]); assertEquals(10, v.convertPrecision(10, true).getPrecision()); final Value vd = ValueDecimal.get(new BigDecimal("1234567890.123456789")); assertEquals(19, vd.getPrecision()); assertEquals("1234567890.1234567", vd.convertPrecision(10, true).getString()); new AssertThrows(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1) { public void test() { vd.convertPrecision(10, false); }}; v = ValueLobDb.createSmallLob(Value.CLOB, spaces.getBytes(), 100); assertEquals(100, v.getPrecision()); assertEquals(10, v.convertPrecision(10, false).getPrecision()); assertEquals(10, v.convertPrecision(10, false).getString().length()); assertEquals(" ", v.convertPrecision(10, false).getString()); assertEquals(10, v.convertPrecision(10, true).getPrecision()); v = ValueLobDb.createSmallLob(Value.BLOB, spaces.getBytes(), 100); assertEquals(100, v.getPrecision()); assertEquals(10, v.convertPrecision(10, false).getPrecision()); assertEquals(10, v.convertPrecision(10, false).getBytes().length); assertEquals(32, v.convertPrecision(10, false).getBytes()[9]); assertEquals(10, v.convertPrecision(10, true).getPrecision()); ResultSet rs = new SimpleResultSet(); v = ValueResultSet.get(rs); assertEquals(Integer.MAX_VALUE, v.getPrecision()); assertEquals(Integer.MAX_VALUE, v.convertPrecision(10, false).getPrecision()); assertTrue(rs == v.convertPrecision(10, false).getObject()); assertFalse(rs == v.convertPrecision(10, true).getObject()); assertEquals(Integer.MAX_VALUE, v.convertPrecision(10, true).getPrecision()); v = ValueString.get(spaces); assertEquals(100, v.getPrecision()); assertEquals(10, v.convertPrecision(10, false).getPrecision()); assertEquals(" ", v.convertPrecision(10, false).getString()); assertEquals(" ", v.convertPrecision(10, true).getString()); } private void testValueResultSet() throws SQLException { SimpleResultSet rs = new SimpleResultSet(); rs.addColumn("ID", Types.INTEGER, 0, 0); rs.addColumn("NAME", Types.VARCHAR, 255, 0); rs.addRow(1, "Hello"); rs.addRow(2, "World"); rs.addRow(3, "Peace"); ValueResultSet v; v = ValueResultSet.get(rs); assertTrue(rs == v.getObject()); v = ValueResultSet.getCopy(rs, 2); assertEquals(0, v.hashCode()); assertEquals(Integer.MAX_VALUE, v.getDisplaySize()); assertEquals(Integer.MAX_VALUE, v.getPrecision()); assertEquals(0, v.getScale()); assertEquals("", v.getSQL()); assertEquals(Value.RESULT_SET, v.getType()); assertEquals("((1, Hello), (2, World))", v.getString()); rs.beforeFirst(); ValueResultSet v2 = ValueResultSet.getCopy(rs, 2); assertTrue(v.equals(v)); assertFalse(v.equals(v2)); rs.beforeFirst(); ResultSet rs2 = v.getResultSet(); rs2.next(); rs.next(); assertEquals(rs.getInt(1), rs2.getInt(1)); assertEquals(rs.getString(2), rs2.getString(2)); rs2.next(); rs.next(); assertEquals(rs.getInt(1), rs2.getInt(1)); assertEquals(rs.getString(2), rs2.getString(2)); assertFalse(rs2.next()); assertTrue(rs.next()); } private void testDataType() { testDataType(Value.NULL, null); testDataType(Value.NULL, Void.class); testDataType(Value.NULL, void.class); testDataType(Value.ARRAY, String[].class); testDataType(Value.STRING, String.class); testDataType(Value.INT, Integer.class); testDataType(Value.LONG, Long.class); testDataType(Value.BOOLEAN, Boolean.class); testDataType(Value.DOUBLE, Double.class); testDataType(Value.BYTE, Byte.class); testDataType(Value.SHORT, Short.class); testDataType(Value.FLOAT, Float.class); testDataType(Value.BYTES, byte[].class); testDataType(Value.UUID, UUID.class); testDataType(Value.NULL, Void.class); testDataType(Value.DECIMAL, BigDecimal.class); testDataType(Value.RESULT_SET, ResultSet.class); testDataType(Value.BLOB, Value.ValueBlob.class); testDataType(Value.CLOB, Value.ValueClob.class); testDataType(Value.DATE, Date.class); testDataType(Value.TIME, Time.class); testDataType(Value.TIMESTAMP, Timestamp.class); testDataType(Value.TIMESTAMP, java.util.Date.class); testDataType(Value.CLOB, java.io.Reader.class); testDataType(Value.CLOB, java.sql.Clob.class); testDataType(Value.BLOB, java.io.InputStream.class); testDataType(Value.BLOB, java.sql.Blob.class); testDataType(Value.ARRAY, Object[].class); testDataType(Value.JAVA_OBJECT, StringBuffer.class); } private void testDataType(int type, Class<?> clazz) { assertEquals(type, DataType.getTypeFromClass(clazz)); } private void testDouble(boolean useFloat) { double[] d = { Double.NEGATIVE_INFINITY, -1, 0, 1, Double.POSITIVE_INFINITY, Double.NaN }; Value[] values = new Value[d.length]; for (int i = 0; i < d.length; i++) { Value v = useFloat ? (Value) ValueFloat.get((float) d[i]) : (Value) ValueDouble.get(d[i]); values[i] = v; assertTrue(values[i].compareTypeSave(values[i], null) == 0); assertTrue(v.equals(v)); assertEquals(i < 2 ? -1 : i > 2 ? 1 : 0, v.getSignum()); } for (int i = 0; i < d.length - 1; i++) { assertTrue(values[i].compareTypeSave(values[i+1], null) < 0); assertTrue(values[i + 1].compareTypeSave(values[i], null) > 0); assertTrue(!values[i].equals(values[i+1])); } } private void testUUID() { long maxHigh = 0, maxLow = 0, minHigh = -1L, minLow = -1L; for (int i = 0; i < 100; i++) { ValueUuid uuid = ValueUuid.getNewRandom(); maxHigh |= uuid.getHigh(); maxLow |= uuid.getLow(); minHigh &= uuid.getHigh(); minLow &= uuid.getLow(); } ValueUuid max = ValueUuid.get(maxHigh, maxLow); assertEquals("ffffffff-ffff-4fff-bfff-ffffffffffff", max.getString()); ValueUuid min = ValueUuid.get(minHigh, minLow); assertEquals("00000000-0000-4000-8000-000000000000", min.getString()); } private void testModulusDouble() { final ValueDouble vd1 = ValueDouble.get(12); new AssertThrows(ErrorCode.DIVISION_BY_ZERO_1) { public void test() { vd1.modulus(ValueDouble.get(0)); }}; ValueDouble vd2 = ValueDouble.get(10); ValueDouble vd3 = vd1.modulus(vd2); assertEquals(2, vd3.getDouble()); } private void testModulusDecimal() { final ValueDecimal vd1 = ValueDecimal.get(new BigDecimal(12)); new AssertThrows(ErrorCode.DIVISION_BY_ZERO_1) { public void test() { vd1.modulus(ValueDecimal.get(new BigDecimal(0))); }}; ValueDecimal vd2 = ValueDecimal.get(new BigDecimal(10)); ValueDecimal vd3 = vd1.modulus(vd2); assertEquals(2, vd3.getDouble()); } private void testModulusOperator() throws SQLException { Connection conn = getConnection("modulus"); try { ResultSet rs = conn.createStatement().executeQuery("CALL 12 % 10"); rs.next(); assertEquals(2, rs.getInt(1)); } finally { conn.close(); deleteDb("modulus"); } } }