From d10128353923ed476032a6229e829c48ecf83f53 Mon Sep 17 00:00:00 2001 From: QingweiYang Date: Wed, 15 Apr 2026 19:35:03 +0800 Subject: [PATCH] [core] Clean up field-level options when dropping columns When dropping a column that has field-level options (e.g. fields.xxx.default-value), SchemaValidation.validateFieldsPrefix() would fail because the options still reference the dropped column. This fix removes fields..* options during dropColumn in SchemaManager.generateTableSchema(). --- .../apache/paimon/schema/SchemaManager.java | 5 +++ .../paimon/schema/SchemaManagerTest.java | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/paimon-core/src/main/java/org/apache/paimon/schema/SchemaManager.java b/paimon-core/src/main/java/org/apache/paimon/schema/SchemaManager.java index 670960889d5c..09ef4f54aaa8 100644 --- a/paimon-core/src/main/java/org/apache/paimon/schema/SchemaManager.java +++ b/paimon-core/src/main/java/org/apache/paimon/schema/SchemaManager.java @@ -447,6 +447,11 @@ protected void updateLastColumn( } } }.updateIntermediateColumn(newFields, 0); + if (drop.fieldNames().length == 1) { + String droppedField = drop.fieldNames()[0]; + String prefix = FIELDS_PREFIX + "." + droppedField + "."; + newOptions.keySet().removeIf(k -> k.startsWith(prefix)); + } } else if (change instanceof UpdateColumnType) { UpdateColumnType update = (UpdateColumnType) change; assertNotUpdatingPartitionKeys(oldTableSchema, update.fieldNames(), "update"); diff --git a/paimon-core/src/test/java/org/apache/paimon/schema/SchemaManagerTest.java b/paimon-core/src/test/java/org/apache/paimon/schema/SchemaManagerTest.java index 9a15cab36159..d2560212343c 100644 --- a/paimon-core/src/test/java/org/apache/paimon/schema/SchemaManagerTest.java +++ b/paimon-core/src/test/java/org/apache/paimon/schema/SchemaManagerTest.java @@ -939,4 +939,41 @@ public void testRollbackSchemaNotExist() throws Exception { new ChangelogManager(LocalFileIO.create(), path, null))) .hasMessageContaining("Schema 999 does not exist"); } + + @Test + public void testDropColumnCleansUpFieldOptions() throws Exception { + Map tableOptions = new HashMap<>(); + tableOptions.put("fields.extra_col.default-value", "1970-01-01 00:00:00"); + tableOptions.put("key", "value"); + + List fields = + Arrays.asList( + new DataField(0, "f0", new IntType()), + new DataField(1, "f1", new BigIntType()), + new DataField(2, "f2", new VarCharType()), + new DataField(3, "extra_col", DataTypes.TIMESTAMP(0))); + Schema schemaWithFieldOptions = + new Schema( + fields, + Collections.singletonList("f0"), + Arrays.asList("f0", "f1"), + tableOptions, + ""); + + SchemaManager mgr = new SchemaManager(LocalFileIO.create(), new Path(tempDir.toString())); + TableSchema created = mgr.createTable(schemaWithFieldOptions); + + assertThat(created.options()).containsKey("fields.extra_col.default-value"); + + List changes = + Collections.singletonList(SchemaChange.dropColumn(new String[] {"extra_col"})); + assertThatCode(() -> mgr.commitChanges(changes)).doesNotThrowAnyException(); + + // Verify the column is removed and field-level options are cleaned up + TableSchema updated = mgr.latest().get(); + assertThat(updated.fieldNames()).doesNotContain("extra_col"); + assertThat(updated.options()).doesNotContainKey("fields.extra_col.default-value"); + // Other options should remain + assertThat(updated.options()).containsKey("key"); + } }