From ba32879ec81cdfa3c44734ab8b210b13fa0581ac Mon Sep 17 00:00:00 2001 From: Matthew Burgess Date: Tue, 17 Apr 2018 10:44:26 -0400 Subject: [PATCH] NIFI-5082: Added support for custom Oracle timestamp types to Avro conversion This closes #2638 Signed-off-by: Mike Thomsen --- .../record/ResultSetRecordSet.java | 2 ++ .../processors/standard/util/JdbcCommon.java | 27 ++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/nifi-commons/nifi-record/src/main/java/org/apache/nifi/serialization/record/ResultSetRecordSet.java b/nifi-commons/nifi-record/src/main/java/org/apache/nifi/serialization/record/ResultSetRecordSet.java index a0f44e5808..551789cac4 100644 --- a/nifi-commons/nifi-record/src/main/java/org/apache/nifi/serialization/record/ResultSetRecordSet.java +++ b/nifi-commons/nifi-record/src/main/java/org/apache/nifi/serialization/record/ResultSetRecordSet.java @@ -350,6 +350,8 @@ public class ResultSetRecordSet implements RecordSet, Closeable { return RecordFieldType.TIME; case Types.TIMESTAMP: case Types.TIMESTAMP_WITH_TIMEZONE: + case -101: // Oracle's TIMESTAMP WITH TIME ZONE + case -102: // Oracle's TIMESTAMP WITH LOCAL TIME ZONE return RecordFieldType.TIMESTAMP; } diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/util/JdbcCommon.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/util/JdbcCommon.java index b203c31c81..260a94ae78 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/util/JdbcCommon.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/util/JdbcCommon.java @@ -41,6 +41,7 @@ import static java.sql.Types.ROWID; import static java.sql.Types.SMALLINT; import static java.sql.Types.TIME; import static java.sql.Types.TIMESTAMP; +import static java.sql.Types.TIMESTAMP_WITH_TIMEZONE; import static java.sql.Types.TINYINT; import static java.sql.Types.VARBINARY; import static java.sql.Types.VARCHAR; @@ -356,7 +357,28 @@ public class JdbcCommon { continue; } - final Object value = rs.getObject(i); + Object value; + + // If a Timestamp type, try getTimestamp() rather than getObject() + if (javaSqlType == TIMESTAMP + || javaSqlType == TIMESTAMP_WITH_TIMEZONE + // The following are Oracle-specific codes for TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE. This would be better + // located in the DatabaseAdapter interfaces, but some processors (like ExecuteSQL) use this method but don't specify a DatabaseAdapter. + || javaSqlType == -101 + || javaSqlType == -102) { + try { + value = rs.getTimestamp(i); + // Some drivers (like Derby) return null for getTimestamp() but return a Timestamp object in getObject() + if (value == null) { + value = rs.getObject(i); + } + } catch (Exception e) { + // The cause of the exception is not known, but we'll fall back to call getObject() and handle any "real" exception there + value = rs.getObject(i); + } + } else { + value = rs.getObject(i); + } if (value == null) { rec.put(i - 1, null); @@ -603,6 +625,9 @@ public class JdbcCommon { break; case TIMESTAMP: + case TIMESTAMP_WITH_TIMEZONE: + case -101: // Oracle's TIMESTAMP WITH TIME ZONE + case -102: // Oracle's TIMESTAMP WITH LOCAL TIME ZONE addNullableField(builder, columnName, u -> options.useLogicalTypes ? u.type(LogicalTypes.timestampMillis().addToSchema(SchemaBuilder.builder().longType()))