From 4971c69cc7cc9c47de2210f7085872f186dc56b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=98=95=EC=A4=80?= Date: Mon, 26 May 2014 11:21:37 +0900 Subject: [PATCH 1/3] TAJO-844: JDBC should be support getTime, getDate, getTimestamp --- .../apache/tajo/jdbc/TajoResultSetBase.java | 209 +++++++++++------- .../tajo/util/datetime/DateTimeUtil.java | 4 + .../org/apache/tajo/jdbc/TestResultSet.java | 92 +++++++- 3 files changed, 225 insertions(+), 80 deletions(-) diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java index 60eb2f1c20..1a3da25e00 100644 --- a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java +++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetBase.java @@ -21,11 +21,10 @@ import org.apache.tajo.catalog.Schema; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.conf.TajoConf; -import org.apache.tajo.datum.Datum; -import org.apache.tajo.datum.NullDatum; -import org.apache.tajo.datum.TimeDatum; -import org.apache.tajo.datum.TimestampDatum; +import org.apache.tajo.datum.*; import org.apache.tajo.storage.Tuple; +import org.apache.tajo.util.datetime.DateTimeUtil; +import org.apache.tajo.util.datetime.TimeMeta; import java.io.IOException; import java.io.InputStream; @@ -35,6 +34,7 @@ import java.sql.*; import java.util.Calendar; import java.util.Map; +import java.util.TimeZone; public abstract class TajoResultSetBase implements ResultSet { protected int curRow; @@ -176,16 +176,18 @@ public Object getObject(int fieldId) throws SQLException { case INT8: return d.asInt8(); case TEXT: case CHAR: - case DATE: case VARCHAR: return d.asChars(); case FLOAT4: return d.asFloat4(); case FLOAT8: return d.asFloat8(); case NUMERIC: return d.asFloat8(); + case DATE: { + return getDate((DateDatum)d, TajoConf.getCurrentTimeZone()); + } case TIME: { - return ((TimeDatum)d).asChars(TajoConf.getCurrentTimeZone(), false); + return getTime((TimeDatum)d, TajoConf.getCurrentTimeZone()); } case TIMESTAMP: { - return ((TimestampDatum)d).asChars(TajoConf.getCurrentTimeZone(), false); + return getTimestamp((TimestampDatum) d, TajoConf.getCurrentTimeZone()); } default: return d.asChars(); } @@ -193,7 +195,7 @@ public Object getObject(int fieldId) throws SQLException { @Override public Object getObject(String name) throws SQLException { - return getObject(findColumn(name)); + return getObject(findColumn(name) + 1); } @Override @@ -236,6 +238,127 @@ public String getString(String name) throws SQLException { } } + @Override + public Date getDate(int fieldId) throws SQLException { + Datum datum = cur.get(fieldId - 1); + handleNull(datum); + if (wasNull) { + return null; + } + + return getDate((DateDatum)datum, TajoConf.getCurrentTimeZone()); + } + + @Override + public Date getDate(String name) throws SQLException { + return getDate(findColumn(name) + 1); + } + + @Override + public Date getDate(int fieldId, Calendar x) throws SQLException { + Datum datum = cur.get(fieldId - 1); + handleNull(datum); + if (wasNull) { + return null; + } + + return getDate((DateDatum)datum, x.getTimeZone()); + } + + @Override + public Date getDate(String name, Calendar x) throws SQLException { + return getDate(findColumn(name) + 1, x); + } + + private Date getDate(DateDatum datum, TimeZone tz) { + TimeMeta tm = datum.toTimeMeta(); + if (tz != null) { + DateTimeUtil.toUserTimezone(tm, tz); + } + return new Date(DateTimeUtil.julianTimeToJavaTime(DateTimeUtil.toJulianTimestamp(tm))); + } + + @Override + public Time getTime(int fieldId) throws SQLException { + Datum datum = cur.get(fieldId - 1); + handleNull(datum); + if (wasNull) { + return null; + } + + return getTime((TimeDatum)datum, TajoConf.getCurrentTimeZone()); + + } + + @Override + public Time getTime(String name) throws SQLException { + return getTime(findColumn(name) + 1); + } + + @Override + public Time getTime(int fieldId, Calendar x) throws SQLException { + Datum datum = cur.get(fieldId - 1); + handleNull(datum); + if (wasNull) { + return null; + } + + return getTime((TimeDatum)datum, x.getTimeZone()); + } + + @Override + public Time getTime(String name, Calendar x) throws SQLException { + return getTime(findColumn(name) + 1, x); + } + + private Time getTime(TimeDatum datum, TimeZone tz) { + TimeMeta tm = datum.toTimeMeta(); + if (tz != null) { + DateTimeUtil.toUserTimezone(tm, tz); + } + return new Time(DateTimeUtil.toJavaTime(tm.hours, tm.minutes, tm.secs, tm.fsecs)); + } + + @Override + public Timestamp getTimestamp(int fieldId) throws SQLException { + Datum datum = cur.get(fieldId - 1); + handleNull(datum); + if (wasNull) { + return null; + } + + return getTimestamp((TimestampDatum)datum, TajoConf.getCurrentTimeZone()); + } + + @Override + public Timestamp getTimestamp(String name) throws SQLException { + return getTimestamp(findColumn(name) + 1); + } + + @Override + public Timestamp getTimestamp(int fieldId, Calendar x) throws SQLException { + Datum datum = cur.get(fieldId - 1); + handleNull(datum); + if (wasNull) { + return null; + } + + return getTimestamp((TimestampDatum)datum, x.getTimeZone()); + } + + @Override + public Timestamp getTimestamp(String name, Calendar x) throws SQLException { + return getTimestamp(findColumn(name) + 1, x); + } + + private Timestamp getTimestamp(TimestampDatum datum, TimeZone tz) { + TimeMeta tm = datum.toTimeMeta(); + if (tz != null) { + DateTimeUtil.toUserTimezone(tm, tz); + } + return new Timestamp(DateTimeUtil.julianTimeToJavaTime(DateTimeUtil.toJulianTimestamp(tm))); + } + @Override public boolean isWrapperFor(Class clazz) throws SQLException { throw new SQLFeatureNotSupportedException("isWrapperFor not supported"); @@ -373,36 +496,6 @@ public String getCursorName() throws SQLException { throw new SQLFeatureNotSupportedException("getCursorName not supported"); } - @Override - public Date getDate(int index) throws SQLException { - Object obj = getObject(index); - if (obj == null) { - return null; - } - - try { - return Date.valueOf((String) obj); - } catch (Exception e) { - throw new SQLException("Cannot convert column " + index - + " to date: " + e.toString()); - } - } - - @Override - public Date getDate(String name) throws SQLException { - return getDate(findColumn(name)); - } - - @Override - public Date getDate(int index, Calendar x) throws SQLException { - throw new SQLFeatureNotSupportedException("getDate not supported"); - } - - @Override - public Date getDate(String name, Calendar x) throws SQLException { - throw new SQLFeatureNotSupportedException("getDate not supported"); - } - @Override public int getFetchDirection() throws SQLException { return ResultSet.FETCH_FORWARD; @@ -517,46 +610,6 @@ public Statement getStatement() throws SQLException { throw new SQLFeatureNotSupportedException("getHistoryStatement not supported"); } - @Override - public Time getTime(int index) throws SQLException { - throw new SQLFeatureNotSupportedException("getTime not supported"); - } - - @Override - public Time getTime(String name) throws SQLException { - throw new SQLFeatureNotSupportedException("getTime not supported"); - } - - @Override - public Time getTime(int index, Calendar x) throws SQLException { - throw new SQLFeatureNotSupportedException("getTime not supported"); - } - - @Override - public Time getTime(String name, Calendar x) throws SQLException { - throw new SQLFeatureNotSupportedException("getTime not supported"); - } - - @Override - public Timestamp getTimestamp(int index) throws SQLException { - throw new SQLFeatureNotSupportedException("getTimestamp not supported"); - } - - @Override - public Timestamp getTimestamp(String name) throws SQLException { - throw new SQLFeatureNotSupportedException("getTimestamp not supported"); - } - - @Override - public Timestamp getTimestamp(int index, Calendar x) throws SQLException { - throw new SQLFeatureNotSupportedException("getTimestamp not supported"); - } - - @Override - public Timestamp getTimestamp(String name, Calendar x) throws SQLException { - throw new SQLFeatureNotSupportedException("getTimestamp not supported"); - } - @Override public int getType() throws SQLException { return ResultSet.TYPE_FORWARD_ONLY; diff --git a/tajo-common/src/main/java/org/apache/tajo/util/datetime/DateTimeUtil.java b/tajo-common/src/main/java/org/apache/tajo/util/datetime/DateTimeUtil.java index 187e25d7ca..327b4237e2 100644 --- a/tajo-common/src/main/java/org/apache/tajo/util/datetime/DateTimeUtil.java +++ b/tajo-common/src/main/java/org/apache/tajo/util/datetime/DateTimeUtil.java @@ -346,6 +346,10 @@ public static long toTime(int hour, int min, int sec, int fsec) { DateTimeConstants.USECS_PER_SEC) + fsec; } + public static long toJavaTime(int hour, int min, int sec, int fsec) { + return toTime(hour, min, sec, fsec)/DateTimeConstants.MSECS_PER_SEC; + } + /** * Calculate julian timestamp. * @param years diff --git a/tajo-core/src/test/java/org/apache/tajo/jdbc/TestResultSet.java b/tajo-core/src/test/java/org/apache/tajo/jdbc/TestResultSet.java index 4477fa5312..fdbca61ea9 100644 --- a/tajo-core/src/test/java/org/apache/tajo/jdbc/TestResultSet.java +++ b/tajo-core/src/test/java/org/apache/tajo/jdbc/TestResultSet.java @@ -36,14 +36,16 @@ import org.apache.tajo.conf.TajoConf; import org.apache.tajo.datum.DatumFactory; import org.apache.tajo.storage.*; +import org.apache.tajo.util.KeyValueSet; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; import java.io.IOException; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; +import java.sql.*; +import java.util.Calendar; +import java.util.TimeZone; import static org.junit.Assert.*; @@ -124,4 +126,90 @@ public void test() throws IOException, SQLException { assertEquals(10000, i); assertTrue(rs.isAfterLast()); } + + @Test + public void testDateTimeType() throws Exception { + TimeZone tajoCurrentTimeZone = TajoConf.getCurrentTimeZone(); + TajoConf.setCurrentTimeZone(TimeZone.getTimeZone("UTC")); + + TimeZone systemCurrentTimeZone = TimeZone.getDefault(); + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + + ResultSet res = null; + try { + String tableName = "datetimetable"; + String query = "select col1, col2, col3 from " + tableName; + + String [] table = new String[] {tableName}; + Schema schema = new Schema(); + schema.addColumn("col1", Type.DATE); + schema.addColumn("col2", Type.TIME); + schema.addColumn("col3", Type.TIMESTAMP); + Schema [] schemas = new Schema[] {schema}; + String [] data = { + "2014-01-01|01:00:00|2014-01-01 01:00:00" + }; + KeyValueSet tableOptions = new KeyValueSet(); + tableOptions.put(StorageConstants.CSVFILE_DELIMITER, StorageConstants.DEFAULT_FIELD_DELIMITER); + + res = TajoTestingCluster + .run(table, schemas, tableOptions, new String[][]{data}, query); + + assertTrue(res.next()); + + Date date = res.getDate(1); + assertNotNull(date); + assertEquals(Date.valueOf("2014-01-01"), date); + + date = res.getDate("col1"); + assertNotNull(date); + assertEquals(Date.valueOf("2014-01-01"), date); + + Time time = res.getTime(2); + assertNotNull(time); + assertEquals(Time.valueOf("01:00:00"), time); + + time = res.getTime("col2"); + assertNotNull(time); + assertEquals(Time.valueOf("01:00:00"), time); + + Timestamp timestamp = res.getTimestamp(3); + assertNotNull(timestamp); + assertEquals(Timestamp.valueOf("2014-01-01 01:00:00"), timestamp); + + timestamp = res.getTimestamp("col3"); + assertNotNull(timestamp); + assertEquals(Timestamp.valueOf("2014-01-01 01:00:00"), timestamp); + + // assert with timezone + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+9")); + date = res.getDate(1, cal); + assertNotNull(date); + assertEquals("2014-01-01", date.toString()); + + date = res.getDate("col1", cal); + assertNotNull(date); + assertEquals("2014-01-01", date.toString()); + + time = res.getTime(2, cal); + assertNotNull(time); + assertEquals("10:00:00", time.toString()); + + time = res.getTime("col2", cal); + assertNotNull(time); + assertEquals("10:00:00", time.toString()); + + timestamp = res.getTimestamp(3, cal); + assertNotNull(timestamp); + assertEquals("2014-01-01 10:00:00.0", timestamp.toString()); + + timestamp = res.getTimestamp("col3", cal); + assertNotNull(timestamp); + assertEquals("2014-01-01 10:00:00.0", timestamp.toString()); + } finally { + TajoConf.setCurrentTimeZone(tajoCurrentTimeZone); + TimeZone.setDefault(systemCurrentTimeZone); + res.close(); + } + } } From 2dc62b65b98c96f6e7696554c861ff47841a073a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=98=95=EC=A4=80?= Date: Mon, 26 May 2014 11:46:49 +0900 Subject: [PATCH 2/3] TAJO-844: JDBC should be support getTime, getDate, getTimestamp --- .../org/apache/tajo/engine/query/TestSortQuery.java | 3 +++ .../results/TestSortQuery/testSortWithDate.result | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java index 415ed499fc..0b1831cac3 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java @@ -120,6 +120,8 @@ public final void testSortWithDate() throws Exception { // skip this test if catalog uses HCatalogStore. // It is because HCatalogStore does not support Time data type. TimeZone oldTimeZone = TajoConf.setCurrentTimeZone(TimeZone.getTimeZone("UTC")); + TimeZone systemOldTimeZone = TimeZone.getDefault(); + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); try { if (!testingCluster.isHCatalogStoreRunning()) { // create external table table1 (col1 timestamp, col2 date, col3 time) ... @@ -131,6 +133,7 @@ public final void testSortWithDate() throws Exception { } } finally { TajoConf.setCurrentTimeZone(oldTimeZone); + TimeZone.setDefault(systemOldTimeZone); } } diff --git a/tajo-core/src/test/resources/results/TestSortQuery/testSortWithDate.result b/tajo-core/src/test/resources/results/TestSortQuery/testSortWithDate.result index 118909c959..81bac55c36 100644 --- a/tajo-core/src/test/resources/results/TestSortQuery/testSortWithDate.result +++ b/tajo-core/src/test/resources/results/TestSortQuery/testSortWithDate.result @@ -1,7 +1,7 @@ col1,col2,col3 ------------------------------- -1993-11-09 20:34:56,1997-01-28,08:34:56 -1995-11-09 20:34:56,1993-11-09,20:34:56 -1995-11-09 20:34:56,1994-02-02,17:34:56 -1997-11-09 20:34:56,1996-03-13,19:34:56 -1997-11-09 20:34:56,1996-04-12,15:34:56 \ No newline at end of file +1993-11-09 20:34:56.0,1997-01-28,08:34:56 +1995-11-09 20:34:56.0,1993-11-09,20:34:56 +1995-11-09 20:34:56.0,1994-02-02,17:34:56 +1997-11-09 20:34:56.0,1996-03-13,19:34:56 +1997-11-09 20:34:56.0,1996-04-12,15:34:56 \ No newline at end of file From 07c4288cc944b873d905ed1183596935f0c7b032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=98=95=EC=A4=80?= Date: Tue, 10 Jun 2014 21:55:50 +0900 Subject: [PATCH 3/3] TAJO-844: JDBC should be support getTime, getDate, getTimestamp Remove .0 from testSortWithDate(TestSortQuery).result file --- .../results/TestSortQuery/testSortWithDate.result | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tajo-core/src/test/resources/results/TestSortQuery/testSortWithDate.result b/tajo-core/src/test/resources/results/TestSortQuery/testSortWithDate.result index 81bac55c36..118909c959 100644 --- a/tajo-core/src/test/resources/results/TestSortQuery/testSortWithDate.result +++ b/tajo-core/src/test/resources/results/TestSortQuery/testSortWithDate.result @@ -1,7 +1,7 @@ col1,col2,col3 ------------------------------- -1993-11-09 20:34:56.0,1997-01-28,08:34:56 -1995-11-09 20:34:56.0,1993-11-09,20:34:56 -1995-11-09 20:34:56.0,1994-02-02,17:34:56 -1997-11-09 20:34:56.0,1996-03-13,19:34:56 -1997-11-09 20:34:56.0,1996-04-12,15:34:56 \ No newline at end of file +1993-11-09 20:34:56,1997-01-28,08:34:56 +1995-11-09 20:34:56,1993-11-09,20:34:56 +1995-11-09 20:34:56,1994-02-02,17:34:56 +1997-11-09 20:34:56,1996-03-13,19:34:56 +1997-11-09 20:34:56,1996-04-12,15:34:56 \ No newline at end of file