This is an automated email from the ASF dual-hosted git repository.
etudenhoefner pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg.git
The following commit(s) were added to refs/heads/main by this push:
new c75efa9c32 Core: Fix metadata table scans with useRef by preserving
metadata schema (#15276)
c75efa9c32 is described below
commit c75efa9c32d85bc1c804a3909a28048fc70c6833
Author: Rui Li <[email protected]>
AuthorDate: Tue Feb 10 21:15:24 2026 +0800
Core: Fix metadata table scans with useRef by preserving metadata schema
(#15276)
---
.../main/java/org/apache/iceberg/SnapshotScan.java | 3 +-
.../org/apache/iceberg/TestMetadataTableScans.java | 76 ++++++++++++++++++++++
2 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/core/src/main/java/org/apache/iceberg/SnapshotScan.java
b/core/src/main/java/org/apache/iceberg/SnapshotScan.java
index 8dd1e7df20..655c4c72e2 100644
--- a/core/src/main/java/org/apache/iceberg/SnapshotScan.java
+++ b/core/src/main/java/org/apache/iceberg/SnapshotScan.java
@@ -124,7 +124,8 @@ public abstract class SnapshotScan<ThisT, T extends
ScanTask, G extends ScanTask
Snapshot snapshot = table().snapshot(name);
Preconditions.checkArgument(snapshot != null, "Cannot find ref %s", name);
TableScanContext newContext =
context().useSnapshotId(snapshot.snapshotId());
- return newRefinedScan(table(), SnapshotUtil.schemaFor(table(), name),
newContext);
+ Schema newSchema = useSnapshotSchema() ? SnapshotUtil.schemaFor(table(),
name) : tableSchema();
+ return newRefinedScan(table(), newSchema, newContext);
}
public ThisT asOfTime(long timestampMillis) {
diff --git a/core/src/test/java/org/apache/iceberg/TestMetadataTableScans.java
b/core/src/test/java/org/apache/iceberg/TestMetadataTableScans.java
index 4d2971c7f1..210dfb3683 100644
--- a/core/src/test/java/org/apache/iceberg/TestMetadataTableScans.java
+++ b/core/src/test/java/org/apache/iceberg/TestMetadataTableScans.java
@@ -1752,6 +1752,82 @@ public class TestMetadataTableScans extends
MetadataTableScanTestBase {
assertEstimatedRowCount(new AllEntriesTable(table), 4);
}
+ @TestTemplate
+ public void testMetadataTableScansOnBranch() throws IOException {
+ table.newFastAppend().appendFile(FILE_A).commit();
+ table.manageSnapshots().createBranch("testBranch").commit();
+ table.newFastAppend().appendFile(FILE_B).commit();
+
+ Table entriesTable = new ManifestEntriesTable(table);
+ assertThat(
+ rowCount(
+ entriesTable
+ .newScan()
+ .useRef("testBranch")
+ .select("status")
+
.filter(Expressions.lessThan("data_file.partition.data_bucket", 0))))
+ .as("ManifestEntriesTable on branch should have no entry satisfying
the filter")
+ .isEqualTo(0);
+ assertThat(rowCount(entriesTable.newScan()))
+ .as("ManifestEntriesTable on main should have 2 entries")
+ .isEqualTo(2);
+
+ Table dataFilesTable = new DataFilesTable(table);
+ assertThat(rowCount(dataFilesTable.newScan().useRef("testBranch")))
+ .as("DataFilesTable on branch should have 1 file")
+ .isEqualTo(1);
+ assertThat(rowCount(dataFilesTable.newScan()))
+ .as("DataFilesTable on main should have 2 files")
+ .isEqualTo(2);
+
+ Table manifestsTable = new ManifestsTable(table);
+ assertThat(rowCount(manifestsTable.newScan().useRef("testBranch")))
+ .as("ManifestsTable on branch should have 1 manifest")
+ .isEqualTo(1);
+ assertThat(rowCount(manifestsTable.newScan()))
+ .as("ManifestsTable on main should have 2 manifests")
+ .isEqualTo(2);
+
+ Table filesTable = new FilesTable(table);
+ assertThat(rowCount(filesTable.newScan().useRef("testBranch")))
+ .as("FilesTable on branch should have 1 file")
+ .isEqualTo(1);
+ assertThat(rowCount(filesTable.newScan()))
+ .as("FilesTable on main should have 2 files")
+ .isEqualTo(2);
+ }
+
+ @TestTemplate
+ public void testDeleteFilesTableScanOnBranch() throws IOException {
+ assumeThat(formatVersion).as("Delete files are not supported by V1
Tables").isGreaterThan(1);
+
+ table.newFastAppend().appendFile(FILE_A).commit();
+ table.newRowDelta().addDeletes(fileADeletes()).commit();
+ table.manageSnapshots().createBranch("testBranch").commit();
+ table.newFastAppend().appendFile(FILE_B).commit();
+ table.newRowDelta().addDeletes(fileBDeletes()).commit();
+
+ Table deleteFilesTable = new DeleteFilesTable(table);
+ assertThat(rowCount(deleteFilesTable.newScan().useRef("testBranch")))
+ .as("DeleteFilesTable on branch should have 1 delete file")
+ .isEqualTo(1);
+ assertThat(rowCount(deleteFilesTable.newScan()))
+ .as("DeleteFilesTable on main should have 2 delete files")
+ .isEqualTo(2);
+ }
+
+ private int rowCount(TableScan scan) throws IOException {
+ int count = 0;
+ try (CloseableIterable<FileScanTask> tasks = scan.planFiles()) {
+ for (FileScanTask task : tasks) {
+ try (CloseableIterable<StructLike> rows = task.asDataTask().rows()) {
+ count += Iterators.size(rows.iterator());
+ }
+ }
+ }
+ return count;
+ }
+
private void assertEstimatedRowCount(Table metadataTable, int size) throws
Exception {
TableScan scan = metadataTable.newScan();