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

Reply via email to