You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by pv...@apache.org on 2026/07/07 08:34:55 UTC

(nifi) branch main updated: NIFI-16080 Switch to JDBC Enquote Identifier in UpdateDatabaseTable (#11397)

This is an automated email from the ASF dual-hosted git repository.

pvillard31 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 c9c68cf69e7 NIFI-16080 Switch to JDBC Enquote Identifier in UpdateDatabaseTable (#11397)
c9c68cf69e7 is described below

commit c9c68cf69e7e186359c8ca2aa4695c7828c51915
Author: David Handermann <ex...@apache.org>
AuthorDate: Tue Jul 7 03:34:48 2026 -0500

    NIFI-16080 Switch to JDBC Enquote Identifier in UpdateDatabaseTable (#11397)
---
 .../processors/standard/UpdateDatabaseTable.java   | 46 +++++++++++++---------
 .../standard/TestUpdateDatabaseTable.java          | 30 +++++++++++++-
 2 files changed, 55 insertions(+), 21 deletions(-)

diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/UpdateDatabaseTable.java b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/UpdateDatabaseTable.java
index 049009f8348..5b79c374dae 100644
--- a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/UpdateDatabaseTable.java
+++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/UpdateDatabaseTable.java
@@ -537,14 +537,14 @@ public class UpdateDatabaseTable extends AbstractProcessor {
                         }
 
                         final int dataType = DataTypeUtils.getSQLTypeValue(recordField.getDataType());
-                        final String quotedColumnName = enquoteIdentifier(columnName, quoteString, quoteColumnNames);
+                        final String quotedColumnName = enquoteIdentifier(s, columnName, quoteColumnNames);
                         columns.add(new ColumnDescription(quotedColumnName, dataType, required, null, recordField.isNullable()));
                         getLogger().debug("Adding column {} to table {}", columnName, tableName);
                     }
 
-                    final String quotedCatalogName = enquoteIdentifier(catalogName, quoteString, quoteTableName);
-                    final String quotedSchemaName = enquoteIdentifier(schemaName, quoteString, quoteTableName);
-                    final String quotedTableName = enquoteIdentifier(tableName, quoteString, quoteTableName);
+                    final String quotedCatalogName = enquoteIdentifier(s, catalogName, quoteTableName);
+                    final String quotedSchemaName = enquoteIdentifier(s, schemaName, quoteTableName);
+                    final String quotedTableName = enquoteIdentifier(s, tableName, quoteTableName);
                     tableSchema = new TableSchema(quotedCatalogName, quotedSchemaName, quotedTableName, columns, translateFieldNames, normalizer, primaryKeyColumnNames, quoteString);
 
                     final TableDefinition tableDefinition = getTableDefinition(tableSchema);
@@ -588,17 +588,18 @@ public class UpdateDatabaseTable extends AbstractProcessor {
                 }
 
                 if (!columnsToAdd.isEmpty()) {
-                    final List<ColumnDefinition> columnDefinitions = columnsToAdd.stream().map(columnDescription ->
-                            new StandardColumnDefinition(
-                                    enquoteIdentifier(columnDescription.getColumnName(), quoteString, quoteColumnNames),
-                                    columnDescription.getDataType(),
-                                    columnDescription.isNullable() ? ColumnDefinition.Nullable.YES : ColumnDefinition.Nullable.UNKNOWN,
-                                    columnDescription.isRequired()
-                            )
-                            )
-                            .map(ColumnDefinition.class::cast)
-                            .toList();
-                    final String qualifiedTableName = enquoteIdentifier(tableName, quoteString, quoteTableName);
+                    final List<ColumnDefinition> columnDefinitions = new ArrayList<>(columnsToAdd.size());
+                    for (final ColumnDescription columnDescription : columnsToAdd) {
+                        final ColumnDefinition columnDefinition = new StandardColumnDefinition(
+                                enquoteIdentifier(s, columnDescription.getColumnName(), quoteColumnNames),
+                                columnDescription.getDataType(),
+                                columnDescription.isNullable() ? ColumnDefinition.Nullable.YES : ColumnDefinition.Nullable.UNKNOWN,
+                                columnDescription.isRequired()
+                        );
+                        columnDefinitions.add(columnDefinition);
+                    }
+
+                    final String qualifiedTableName = enquoteIdentifier(s, tableName, quoteTableName);
                     final TableDefinition tableDefinition = new TableDefinition(Optional.empty(), Optional.empty(), qualifiedTableName, columnDefinitions);
                     final StatementRequest statementRequest = new StandardStatementRequest(StatementType.ALTER, tableDefinition);
                     final StatementResponse statementResponse = databaseDialectService.getStatement(statementRequest);
@@ -708,11 +709,18 @@ public class UpdateDatabaseTable extends AbstractProcessor {
         );
     }
 
-    private String enquoteIdentifier(final String identifier, final String quotedIdentifierString, final boolean quoteIdentifier) {
-        if (identifier != null && quoteIdentifier) {
-            return quotedIdentifierString + identifier + quotedIdentifierString;
+    private String enquoteIdentifier(final Statement statement, final String identifier, final boolean quoteIdentifier) throws SQLException {
+        final String enquoted;
+
+        if (identifier == null) {
+            enquoted = identifier;
+        } else if (quoteIdentifier) {
+            enquoted = statement.enquoteIdentifier(identifier, quoteIdentifier);
+        } else {
+            enquoted = identifier;
         }
-        return identifier;
+
+        return enquoted;
     }
 
     private static class OutputMetadataHolder {
diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestUpdateDatabaseTable.java b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestUpdateDatabaseTable.java
index 2b472e065b2..d2dd468616d 100644
--- a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestUpdateDatabaseTable.java
+++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestUpdateDatabaseTable.java
@@ -83,6 +83,32 @@ class TestUpdateDatabaseTable extends AbstractDatabaseConnectionServiceTest {
         }
     }
 
+    @Test
+    void testCreateTableIdentifierLengthExceeded() throws InitializationException {
+        final MockRecordParser recordReader = new MockRecordParser();
+        final String recordReaderId = MockRecordParser.class.getSimpleName();
+
+        // Column Name longer than 128 produces SQLException in default implementation of Statement.enquoteIdentifier()
+        final String columnName = "A".repeat(129);
+
+        recordReader.addSchemaField(new RecordField(columnName, RecordFieldType.INT.getDataType(), false));
+        recordReader.addRecord(1);
+
+        runner.addControllerService(recordReaderId, recordReader);
+        runner.enableControllerService(recordReader);
+
+        runner.setProperty(UpdateDatabaseTable.RECORD_READER, recordReaderId);
+        runner.setProperty(UpdateDatabaseTable.TABLE_NAME, "NEW_TABLE");
+        runner.setProperty(UpdateDatabaseTable.CREATE_TABLE, UpdateDatabaseTable.CREATE_IF_NOT_EXISTS);
+        runner.setProperty(UpdateDatabaseTable.QUOTE_COLUMN_IDENTIFIERS, Boolean.TRUE.toString());
+        runner.setProperty(UpdateDatabaseTable.DB_TYPE, TEST_DB_TYPE);
+
+        runner.enqueue(new byte[0]);
+        runner.run();
+
+        runner.assertAllFlowFilesTransferred(UpdateDatabaseTable.REL_FAILURE);
+    }
+
     @Test
     public void testCreateTable() throws Exception {
         MockRecordParser readerFactory = new MockRecordParser();
@@ -90,7 +116,7 @@ class TestUpdateDatabaseTable extends AbstractDatabaseConnectionServiceTest {
         readerFactory.addSchemaField(new RecordField("id", RecordFieldType.INT.getDataType(), false));
         readerFactory.addSchemaField(new RecordField("fractional", RecordFieldType.DOUBLE.getDataType(), true));
         readerFactory.addSchemaField(new RecordField("code", RecordFieldType.INT.getDataType(), 0, true));
-        readerFactory.addSchemaField(new RecordField("newField", RecordFieldType.DOUBLE.getDataType(), false));
+        readerFactory.addSchemaField(new RecordField("spaced Field", RecordFieldType.DOUBLE.getDataType(), false));
         readerFactory.addRecord(1, 1.2345, 10);
 
         runner.addControllerService("mock-reader-factory", readerFactory);
@@ -120,7 +146,7 @@ class TestUpdateDatabaseTable extends AbstractDatabaseConnectionServiceTest {
             assertColumnEquals(rs, "id", 1, "INTEGER");
             assertColumnEquals(rs, "fractional", 2, "DOUBLE PRECISION");
             assertColumnEquals(rs, "code", 3, "INTEGER");
-            assertColumnEquals(rs, "newField", 4, "DOUBLE PRECISION");
+            assertColumnEquals(rs, "spaced Field", 4, "DOUBLE PRECISION");
             assertFalse(rs.next());
         }
     }