From e12832a307b6c9f092f2b3daee674dff71b05ab7 Mon Sep 17 00:00:00 2001 From: Mike Pigott Date: Sat, 1 Dec 2018 10:47:34 -0500 Subject: [PATCH] Allowing for timestamps without a time zone. --- .../arrow/adapter/jdbc/JdbcToArrow.java | 10 ++++---- .../arrow/adapter/jdbc/JdbcToArrowUtils.java | 24 ++++++++++++++----- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/java/adapter/jdbc/src/main/java/org/apache/arrow/adapter/jdbc/JdbcToArrow.java b/java/adapter/jdbc/src/main/java/org/apache/arrow/adapter/jdbc/JdbcToArrow.java index 14e4368368dda..fce3b476f8b41 100644 --- a/java/adapter/jdbc/src/main/java/org/apache/arrow/adapter/jdbc/JdbcToArrow.java +++ b/java/adapter/jdbc/src/main/java/org/apache/arrow/adapter/jdbc/JdbcToArrow.java @@ -131,7 +131,7 @@ public static VectorSchemaRoot sqlToArrow( public static VectorSchemaRoot sqlToArrow(ResultSet resultSet) throws SQLException, IOException { Preconditions.checkNotNull(resultSet, "JDBC ResultSet object can not be null"); - return sqlToArrow(resultSet, Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT)); + return sqlToArrow(resultSet, (Calendar) null); } /** @@ -147,20 +147,19 @@ public static VectorSchemaRoot sqlToArrow(ResultSet resultSet, BaseAllocator all Preconditions.checkNotNull(resultSet, "JDBC ResultSet object can not be null"); Preconditions.checkNotNull(allocator, "Memory Allocator object can not be null"); - return sqlToArrow(resultSet, allocator, Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT)); + return sqlToArrow(resultSet, allocator, null); } /** * For the given JDBC {@link ResultSet}, fetch the data from Relational DB and convert it to Arrow objects. * * @param resultSet ResultSet to use to fetch the data from underlying database - * @param calendar Calendar instance to use for Date, Time and Timestamp datasets. + * @param calendar Calendar instance to use for Date, Time and Timestamp datasets, or null if none. * @return Arrow Data Objects {@link VectorSchemaRoot} * @throws SQLException on error */ public static VectorSchemaRoot sqlToArrow(ResultSet resultSet, Calendar calendar) throws SQLException, IOException { Preconditions.checkNotNull(resultSet, "JDBC ResultSet object can not be null"); - Preconditions.checkNotNull(calendar, "Calendar object can not be null"); RootAllocator rootAllocator = new RootAllocator(Integer.MAX_VALUE); VectorSchemaRoot root = sqlToArrow(resultSet, rootAllocator, calendar); @@ -173,7 +172,7 @@ public static VectorSchemaRoot sqlToArrow(ResultSet resultSet, Calendar calendar * * @param resultSet ResultSet to use to fetch the data from underlying database * @param allocator Memory allocator to use. - * @param calendar Calendar instance to use for Date, Time and Timestamp datasets. + * @param calendar Calendar instance to use for Date, Time and Timestamp datasets, or null if none. * @return Arrow Data Objects {@link VectorSchemaRoot} * @throws SQLException on error */ @@ -181,7 +180,6 @@ public static VectorSchemaRoot sqlToArrow(ResultSet resultSet, BaseAllocator all throws SQLException, IOException { Preconditions.checkNotNull(resultSet, "JDBC ResultSet object can not be null"); Preconditions.checkNotNull(allocator, "Memory Allocator object can not be null"); - Preconditions.checkNotNull(calendar, "Calendar object can not be null"); VectorSchemaRoot root = VectorSchemaRoot.create( JdbcToArrowUtils.jdbcToArrowSchema(resultSet.getMetaData(), calendar), allocator); diff --git a/java/adapter/jdbc/src/main/java/org/apache/arrow/adapter/jdbc/JdbcToArrowUtils.java b/java/adapter/jdbc/src/main/java/org/apache/arrow/adapter/jdbc/JdbcToArrowUtils.java index 3425fa6471e87..df9b94db3b743 100644 --- a/java/adapter/jdbc/src/main/java/org/apache/arrow/adapter/jdbc/JdbcToArrowUtils.java +++ b/java/adapter/jdbc/src/main/java/org/apache/arrow/adapter/jdbc/JdbcToArrowUtils.java @@ -120,6 +120,11 @@ public class JdbcToArrowUtils { * CLOB --> ArrowType.Utf8 * BLOB --> ArrowType.Binary * + *

If a {@link java.util.Calendar} is set, {@link java.sql.Timestamp} fields in the {@link java.sql.ResultSet} will + * be converted to an Arrow {@link org.apache.arrow.vector.TimeStampVector} using the Calendar's time + * zone. If the Calendar is null, no time zone will be set on the + * TimeStampVector. + * * @param rsmd ResultSetMetaData * @return {@link Schema} * @throws SQLException on error @@ -127,7 +132,8 @@ public class JdbcToArrowUtils { public static Schema jdbcToArrowSchema(ResultSetMetaData rsmd, Calendar calendar) throws SQLException { Preconditions.checkNotNull(rsmd, "JDBC ResultSetMetaData object can't be null"); - Preconditions.checkNotNull(calendar, "Calendar object can't be null"); + + final String tz = (calendar != null) ? calendar.getTimeZone().getID() : null; List fields = new ArrayList<>(); int columnCount = rsmd.getColumnCount(); @@ -178,8 +184,8 @@ public static Schema jdbcToArrowSchema(ResultSetMetaData rsmd, Calendar calendar fields.add(new Field(columnName, FieldType.nullable(new ArrowType.Time(TimeUnit.MILLISECOND, 32)), null)); break; case Types.TIMESTAMP: - fields.add(new Field(columnName, FieldType.nullable(new ArrowType.Timestamp(TimeUnit.MILLISECOND, - calendar.getTimeZone().getID())), null)); + fields.add(new Field(columnName, FieldType.nullable(new ArrowType.Timestamp(TimeUnit.MILLISECOND, tz)), + null)); break; case Types.BINARY: case Types.VARBINARY: @@ -231,7 +237,6 @@ public static void jdbcToArrowVectors(ResultSet rs, VectorSchemaRoot root, Calen Preconditions.checkNotNull(rs, "JDBC ResultSet object can't be null"); Preconditions.checkNotNull(root, "JDBC ResultSet object can't be null"); - Preconditions.checkNotNull(calendar, "Calendar object can't be null"); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); @@ -296,9 +301,16 @@ public static void jdbcToArrowVectors(ResultSet rs, VectorSchemaRoot root, Calen rs.getTime(i, calendar), !rs.wasNull(), rowCount); break; case Types.TIMESTAMP: - // TODO: Need to handle precision such as milli, micro, nano + final Timestamp ts; + if (calendar != null) { + ts = rs.getTimestamp(i, calendar); + } else { + ts = rs.getTimestamp(i); + } + + // TODO: Need to handle precision such as milli, micro, nano updateVector((TimeStampVector) root.getVector(columnName), - rs.getTimestamp(i, calendar), !rs.wasNull(), rowCount); + ts, !rs.wasNull(), rowCount); break; case Types.BINARY: case Types.VARBINARY: