This is an automated email from the ASF dual-hosted git repository.
exceptionfactory 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 d7e92b8705d NIFI-16336 Initialized all field names with inference
defaults in ExcelStartingRowSchemaInference (#11716)
d7e92b8705d is described below
commit d7e92b8705d1c2eee48aa4d51875b0c6b4d4c362
Author: dan-s1 <[email protected]>
AuthorDate: Mon Sep 28 17:21:33 2026 -0400
NIFI-16336 Initialized all field names with inference defaults in
ExcelStartingRowSchemaInference (#11716)
- Initialization ensures a record field type for each field
Signed-off-by: David Handermann <[email protected]>
---
.../excel/ExcelStartingRowSchemaInference.java | 5 ++
.../excel/TestExcelStartingRowSchemaInference.java | 91 +++++++++++++++++++---
2 files changed, 86 insertions(+), 10 deletions(-)
diff --git
a/nifi-extension-bundles/nifi-poi-bundle/nifi-poi-services/src/main/java/org/apache/nifi/excel/ExcelStartingRowSchemaInference.java
b/nifi-extension-bundles/nifi-poi-bundle/nifi-poi-services/src/main/java/org/apache/nifi/excel/ExcelStartingRowSchemaInference.java
index 4a6c0f45443..d951f81ef4e 100644
---
a/nifi-extension-bundles/nifi-poi-bundle/nifi-poi-services/src/main/java/org/apache/nifi/excel/ExcelStartingRowSchemaInference.java
+++
b/nifi-extension-bundles/nifi-poi-bundle/nifi-poi-services/src/main/java/org/apache/nifi/excel/ExcelStartingRowSchemaInference.java
@@ -69,6 +69,11 @@ public class ExcelStartingRowSchemaInference implements
SchemaInferenceEngine<Ro
while ((row = recordSource.next()) != null) {
if (index == 0) {
fieldNames = getFieldNames(firstRow, row);
+ // Initialize the typeMap with all the determined field names
thereby setting data type defaults for all fields
+ // just in case a specific field data type cannot be inferred.
+ for (String fieldName : fieldNames) {
+ typeMap.put(fieldName, new FieldTypeInference());
+ }
} else if (row.getRowNum() == zeroBasedFirstRow) { // skip first
row of all sheets
continue;
} else {
diff --git
a/nifi-extension-bundles/nifi-poi-bundle/nifi-poi-services/src/test/java/org/apache/nifi/excel/TestExcelStartingRowSchemaInference.java
b/nifi-extension-bundles/nifi-poi-bundle/nifi-poi-services/src/test/java/org/apache/nifi/excel/TestExcelStartingRowSchemaInference.java
index a6801470c23..104a4171240 100644
---
a/nifi-extension-bundles/nifi-poi-bundle/nifi-poi-services/src/test/java/org/apache/nifi/excel/TestExcelStartingRowSchemaInference.java
+++
b/nifi-extension-bundles/nifi-poi-bundle/nifi-poi-services/src/test/java/org/apache/nifi/excel/TestExcelStartingRowSchemaInference.java
@@ -22,6 +22,7 @@ import org.apache.nifi.logging.ComponentLog;
import org.apache.nifi.schema.access.SchemaNotFoundException;
import org.apache.nifi.schema.inference.InferSchemaAccessStrategy;
import org.apache.nifi.schema.inference.TimeValueInference;
+import org.apache.nifi.serialization.record.DataType;
import org.apache.nifi.serialization.record.RecordField;
import org.apache.nifi.serialization.record.RecordFieldType;
import org.apache.nifi.serialization.record.RecordSchema;
@@ -51,6 +52,7 @@ import java.nio.file.Path;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import static java.nio.file.Files.newDirectoryStream;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
@@ -169,6 +171,60 @@ public class TestExcelStartingRowSchemaInference {
}
}
+ @Test
+ void testWithHeaderWithOnlySingleCellOfData() throws Exception {
+ Object[][] singleSheet = {{"ID", "First", "Middle"}, {}, {}, {},
+ {}, {}, {6}, {}, {}, {}, {}};
+
+ final ByteArrayOutputStream outputStream = createWorkbook(singleSheet);
+
+ try (final InputStream inputStream = new
ByteArrayInputStream(outputStream.toByteArray())) {
+ final InferSchemaAccessStrategy<?> inferSchemaAccessStrategy =
getInferSchemaAccessStrategy(RowEvaluationStrategy.STANDARD);
+ final RecordSchema recordSchema =
inferSchemaAccessStrategy.getSchema(null, inputStream, null);
+
+ assertEquals(List.of("ID", "First", "Middle"),
recordSchema.getFieldNames());
+ Optional<DataType> optional = recordSchema.getDataType("ID");
+ assertTrue(optional.isPresent() &&
optional.get().getFieldType().equals(RecordFieldType.LONG));
+
+ optional = recordSchema.getDataType("First");
+ assertTrue(optional.isPresent() &&
optional.get().getFieldType().equals(RecordFieldType.STRING));
+
+ optional = recordSchema.getDataType("Middle");
+ assertTrue(optional.isPresent() &&
optional.get().getFieldType().equals(RecordFieldType.STRING));
+ }
+ }
+
+ @ParameterizedTest
+ @EnumSource(RowEvaluationStrategy.class)
+ void
testWhereLeadingRowAndConfiguredInferenceRowsHaveNoCells(RowEvaluationStrategy
rowEvaluationStrategy) throws IOException {
+ Object[][] singleSheet = {{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}};
+ final ByteArrayOutputStream outputStream = createWorkbook(singleSheet);
+
+ try (final InputStream inputStream = new
ByteArrayInputStream(outputStream.toByteArray())) {
+ final InferSchemaAccessStrategy<?> inferSchemaAccessStrategy =
getInferSchemaAccessStrategy(rowEvaluationStrategy);
+ final IOException ioException = assertThrows(IOException.class, ()
-> inferSchemaAccessStrategy.getSchema(null, inputStream, null));
+ assertInstanceOf(SchemaNotFoundException.class,
ioException.getCause());
+ }
+ }
+
+ @ParameterizedTest
+ @EnumSource(RowEvaluationStrategy.class)
+ void
testWhereLeadingRowHasBlankValuesAndConfiguredInferenceRowsHaveNoCells(RowEvaluationStrategy
rowEvaluationStrategy) throws IOException {
+ Object[][] singleSheet = {{"", "", ""}, {}, {}, {}, {}, {}, {}, {},
{}, {}, {}};
+ final ByteArrayOutputStream outputStream = createWorkbook(singleSheet);
+
+ try (final InputStream inputStream = new
ByteArrayInputStream(outputStream.toByteArray())) {
+ final InferSchemaAccessStrategy<?> inferSchemaAccessStrategy =
getInferSchemaAccessStrategy(rowEvaluationStrategy);
+ final RecordSchema recordSchema =
inferSchemaAccessStrategy.getSchema(null, inputStream, null);
+ assertEquals(List.of("column_0", "column_1", "column_2"),
recordSchema.getFieldNames());
+
+ for (String fieldName : recordSchema.getFieldNames()) {
+ final Optional<DataType> optional =
recordSchema.getDataType(fieldName);
+ assertTrue(optional.isPresent() &&
optional.get().getFieldType().equals(RecordFieldType.STRING));
+ }
+ }
+ }
+
@ParameterizedTest
@EnumSource(RowEvaluationStrategy.class)
void testWhereConfiguredInferenceRowsAreAllBlank(RowEvaluationStrategy
rowEvaluationStrategy) throws Exception {
@@ -177,15 +233,23 @@ public class TestExcelStartingRowSchemaInference {
try (final InputStream inputStream = new
ByteArrayInputStream(outputStream.toByteArray())) {
final InferSchemaAccessStrategy<?> inferSchemaAccessStrategy =
getInferSchemaAccessStrategy(rowEvaluationStrategy);
+ final RecordSchema recordSchema =
inferSchemaAccessStrategy.getSchema(null, inputStream, null);
- switch (rowEvaluationStrategy) {
- case STANDARD -> {
- final IOException ioException =
assertThrows(IOException.class, () -> inferSchemaAccessStrategy.getSchema(null,
inputStream, null));
- assertInstanceOf(SchemaNotFoundException.class,
ioException.getCause());
-
assertTrue(ioException.getCause().getMessage().contains("empty"));
- }
- case ALL -> assertDoesNotThrow(() ->
inferSchemaAccessStrategy.getSchema(null, inputStream, null));
+ assertEquals(List.of("ID", "First", "Middle"),
recordSchema.getFieldNames());
+ Optional<DataType> optional = recordSchema.getDataType("ID");
+
+ if (RowEvaluationStrategy.STANDARD.equals(rowEvaluationStrategy)) {
+ assertTrue(optional.isPresent() &&
optional.get().getFieldType().equals(RecordFieldType.STRING));
+ } else {
+ assertTrue(optional.isPresent() &&
optional.get().getFieldType().equals(RecordFieldType.LONG));
}
+
+ optional = recordSchema.getDataType("First");
+ assertTrue(optional.isPresent() &&
optional.get().getFieldType().equals(RecordFieldType.STRING));
+
+ optional = recordSchema.getDataType("Middle");
+ assertTrue(optional.isPresent() &&
optional.get().getFieldType().equals(RecordFieldType.STRING));
+
}
}
@@ -197,10 +261,17 @@ public class TestExcelStartingRowSchemaInference {
try (final InputStream inputStream = new
ByteArrayInputStream(outputStream.toByteArray())) {
final InferSchemaAccessStrategy<?> inferSchemaAccessStrategy =
getInferSchemaAccessStrategy(rowEvaluationStrategy);
+ final RecordSchema recordSchema =
inferSchemaAccessStrategy.getSchema(null, inputStream, null);
- final IOException ioException = assertThrows(IOException.class, ()
-> inferSchemaAccessStrategy.getSchema(null, inputStream, null));
- assertInstanceOf(SchemaNotFoundException.class,
ioException.getCause());
- assertTrue(ioException.getCause().getMessage().contains("empty"));
+ assertEquals(List.of("ID", "First", "Middle"),
recordSchema.getFieldNames());
+ Optional<DataType> optional = recordSchema.getDataType("ID");
+ assertTrue(optional.isPresent() &&
optional.get().getFieldType().equals(RecordFieldType.STRING));
+
+ optional = recordSchema.getDataType("First");
+ assertTrue(optional.isPresent() &&
optional.get().getFieldType().equals(RecordFieldType.STRING));
+
+ optional = recordSchema.getDataType("Middle");
+ assertTrue(optional.isPresent() &&
optional.get().getFieldType().equals(RecordFieldType.STRING));
}
}