@@ -139,14 +139,14 @@ class TestMergeAppend : public MergingSnapshotUpdate {
139139 return MergingSnapshotUpdate::ValidateDeletedDataFiles (
140140 metadata, starting_snapshot_id, partition_set, parent, std::move (io));
141141 }
142- static Status ValidateAddedDVsForTest (const TableMetadata& metadata,
143- int64_t starting_snapshot_id,
144- std::shared_ptr<Expression> conflict_filter,
145- const std::shared_ptr<Snapshot >& parent ,
146- std::shared_ptr<FileIO> io) {
147- return MergingSnapshotUpdate::ValidateAddedDVs (metadata, starting_snapshot_id,
148- std::move (conflict_filter), parent ,
149- std::move (io));
142+ static Status ValidateAddedDVsForTest (
143+ const TableMetadata& metadata, int64_t starting_snapshot_id,
144+ std::shared_ptr<Expression> conflict_filter,
145+ const std::unordered_set<std::string >& referenced_data_files ,
146+ const std::shared_ptr<Snapshot>& parent, std::shared_ptr<FileIO> io) {
147+ return MergingSnapshotUpdate::ValidateAddedDVs (
148+ metadata, starting_snapshot_id, std::move (conflict_filter), referenced_data_files ,
149+ parent, std::move (io));
150150 }
151151
152152 bool HasDataFiles () const { return AddsDataFiles (); }
@@ -371,8 +371,8 @@ TEST_F(MergingSnapshotUpdateTest, CommitNewDataFile) {
371371
372372 EXPECT_THAT (table_->Refresh (), IsOk ());
373373 ICEBERG_UNWRAP_OR_FAIL (auto snapshot, table_->current_snapshot ());
374- EXPECT_EQ (snapshot->summary .at (" added-data-files " ), " 1" );
375- EXPECT_EQ (snapshot->summary .at (" added-records " ), " 100" );
374+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kAddedDataFiles ), " 1" );
375+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kAddedRecords ), " 100" );
376376}
377377
378378TEST_F (MergingSnapshotUpdateTest, CommitMultipleDataFiles) {
@@ -383,8 +383,8 @@ TEST_F(MergingSnapshotUpdateTest, CommitMultipleDataFiles) {
383383
384384 EXPECT_THAT (table_->Refresh (), IsOk ());
385385 ICEBERG_UNWRAP_OR_FAIL (auto snapshot, table_->current_snapshot ());
386- EXPECT_EQ (snapshot->summary .at (" added-data-files " ), " 2" );
387- EXPECT_EQ (snapshot->summary .at (" added-records " ), " 200" );
386+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kAddedDataFiles ), " 2" );
387+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kAddedRecords ), " 200" );
388388}
389389
390390TEST_F (MergingSnapshotUpdateTest, CommitDataFileAndDeleteFile) {
@@ -398,7 +398,7 @@ TEST_F(MergingSnapshotUpdateTest, CommitDataFileAndDeleteFile) {
398398 EXPECT_THAT (table_->Refresh (), IsOk ());
399399 ICEBERG_UNWRAP_OR_FAIL (auto snapshot, table_->current_snapshot ());
400400 // Data file summary
401- EXPECT_EQ (snapshot->summary .at (" added-data-files " ), " 1" );
401+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kAddedDataFiles ), " 1" );
402402}
403403
404404TEST_F (MergingSnapshotUpdateTest, CommitPreservesExistingManifests) {
@@ -413,7 +413,7 @@ TEST_F(MergingSnapshotUpdateTest, CommitPreservesExistingManifests) {
413413 EXPECT_THAT (table_->Refresh (), IsOk ());
414414 ICEBERG_UNWRAP_OR_FAIL (auto snapshot, table_->current_snapshot ());
415415 // Both data files should be visible — 1 existing + 1 new
416- EXPECT_EQ (snapshot->summary .at (" total-data-files " ), " 2" );
416+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kTotalDataFiles ), " 2" );
417417}
418418
419419TEST_F (MergingSnapshotUpdateTest, CommitDeletesDataFile) {
@@ -426,8 +426,8 @@ TEST_F(MergingSnapshotUpdateTest, CommitDeletesDataFile) {
426426
427427 EXPECT_THAT (table_->Refresh (), IsOk ());
428428 ICEBERG_UNWRAP_OR_FAIL (auto snapshot, table_->current_snapshot ());
429- EXPECT_EQ (snapshot->summary .at (" total-data-files " ), " 0" );
430- EXPECT_EQ (snapshot->summary .at (" deleted-data-files " ), " 1" );
429+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kTotalDataFiles ), " 0" );
430+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kDeletedDataFiles ), " 1" );
431431}
432432
433433TEST_F (MergingSnapshotUpdateTest, SetNewDataFilesDataSequenceNumber) {
@@ -438,7 +438,19 @@ TEST_F(MergingSnapshotUpdateTest, SetNewDataFilesDataSequenceNumber) {
438438
439439 EXPECT_THAT (table_->Refresh (), IsOk ());
440440 ICEBERG_UNWRAP_OR_FAIL (auto snapshot, table_->current_snapshot ());
441- EXPECT_EQ (snapshot->summary .at (" added-data-files" ), " 1" );
441+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields::kAddedDataFiles ), " 1" );
442+ }
443+
444+ TEST_F (MergingSnapshotUpdateTest, CustomSummaryPropertySurvivesApplyRebuild) {
445+ ICEBERG_UNWRAP_OR_FAIL (auto op, NewMergeAppend ());
446+ op->Set (" custom-prop" , " custom-value" );
447+ EXPECT_THAT (op->AddFile (file_a_), IsOk ());
448+ EXPECT_THAT (op->Commit (), IsOk ());
449+
450+ EXPECT_THAT (table_->Refresh (), IsOk ());
451+ ICEBERG_UNWRAP_OR_FAIL (auto snapshot, table_->current_snapshot ());
452+ EXPECT_EQ (snapshot->summary .at (" custom-prop" ), " custom-value" );
453+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields::kAddedDataFiles ), " 1" );
442454}
443455
444456// -------------------------------------------------------------------------
@@ -694,8 +706,8 @@ TEST_F(MergingSnapshotUpdateTest, AppendManifestEmptyTable) {
694706 ICEBERG_UNWRAP_OR_FAIL (auto data_manifests, snapshot_cache.DataManifests (file_io_));
695707 ASSERT_EQ (data_manifests.size (), 1 );
696708
697- EXPECT_EQ (snapshot->summary .at (" added-data-files " ), " 2" );
698- EXPECT_EQ (snapshot->summary .at (" total-data-files " ), " 2" );
709+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kAddedDataFiles ), " 2" );
710+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kTotalDataFiles ), " 2" );
699711}
700712
701713TEST_F (MergingSnapshotUpdateTest, AppendManifestWithDataFiles) {
@@ -714,7 +726,7 @@ TEST_F(MergingSnapshotUpdateTest, AppendManifestWithDataFiles) {
714726 ICEBERG_UNWRAP_OR_FAIL (auto data_manifests, snapshot_cache.DataManifests (file_io_));
715727 // Written manifest (file_b_) + appended manifest (file_a_, file_b_)
716728 EXPECT_EQ (data_manifests.size (), 2 );
717- EXPECT_EQ (snapshot->summary .at (" added-data-files " ), " 3" );
729+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kAddedDataFiles ), " 3" );
718730}
719731
720732// -------------------------------------------------------------------------
@@ -742,7 +754,7 @@ TEST_F(MergingSnapshotUpdateTest, AppendManifestMergeWithMinCountOne) {
742754 ICEBERG_UNWRAP_OR_FAIL (auto data_manifests, snapshot_cache.DataManifests (file_io_));
743755 // Both manifests merged into one.
744756 EXPECT_EQ (data_manifests.size (), 1 );
745- EXPECT_EQ (snapshot->summary .at (" added-data-files " ), " 3" );
757+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kAddedDataFiles ), " 3" );
746758}
747759
748760TEST_F (MergingSnapshotUpdateTest, AppendManifestDoNotMergeMinCount) {
@@ -772,7 +784,7 @@ TEST_F(MergingSnapshotUpdateTest, AppendManifestDoNotMergeMinCount) {
772784 ICEBERG_UNWRAP_OR_FAIL (auto data_manifests, snapshot_cache.DataManifests (file_io_));
773785 // Below min-count-to-merge threshold — all 3 pass through unchanged.
774786 EXPECT_EQ (data_manifests.size (), 3 );
775- EXPECT_EQ (snapshot->summary .at (" added-data-files " ), " 3" );
787+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kAddedDataFiles ), " 3" );
776788}
777789
778790// -------------------------------------------------------------------------
@@ -799,7 +811,7 @@ TEST_F(MergingSnapshotUpdateTest, ManifestMergeMergesIntoOne) {
799811 SnapshotCache snapshot_cache (snapshot.get ());
800812 ICEBERG_UNWRAP_OR_FAIL (auto data_manifests, snapshot_cache.DataManifests (file_io_));
801813 EXPECT_EQ (data_manifests.size (), 1 );
802- EXPECT_EQ (snapshot->summary .at (" total-data-files " ), " 2" );
814+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kTotalDataFiles ), " 2" );
803815 EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields::kManifestsReplaced ), " 1" );
804816}
805817
@@ -816,7 +828,7 @@ TEST_F(MergingSnapshotUpdateTest, ManifestMergeDoesNotMergeWhenBelowMinCount) {
816828 SnapshotCache snapshot_cache (snapshot.get ());
817829 ICEBERG_UNWRAP_OR_FAIL (auto data_manifests, snapshot_cache.DataManifests (file_io_));
818830 EXPECT_EQ (data_manifests.size (), 2 );
819- EXPECT_EQ (snapshot->summary .at (" total-data-files " ), " 2" );
831+ EXPECT_EQ (snapshot->summary .at (SnapshotSummaryFields:: kTotalDataFiles ), " 2" );
820832}
821833
822834TEST_F (MergingSnapshotUpdateTest, ManifestMergeDoesNotMergeWhenSizeTargetTooSmall) {
@@ -1147,12 +1159,51 @@ TEST_F(MergingSnapshotUpdateTest, ValidateAddedDVsDetectsConflict) {
11471159 metadata->current_snapshot_id = second_snapshot->snapshot_id ;
11481160 metadata->last_sequence_number = second_snapshot->sequence_number ;
11491161
1162+ const std::unordered_set<std::string> referenced_data_files{file_a_->file_path };
11501163 EXPECT_THAT (TestMergeAppend::ValidateAddedDVsForTest (
11511164 *metadata, first_snapshot->snapshot_id , Expressions::AlwaysTrue (),
1152- second_snapshot, file_io_),
1165+ referenced_data_files, second_snapshot, file_io_),
11531166 IsError (ErrorKind::kInvalidArgument ));
11541167}
11551168
1169+ TEST_F (MergingSnapshotUpdateTest, ValidateAddedDVsIgnoresUnrelatedDVs) {
1170+ CommitFileA ();
1171+ ICEBERG_UNWRAP_OR_FAIL (auto first_snapshot, table_->current_snapshot ());
1172+
1173+ auto metadata = std::make_shared<TableMetadata>(*table_->metadata ());
1174+ metadata->format_version = 3 ;
1175+
1176+ auto dv_file = MakeDeleteFile (" /delete/dv_a.puffin" , 1L );
1177+ dv_file->file_format = FileFormatType::kPuffin ;
1178+ dv_file->referenced_data_file = file_a_->file_path ;
1179+ dv_file->content_offset = 0 ;
1180+ dv_file->content_size_in_bytes = 10 ;
1181+
1182+ constexpr int64_t kSecondSnapshotId = 123456 ;
1183+ auto manifest_path = table_location_ + " /metadata/dv-unrelated.avro" ;
1184+ ICEBERG_UNWRAP_OR_FAIL (auto manifest,
1185+ WriteDeleteManifest (*metadata, manifest_path, {dv_file},
1186+ first_snapshot->sequence_number + 1 ));
1187+ manifest.added_snapshot_id = kSecondSnapshotId ;
1188+ manifest.sequence_number = first_snapshot->sequence_number + 1 ;
1189+ manifest.min_sequence_number = first_snapshot->sequence_number + 1 ;
1190+ ICEBERG_UNWRAP_OR_FAIL (
1191+ auto second_snapshot,
1192+ MakeSyntheticSnapshot (DataOperation::kOverwrite , kSecondSnapshotId ,
1193+ first_snapshot->snapshot_id ,
1194+ first_snapshot->sequence_number + 1 , {manifest}));
1195+
1196+ metadata->snapshots .push_back (second_snapshot);
1197+ metadata->current_snapshot_id = second_snapshot->snapshot_id ;
1198+ metadata->last_sequence_number = second_snapshot->sequence_number ;
1199+
1200+ const std::unordered_set<std::string> referenced_data_files{file_b_->file_path };
1201+ EXPECT_THAT (TestMergeAppend::ValidateAddedDVsForTest (
1202+ *metadata, first_snapshot->snapshot_id , Expressions::AlwaysTrue (),
1203+ referenced_data_files, second_snapshot, file_io_),
1204+ IsOk ());
1205+ }
1206+
11561207TEST_F (MergingSnapshotUpdateTest, ValidateDeletedDataFilesWithExpressionDetectsConflict) {
11571208 CommitFileA ();
11581209 ICEBERG_UNWRAP_OR_FAIL (auto first_snapshot, table_->current_snapshot ());
0 commit comments