From 9ed001869b4887f57e108764354557391092ecab Mon Sep 17 00:00:00 2001 From: Matt Burgess Date: Mon, 17 Apr 2017 22:40:47 -0400 Subject: [PATCH] NIFI-2323: Fixed Oracle timestamp handling in DB fetch processors. This closes #1664. --- .../AbstractDatabaseFetchProcessor.java | 42 +++++++++---------- .../standard/QueryDatabaseTableTest.java | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/AbstractDatabaseFetchProcessor.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/AbstractDatabaseFetchProcessor.java index 71b287be81..1d943f4c19 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/AbstractDatabaseFetchProcessor.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/AbstractDatabaseFetchProcessor.java @@ -181,7 +181,7 @@ public abstract class AbstractDatabaseFetchProcessor extends AbstractSessionFact ServiceLoader dbAdapterLoader = ServiceLoader.load(DatabaseAdapter.class); dbAdapterLoader.forEach(it -> { dbAdapters.put(it.getName(), it); - dbAdapterValues.add(new AllowableValue(it.getName(),it.getName(), it.getDescription())); + dbAdapterValues.add(new AllowableValue(it.getName(), it.getName(), it.getDescription())); }); DB_TYPE = new PropertyDescriptor.Builder() @@ -351,26 +351,20 @@ public abstract class AbstractDatabaseFetchProcessor extends AbstractSessionFact break; case TIMESTAMP: - // Oracle timestamp queries must use literals in java.sql.Date format - if ("Oracle".equals(databaseType)) { - Date rawColOracleTimestampValue = resultSet.getDate(columnIndex); - java.sql.Date oracleTimestampValue = new java.sql.Date(rawColOracleTimestampValue.getTime()); - java.sql.Date maxOracleTimestampValue = null; - if (maxValueString != null) { - maxOracleTimestampValue = java.sql.Date.valueOf(maxValueString); - } - if (maxOracleTimestampValue == null || oracleTimestampValue.after(maxOracleTimestampValue)) { - return oracleTimestampValue.toString(); - } - } else { - Timestamp colTimestampValue = resultSet.getTimestamp(columnIndex); - java.sql.Timestamp maxTimestampValue = null; - if (maxValueString != null) { + Timestamp colTimestampValue = resultSet.getTimestamp(columnIndex); + java.sql.Timestamp maxTimestampValue = null; + if (maxValueString != null) { + // For backwards compatibility, the type might be TIMESTAMP but the state value is in DATE format. This should be a one-time occurrence as the next maximum value + // should be stored as a full timestamp. Even so, check to see if the value is missing time-of-day information, and use the "date" coercion rather than the + // "timestamp" coercion in that case + try { maxTimestampValue = java.sql.Timestamp.valueOf(maxValueString); + } catch (IllegalArgumentException iae) { + maxTimestampValue = new java.sql.Timestamp(java.sql.Date.valueOf(maxValueString).getTime()); } - if (maxTimestampValue == null || colTimestampValue.after(maxTimestampValue)) { - return colTimestampValue.toString(); - } + } + if (maxTimestampValue == null || colTimestampValue.after(maxTimestampValue)) { + return colTimestampValue.toString(); } break; @@ -411,9 +405,15 @@ public abstract class AbstractDatabaseFetchProcessor extends AbstractSessionFact case TIME: return "'" + value + "'"; case TIMESTAMP: - // Timestamp literals in Oracle need to be cast with TO_DATE if ("Oracle".equals(databaseType)) { - return "to_date('" + value + "', 'yyyy-mm-dd HH24:MI:SS')"; + // For backwards compatibility, the type might be TIMESTAMP but the state value is in DATE format. This should be a one-time occurrence as the next maximum value + // should be stored as a full timestamp. Even so, check to see if the value is missing time-of-day information, and use the "date" coercion rather than the + // "timestamp" coercion in that case + if (value.matches("\\d{4}-\\d{2}-\\d{2}")) { + return "date '" + value + "'"; + } else { + return "timestamp '" + value + "'"; + } } else { return "'" + value + "'"; } diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/QueryDatabaseTableTest.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/QueryDatabaseTableTest.java index 6af59ebab6..b015371704 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/QueryDatabaseTableTest.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/QueryDatabaseTableTest.java @@ -157,7 +157,7 @@ public class QueryDatabaseTableTest { // Test Oracle strategy dbAdapter = new OracleDatabaseAdapter(); query = processor.getQuery(dbAdapter, "myTable", null, Arrays.asList("id", "DATE_CREATED"), stateManager.getState(Scope.CLUSTER).toMap()); - assertEquals("SELECT * FROM myTable WHERE id > 509 AND DATE_CREATED >= to_date('2016-03-07 12:34:56', 'yyyy-mm-dd HH24:MI:SS')", query); + assertEquals("SELECT * FROM myTable WHERE id > 509 AND DATE_CREATED >= timestamp '2016-03-07 12:34:56'", query); } @Test(expected = IllegalArgumentException.class)