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 00b9d1ba5224..5161717220b0 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 @@ -559,7 +559,7 @@ private synchronized OutputMetadataHolder checkAndUpdateTableSchema(final Connec } if (!columnsToAdd.isEmpty()) { - final List alterTableSqlStatements = databaseAdapter.getAlterTableStatements(tableName, columnsToAdd, quoteTableName, quoteColumnNames); + final List alterTableSqlStatements = databaseAdapter.getAlterTableStatements(tableSchema, columnsToAdd, quoteTableName, quoteColumnNames); if (alterTableSqlStatements != null && !alterTableSqlStatements.isEmpty()) { for (String alterTableSql : alterTableSqlStatements) { diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/db/DatabaseAdapter.java b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/db/DatabaseAdapter.java index 156cd1285a8b..bc5f64cab19a 100644 --- a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/db/DatabaseAdapter.java +++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/db/DatabaseAdapter.java @@ -186,8 +186,14 @@ default String getCreateTableStatement(TableSchema tableSchema, boolean quoteTab return createTableStatement.toString(); } + default List getAlterTableStatements(TableSchema tableSchema, List columnsToAdd, boolean quoteTableName, boolean quoteColumnNames) { + String tableName = generateTableName(quoteTableName, tableSchema.getCatalogName(), tableSchema.getSchemaName(), tableSchema.getTableName(), tableSchema); + // `quoteTableName` is always passed as false, since `tableName` is already quoted by `generateTableName` if needed. We don't want to quote twice. + return getAlterTableStatements(tableName, columnsToAdd, false, quoteColumnNames); + } + default List getAlterTableStatements(String tableName, List columnsToAdd, final boolean quoteTableName, final boolean quoteColumnNames) { - StringBuilder createTableStatement = new StringBuilder(); + StringBuilder alterTableStatement = new StringBuilder(); List columnsAndDatatypes = new ArrayList<>(columnsToAdd.size()); for (ColumnDescription column : columnsToAdd) { @@ -200,7 +206,7 @@ default List getAlterTableStatements(String tableName, List getAlterTableStatements(String tableName, List attrs = new HashMap<>(); + attrs.put("db.name", "default"); + attrs.put("table.name", "persons"); + runner.enqueue(new byte[0], attrs); + runner.run(); + + runner.assertTransferCount(UpdateDatabaseTable.REL_SUCCESS, 1); + final MockFlowFile flowFile = runner.getFlowFilesForRelationship(UpdateDatabaseTable.REL_SUCCESS).get(0); + flowFile.assertAttributeEquals(UpdateDatabaseTable.ATTR_OUTPUT_TABLE, "persons"); + // Verify the table has been updated with the expected field(s) + try (Statement s = conn.createStatement()) { + // The Derby equivalent of DESCRIBE TABLE (using a query rather than the ij tool) + ResultSet rs = s.executeQuery("SELECT * FROM SYS.SYSCOLUMNS WHERE referenceid = (SELECT tableid FROM SYS.SYSTABLES WHERE tablename = 'persons') ORDER BY columnnumber"); + assertTrue(rs.next()); + // Columns 2,3,4 are Column Name, Column Index, and Column Type + assertEquals("id", rs.getString(2)); + assertEquals(1, rs.getInt(3)); + // Primary key cannot be null, Derby stores that in this column + assertEquals("INTEGER NOT NULL", rs.getString(4)); + + assertTrue(rs.next()); + assertEquals("name", rs.getString(2)); + assertEquals(2, rs.getInt(3)); + assertEquals("VARCHAR(100)", rs.getString(4)); + + assertTrue(rs.next()); + assertEquals("code", rs.getString(2)); + assertEquals(3, rs.getInt(3)); + assertEquals("INTEGER", rs.getString(4)); + + assertTrue(rs.next()); + assertEquals("NEWFIELD", rs.getString(2)); + assertEquals(4, rs.getInt(3)); + assertEquals("VARCHAR(100)", rs.getString(4)); + + // No more rows + assertFalse(rs.next()); + } + } + } /** * Simple implementation only for testing purposes