This is an automated email from the ASF dual-hosted git repository.
pvillard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new bed442699a5 NIFI-15808 Record path toDate returns a timestamp type
(#11120)
bed442699a5 is described below
commit bed442699a5ecc0ca99a38681fe34ab5e5dc5edb
Author: Alaksiej Ščarbaty <[email protected]>
AuthorDate: Thu Apr 9 16:46:50 2026 +0200
NIFI-15808 Record path toDate returns a timestamp type (#11120)
The toDate function previously returned a FieldValue that inherited
the source field's DataType instead of TIMESTAMP. Since toDate parses
strings into java.util.Date objects with full date+time precision,
TIMESTAMP is the correct output type to avoid loss of time components.
---
.../java/org/apache/nifi/record/path/functions/ToDate.java | 12 +++++++++++-
.../java/org/apache/nifi/record/path/TestRecordPath.java | 14 ++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git
a/nifi-commons/nifi-record-path/src/main/java/org/apache/nifi/record/path/functions/ToDate.java
b/nifi-commons/nifi-record-path/src/main/java/org/apache/nifi/record/path/functions/ToDate.java
index 9a076c2450a..0e3f1e8ddc1 100644
---
a/nifi-commons/nifi-record-path/src/main/java/org/apache/nifi/record/path/functions/ToDate.java
+++
b/nifi-commons/nifi-record-path/src/main/java/org/apache/nifi/record/path/functions/ToDate.java
@@ -22,6 +22,8 @@ import
org.apache.nifi.record.path.RecordPathEvaluationContext;
import org.apache.nifi.record.path.StandardFieldValue;
import org.apache.nifi.record.path.paths.RecordPathSegment;
import org.apache.nifi.record.path.util.RecordPathUtils;
+import org.apache.nifi.serialization.record.RecordField;
+import org.apache.nifi.serialization.record.RecordFieldType;
import java.time.Instant;
import java.time.ZoneId;
@@ -117,7 +119,15 @@ public class ToDate extends RecordPathSegment {
return fv;
}
- return new StandardFieldValue(dateValue, fv.getField(),
fv.getParent().orElse(null));
+ final RecordField originalField = fv.getField();
+ final RecordField timestampField;
+ if (originalField != null) {
+ timestampField = new
RecordField(originalField.getFieldName(),
RecordFieldType.TIMESTAMP.getDataType(),
+ null, originalField.getAliases(), false);
+ } else {
+ timestampField = new RecordField("toDate",
RecordFieldType.TIMESTAMP.getDataType());
+ }
+ return new StandardFieldValue(dateValue, timestampField,
fv.getParent().orElse(null));
});
}
diff --git
a/nifi-commons/nifi-record-path/src/test/java/org/apache/nifi/record/path/TestRecordPath.java
b/nifi-commons/nifi-record-path/src/test/java/org/apache/nifi/record/path/TestRecordPath.java
index c9bae3a2798..03d7c666796 100644
---
a/nifi-commons/nifi-record-path/src/test/java/org/apache/nifi/record/path/TestRecordPath.java
+++
b/nifi-commons/nifi-record-path/src/test/java/org/apache/nifi/record/path/TestRecordPath.java
@@ -42,6 +42,7 @@ import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.Instant;
+import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
@@ -2050,6 +2051,7 @@ public class TestRecordPath {
final FieldValue fieldValue =
evaluateSingleFieldValue("toDate(/date, \"yyyy-MM-dd'T'HH:mm:ss\")", record);
assertEquals(expectedValue, fieldValue.getValue());
+ assertEquals(RecordFieldType.TIMESTAMP.getDataType(),
fieldValue.getField().getDataType());
}
@Test
@@ -2063,6 +2065,7 @@ public class TestRecordPath {
final FieldValue fieldValue =
evaluateSingleFieldValue("toDate(/date, \"yyyy-MM-dd'T'HH:mm:ss\",
'GMT+8:00')", record);
assertEquals(expectedValue, fieldValue.getValue());
+ assertEquals(RecordFieldType.TIMESTAMP.getDataType(),
fieldValue.getField().getDataType());
}
@Test
@@ -2075,6 +2078,7 @@ public class TestRecordPath {
final FieldValue fieldValue =
evaluateSingleFieldValue("toDate(/date, /name)", record);
assertEquals(expectedValue, fieldValue.getValue());
+ assertEquals(RecordFieldType.TIMESTAMP.getDataType(),
fieldValue.getField().getDataType());
}
@Test
@@ -2090,6 +2094,7 @@ public class TestRecordPath {
final FieldValue fieldValue =
evaluateSingleFieldValue("toDate(/date, \"yyyy-MM-dd'T'HH:mm:ss\", /name)",
record);
assertEquals(expectedValue, fieldValue.getValue());
+ assertEquals(RecordFieldType.TIMESTAMP.getDataType(),
fieldValue.getField().getDataType());
}
@Test
@@ -2115,6 +2120,15 @@ public class TestRecordPath {
assertEquals(record.getValue(fieldName),
fieldValue.getValue());
}));
}
+
+ @Test
+ public void handlesLiteralValue() {
+ final Date expectedValue = new
Date(LocalDate.parse("2017-10-20").atStartOfDay(TEST_ZONE_ID).toInstant().toEpochMilli());
+
+ final FieldValue fieldValue =
evaluateSingleFieldValue("toDate('2017-10-20', 'yyyy-MM-dd')", record);
+ assertEquals(expectedValue, fieldValue.getValue());
+ assertEquals(RecordFieldType.TIMESTAMP.getDataType(),
fieldValue.getField().getDataType());
+ }
}
@Nested