This is an automated email from the ASF dual-hosted git repository. huaxingao pushed a commit to branch 1.10.x in repository https://gitbox.apache.org/repos/asf/iceberg.git
commit 0462b03cc354cef7db256cd6543873b3415edae7 Author: Yubo Xu <[email protected]> AuthorDate: Tue Sep 30 08:50:19 2025 -0700 Core: Handle unpartitioned check for a spec with all void transforms in replace partitions (#14186) (cherry picked from commit 00d18e38feb5439f715ee3c13e206e9445ed2faa) --- .../org/apache/iceberg/BaseReplacePartitions.java | 2 +- .../org/apache/iceberg/TestReplacePartitions.java | 53 ++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/apache/iceberg/BaseReplacePartitions.java b/core/src/main/java/org/apache/iceberg/BaseReplacePartitions.java index 04611f50f1..892257b51b 100644 --- a/core/src/main/java/org/apache/iceberg/BaseReplacePartitions.java +++ b/core/src/main/java/org/apache/iceberg/BaseReplacePartitions.java @@ -111,7 +111,7 @@ public class BaseReplacePartitions extends MergingSnapshotProducer<ReplacePartit @Override public List<ManifestFile> apply(TableMetadata base, Snapshot snapshot) { - if (dataSpec().fields().isEmpty()) { + if (dataSpec().isUnpartitioned()) { // replace all data in an unpartitioned table deleteByRowFilter(Expressions.alwaysTrue()); } diff --git a/core/src/test/java/org/apache/iceberg/TestReplacePartitions.java b/core/src/test/java/org/apache/iceberg/TestReplacePartitions.java index 29daeb995c..abc27cddd6 100644 --- a/core/src/test/java/org/apache/iceberg/TestReplacePartitions.java +++ b/core/src/test/java/org/apache/iceberg/TestReplacePartitions.java @@ -102,6 +102,23 @@ public class TestReplacePartitions extends TestBase { .withRecordCount(1) .build(); + static final PartitionSpec SPEC_ALL_VOID = + PartitionSpec.builderFor(SCHEMA).alwaysNull("id").alwaysNull("data").build(); + + static final DataFile FILE_ALL_VOID_UNPARTITIONED_A = + DataFiles.builder(SPEC_ALL_VOID) + .withPath("/path/to/data-all-void-unpartitioned-a.parquet") + .withFileSizeInBytes(10) + .withRecordCount(1) + .build(); + + static final DataFile FILE_ALL_VOID_UNPARTITIONED_B = + DataFiles.builder(SPEC_ALL_VOID) + .withPath("/path/to/data-all-void-unpartitioned-b.parquet") + .withFileSizeInBytes(10) + .withRecordCount(1) + .build(); + @Parameter(index = 1) private String branch; @@ -198,6 +215,42 @@ public class TestReplacePartitions extends TestBase { statuses(Status.DELETED)); } + @TestTemplate + public void testReplaceAllVoidUnpartitionedTable() { + Table tableVoid = + TestTables.create(tableDir, "allvoidUnpartitioned", SCHEMA, SPEC_ALL_VOID, formatVersion); + + commit(tableVoid, tableVoid.newAppend().appendFile(FILE_ALL_VOID_UNPARTITIONED_A), branch); + validateSnapshot( + null, + latestSnapshot(TestTables.readMetadata("allvoidUnpartitioned"), branch), + FILE_ALL_VOID_UNPARTITIONED_A); + + ReplacePartitions replacePartitions = + tableVoid.newReplacePartitions().addFile(FILE_ALL_VOID_UNPARTITIONED_B); + commit(tableVoid, replacePartitions, branch); + + assertThat(TestTables.metadataVersion("allvoidUnpartitioned")).isEqualTo(2); + TableMetadata replaceMetadata = TestTables.readMetadata("allvoidUnpartitioned"); + long replaceId = latestSnapshot(replaceMetadata, branch).snapshotId(); + List<ManifestFile> manifestFiles = + latestSnapshot(replaceMetadata, branch).allManifests(tableVoid.io()); + + assertThat(manifestFiles).hasSize(2); + + validateManifestEntries( + manifestFiles.get(0), + ids(replaceId), + files(FILE_ALL_VOID_UNPARTITIONED_B), + statuses(Status.ADDED)); + + validateManifestEntries( + manifestFiles.get(1), + ids(replaceId), + files(FILE_ALL_VOID_UNPARTITIONED_A), + statuses(Status.DELETED)); + } + @TestTemplate public void testReplaceAndMergeWithUnpartitionedTable() throws IOException { Table unpartitioned =
