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 ec9a3a7be26 NIFI-15803 Record path format returns a string type 
(#11115)
ec9a3a7be26 is described below

commit ec9a3a7be268a16c0aab112e9418b26b5e95a79c
Author: Alaksiej Ščarbaty <[email protected]>
AuthorDate: Thu Apr 9 16:37:44 2026 +0200

    NIFI-15803 Record path format returns a string type (#11115)
---
 .../apache/nifi/record/path/functions/Format.java  | 12 ++++++-
 .../apache/nifi/record/path/TestRecordPath.java    | 42 ++++++++++++++++++----
 2 files changed, 46 insertions(+), 8 deletions(-)

diff --git 
a/nifi-commons/nifi-record-path/src/main/java/org/apache/nifi/record/path/functions/Format.java
 
b/nifi-commons/nifi-record-path/src/main/java/org/apache/nifi/record/path/functions/Format.java
index 0ac3ad0dc72..97f126067d8 100644
--- 
a/nifi-commons/nifi-record-path/src/main/java/org/apache/nifi/record/path/functions/Format.java
+++ 
b/nifi-commons/nifi-record-path/src/main/java/org/apache/nifi/record/path/functions/Format.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;
@@ -82,7 +84,15 @@ public class Format extends RecordPathSegment {
 
                     final ZonedDateTime dateTime = instant.atZone(zoneId);
                     final String formatted = 
dateTimeFormatter.format(dateTime);
-                    return new StandardFieldValue(formatted, fv.getField(), 
fv.getParent().orElse(null));
+                    final RecordField originalField = fv.getField();
+                    final RecordField stringField;
+                    if (originalField != null) {
+                        stringField = new 
RecordField(originalField.getFieldName(), RecordFieldType.STRING.getDataType(),
+                            null, originalField.getAliases(), false);
+                    } else {
+                        stringField = new RecordField("format", 
RecordFieldType.STRING.getDataType());
+                    }
+                    return new StandardFieldValue(formatted, stringField, 
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 3e280cec26d..00bda40fd4d 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
@@ -1264,8 +1264,13 @@ public class TestRecordPath {
 
                 record.setValue("id", 
Instant.parse(instantFormatted).toEpochMilli());
 
-                assertEquals(localDate, evaluateSingleFieldValue("format(/id, 
'yyyy-MM-dd')", record).getValue());
-                assertEquals(instantFormatted, 
evaluateSingleFieldValue("format(/id, \"yyyy-MM-dd'T'HH:mm:ss'Z'\", 'GMT')", 
record).getValue());
+                final FieldValue dateResult = 
evaluateSingleFieldValue("format(/id, 'yyyy-MM-dd')", record);
+                assertEquals(localDate, dateResult.getValue());
+                assertEquals(RecordFieldType.STRING.getDataType(), 
dateResult.getField().getDataType());
+
+                final FieldValue dateTimeResult = 
evaluateSingleFieldValue("format(/id, \"yyyy-MM-dd'T'HH:mm:ss'Z'\", 'GMT')", 
record);
+                assertEquals(instantFormatted, dateTimeResult.getValue());
+                assertEquals(RecordFieldType.STRING.getDataType(), 
dateTimeResult.getField().getDataType());
             }
 
             @Test
@@ -1275,8 +1280,13 @@ public class TestRecordPath {
 
                 record.setValue("id", new 
Date(Instant.parse(instantFormatted).toEpochMilli()));
 
-                assertEquals(localDate, evaluateSingleFieldValue("format(/id, 
'yyyy-MM-dd')", record).getValue());
-                assertEquals(instantFormatted, 
evaluateSingleFieldValue("format(/id, \"yyyy-MM-dd'T'HH:mm:ss'Z'\", 'GMT')", 
record).getValue());
+                final FieldValue dateResult = 
evaluateSingleFieldValue("format(/id, 'yyyy-MM-dd')", record);
+                assertEquals(localDate, dateResult.getValue());
+                assertEquals(RecordFieldType.STRING.getDataType(), 
dateResult.getField().getDataType());
+
+                final FieldValue dateTimeResult = 
evaluateSingleFieldValue("format(/id, \"yyyy-MM-dd'T'HH:mm:ss'Z'\", 'GMT')", 
record);
+                assertEquals(instantFormatted, dateTimeResult.getValue());
+                assertEquals(RecordFieldType.STRING.getDataType(), 
dateTimeResult.getField().getDataType());
             }
 
             @Test
@@ -1284,7 +1294,9 @@ public class TestRecordPath {
                 record.setValue("id", Date.valueOf("2024-08-18"));
                 record.setValue("name", "yyyy-MM-dd");
 
-                assertEquals("2024-08-18", 
evaluateSingleFieldValue("format(/id, /name)", record).getValue());
+                final FieldValue result = 
evaluateSingleFieldValue("format(/id, /name)", record);
+                assertEquals("2024-08-18", result.getValue());
+                assertEquals(RecordFieldType.STRING.getDataType(), 
result.getField().getDataType());
             }
 
             @Test
@@ -1293,7 +1305,9 @@ public class TestRecordPath {
                 record.setValue("id", new 
Date(Instant.parse(instantFormatted).toEpochMilli()));
                 record.setValue("name", "GMT");
 
-                assertEquals(instantFormatted, 
evaluateSingleFieldValue("format(/id, \"yyyy-MM-dd'T'HH:mm:ss'Z'\", /name)", 
record).getValue());
+                final FieldValue result = 
evaluateSingleFieldValue("format(/id, \"yyyy-MM-dd'T'HH:mm:ss'Z'\", /name)", 
record);
+                assertEquals(instantFormatted, result.getValue());
+                assertEquals(RecordFieldType.STRING.getDataType(), 
result.getField().getDataType());
             }
 
             @Test
@@ -1301,7 +1315,11 @@ public class TestRecordPath {
                 final Date originalValue = Date.valueOf("2024-08-18");
                 record.setValue("id", originalValue);
 
-                assertEquals(originalValue, 
evaluateSingleFieldValue("format(/id, 'INVALID')", record).getValue());
+                final FieldValue result = 
evaluateSingleFieldValue("format(/id, 'INVALID')", record);
+                final DataType originalDataType = 
record.getSchema().getField("id").orElseThrow().getDataType();
+
+                assertEquals(originalValue, result.getValue());
+                assertEquals(originalDataType, 
result.getField().getDataType());
             }
 
             @Test
@@ -1310,9 +1328,19 @@ public class TestRecordPath {
 
                 assertAll(nonLongOrDateFields.stream().map(fieldName -> () -> {
                     final FieldValue fieldValue = 
evaluateSingleFieldValue("format(/%s, 'yyyy-MM-dd')".formatted(fieldName), 
record);
+                    final DataType originalDataType = 
record.getSchema().getField(fieldName).orElseThrow().getDataType();
+
                     assertEquals(record.getValue(fieldName), 
fieldValue.getValue());
+                    assertEquals(originalDataType, 
fieldValue.getField().getDataType());
                 }));
             }
+
+            @Test
+            public void handlesLiteralValue() {
+                final FieldValue result = evaluateSingleFieldValue("format(0, 
'yyyy-MM-dd', 'GMT')", record);
+                assertEquals("1970-01-01", result.getValue());
+                assertEquals(RecordFieldType.STRING.getDataType(), 
result.getField().getDataType());
+            }
         }
 
         @Nested

Reply via email to