/* This file is part of VoltDB. * Copyright (C) 2008-2017 VoltDB Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ package org.voltdb; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; import org.voltdb.types.TimestampType; import junit.framework.TestCase; public class TestVoltType extends TestCase { public void testGet() { boolean caught = false; try { VoltType.get(Byte.MAX_VALUE); } catch (AssertionError ex) { caught = true; } assertTrue(caught); VoltType vt = VoltType.get((byte)3); assertTrue(vt.getValue() == VoltType.TINYINT.getValue()); } public void testTypeFromString() { assertEquals(VoltType.TINYINT, VoltType.typeFromString("TINYINT")); assertEquals(VoltType.SMALLINT, VoltType.typeFromString("SMALLINT")); assertEquals(VoltType.INTEGER, VoltType.typeFromString("INTEGER")); assertEquals(VoltType.BIGINT, VoltType.typeFromString("BIGINT")); assertEquals(VoltType.FLOAT, VoltType.typeFromString("FLOAT")); assertEquals(VoltType.FLOAT, VoltType.typeFromString("DOUBLE")); // also floats assertEquals(VoltType.TIMESTAMP, VoltType.typeFromString("TIMESTAMP")); assertEquals(VoltType.STRING, VoltType.typeFromString("STRING")); assertEquals(VoltType.VOLTTABLE, VoltType.typeFromString("VOLTTABLE")); assertEquals(VoltType.STRING, VoltType.typeFromString("VARCHAR")); // Need to be able to turn CHARACTER SqlStmt parameters into varchars. assertEquals(VoltType.STRING, VoltType.typeFromString("CHARACTER")); assertEquals(VoltType.TIMESTAMP, VoltType.typeFromString("TIMESTAMP")); assertEquals(VoltType.DECIMAL, VoltType.typeFromString("DECIMAL")); assertEquals(VoltType.VARBINARY, VoltType.typeFromString("VARBINARY")); // test with classname prefix assertEquals(VoltType.VARBINARY, VoltType.typeFromString("VoltType.VARBINARY")); assertEquals(VoltType.STRING, VoltType.typeFromString("VoltType.STRING")); assertEquals(VoltType.STRING, VoltType.typeFromString("VoltType.VARCHAR")); assertEquals(VoltType.FLOAT, VoltType.typeFromString("VoltType.DOUBLE")); boolean caught = false; try { VoltType.typeFromString("Muhahaha"); } catch (RuntimeException ex) { caught = true; } assertTrue(caught); } public void testGetLengthInBytesForFixedTypes() { assertEquals(1, VoltType.TINYINT.getLengthInBytesForFixedTypes()); assertEquals(2, VoltType.SMALLINT.getLengthInBytesForFixedTypes()); assertEquals(4, VoltType.INTEGER.getLengthInBytesForFixedTypes()); assertEquals(8, VoltType.BIGINT.getLengthInBytesForFixedTypes()); assertEquals(8, VoltType.FLOAT.getLengthInBytesForFixedTypes()); assertEquals(8, VoltType.TIMESTAMP.getLengthInBytesForFixedTypes()); assertEquals(16, VoltType.DECIMAL.getLengthInBytesForFixedTypes()); boolean caught = false; try { VoltType.STRING.getLengthInBytesForFixedTypes(); } catch (RuntimeException ex) { caught = true; } assertTrue(caught); } public void testToSQLString() { assertEquals("tinyint", VoltType.TINYINT.toSQLString()); assertEquals("smallint", VoltType.SMALLINT.toSQLString()); assertEquals("integer", VoltType.INTEGER.toSQLString()); assertEquals("bigint", VoltType.BIGINT.toSQLString()); assertEquals("float", VoltType.FLOAT.toSQLString()); assertEquals("timestamp", VoltType.TIMESTAMP.toSQLString()); assertEquals("decimal", VoltType.DECIMAL.toSQLString()); assertEquals("varchar", VoltType.STRING.toSQLString()); assertEquals("varbinary", VoltType.VARBINARY.toSQLString()); assertNull(VoltType.VOLTTABLE.toSQLString()); } public void testTypeFromObject() { VoltType vt; vt = VoltType.typeFromObject(new Byte((byte) 0)); assertTrue(vt.getValue() == VoltType.TINYINT.getValue()); vt = VoltType.typeFromObject(new Short((short) 0)); assertTrue(vt.getValue() == VoltType.SMALLINT.getValue()); boolean caught = false; try { VoltType.typeFromClass(Class.class); } catch (RuntimeException ex) { caught = true; } assertTrue(caught); } public void testEquivalences() { assertEquals(VoltType.typeFromString("TINYINT"), VoltType.typeFromClass(Byte.class)); assertEquals(VoltType.typeFromString("SMALLINT"), VoltType.typeFromClass(Short.class)); assertEquals(VoltType.typeFromString("INTEGER"), VoltType.typeFromClass(Integer.class)); assertEquals(VoltType.typeFromString("BIGINT"), VoltType.typeFromClass(Long.class)); assertEquals(VoltType.typeFromString("FLOAT"), VoltType.typeFromClass(Float.class)); assertEquals(VoltType.typeFromString("DOUBLE"), VoltType.typeFromClass(Double.class)); assertEquals(VoltType.typeFromString("TIMESTAMP"), VoltType.typeFromClass(TimestampType.class)); assertEquals(VoltType.typeFromString("STRING"), VoltType.typeFromClass(String.class)); assertEquals(VoltType.typeFromString("CHARACTER"), VoltType.typeFromClass(String.class)); assertEquals(VoltType.typeFromString("VOLTTABLE"), VoltType.typeFromClass(VoltTable.class)); assertEquals(VoltType.typeFromString("DECIMAL"), VoltType.typeFromClass(BigDecimal.class)); assertEquals(VoltType.typeFromString("VARBINARY"), VoltType.typeFromClass(byte[].class)); } /* round trip the constructors */ public void testTimestampCreation() { long usec = 999999999; TimestampType ts1 = new TimestampType(usec); assertEquals(usec, ts1.getTime()); String ts1string = ts1.toString(); TimestampType ts1prime = new TimestampType(ts1string); assertEquals(usec, ts1prime.getTime()); usec = 999999000; ts1 = new TimestampType(usec); assertEquals(usec, ts1.getTime()); // the 0 at the start of microseconds is important // for round-trip string/string correctness test String date = "2011-06-24 10:30:26.123012"; TimestampType ts3 = new TimestampType(date); assertEquals(date, ts3.toString()); boolean caught = false; caught = false; try { // Date string inputs interpreted as Dates should not have sub-millisecond granularity. // This is the utility function that does this validation. TimestampType.millisFromJDBCformat(date); } catch (IllegalArgumentException ex) { caught = true; } assertTrue(caught); caught = false; try { // Date string inputs interpreted as TimestampType should not have sub-microsecond granularity. String nanoNoNos = "2011-06-24 10:30:26.123012001"; new TimestampType(nanoNoNos); } catch (IllegalArgumentException ex) { caught = true; } assertTrue(caught); // Test timestamp before epoch usec = -923299922232L; ts1 = new TimestampType(usec); assertEquals(usec, ts1.getTime()); ts1string = ts1.toString(); ts1prime = new TimestampType(ts1string); assertEquals(usec, ts1prime.getTime()); date = "1966-06-24 10:30:26.123012"; ts3 = new TimestampType(date); assertEquals(date, ts3.toString()); } /* Compare some values that differ by microseconds and by full millis */ public void testTimestampEquality() { TimestampType ts1 = new TimestampType(150000); TimestampType ts2 = new TimestampType(150000); TimestampType ts3 = new TimestampType(150001); TimestampType ts4 = new TimestampType(160000); assertTrue(ts1.equals(ts2)); assertTrue(ts2.equals(ts1)); assertFalse(ts1.equals(ts3)); assertFalse(ts3.equals(ts1)); assertFalse(ts1.equals(ts4)); assertFalse(ts4.equals(ts1)); assertTrue(ts1.compareTo(ts2) == 0); assertTrue(ts2.compareTo(ts1) == 0); assertTrue(ts1.compareTo(ts3) < 0); assertTrue(ts3.compareTo(ts1) > 0); assertTrue(ts1.compareTo(ts4) < 0); assertTrue(ts4.compareTo(ts1) > 0); String micro = "2011-06-24 10:30:26.123012"; String milli = "2011-06-24 10:30:26.123"; TimestampType microTs = new TimestampType(micro); TimestampType milliTs = new TimestampType(milli); Date fromString = new Date(TimestampType.millisFromJDBCformat(milli.toString())); Date fromMillis = new Date(milliTs.getTime()/1000); assertEquals(fromString, fromMillis); java.sql.Date sqlFromString = new java.sql.Date(TimestampType.millisFromJDBCformat(milliTs.toString())); java.sql.Date sqlFromMillis = new java.sql.Date(milliTs.getTime()/1000); assertEquals(sqlFromString, sqlFromMillis); boolean caught = false; caught = false; try { // Date string inputs converted from TimestampType should not have sub-millisecond granularity. new Date(TimestampType.millisFromJDBCformat(microTs.toString())); } catch (IllegalArgumentException ex) { caught = true; } assertTrue(caught); caught = false; try { // Date string inputs converted from TimestampType should not have sub-millisecond granularity. new java.sql.Date(TimestampType.millisFromJDBCformat(microTs.toString())); } catch (IllegalArgumentException ex) { caught = true; } assertTrue(caught); } public void testTimestampToString() { // I suppose these could fall across minute boundaries and fail the // test.. but that would seem exceedingly unlikely? Do this a few times // to try to avoid the false negative. for (int ii=0; ii < 5; ++ii) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); TimestampType now = new TimestampType(); Date date = new Date(); if (now.toString().startsWith(sdf.format(date))) { assertTrue(now.toString().startsWith(sdf.format(date))); return; } } fail(); } public void testTimestampToStringBeforeEpoch() { long micros = -48932323284323L; TimeZone tz = TimeZone.getTimeZone("America/New_York"); TimestampType beforeEpoch = new TimestampType(micros); String answer = beforeEpoch.toString(tz); assertEquals("1968-06-13 11:41:16.715677", answer); assertEquals(micros, beforeEpoch.getTime()); // test Long.MIN as NULL_TimestampType // NULL_TimestampType is translated to VoltType.NULL_BIGINT in // @see org.voltdb.ParameterSet#flattenToBuffer() beforeEpoch = new TimestampType(VoltType.NULL_BIGINT); answer = beforeEpoch.toString(tz); assertEquals("290303-12-10 14:59:05.224192", answer); assertEquals(VoltType.NULL_BIGINT, beforeEpoch.getTime()); } public void testTimestampStringRoundTrip() { String[] date_str = {"1900-01-01", "2000-02-03", "2100-04-05", "2012-12-31", "2001-10-25", }; for (int ii=0; ii<date_str.length; ++ii) { try{ String str = new TimestampType(date_str[ii]).toString(); assertEquals(date_str[ii]+" 00:00:00.000000", str); } catch (Exception e){ e.printStackTrace(); fail(); } } } }