@@ -369,18 +369,77 @@ TEST_P(ManifestGroupTest, PlanFilesDropsUnselectedStatsWithEqualityDeletes) {
369369 /* sequence_number=*/ 2 , std::move (equality_delete))},
370370 partitioned_spec_);
371371
372- ICEBERG_UNWRAP_OR_FAIL (
373- auto group, ManifestGroup::Make (file_io_, schema_, GetSpecsById (), {data_manifest},
374- {delete_manifest}));
375- group->Select ({" file_path" });
372+ for (bool use_executor : {false , true }) {
373+ SCOPED_TRACE (std::format (" use_executor={}" , use_executor));
374+ for (bool use_stream : {false , true }) {
375+ SCOPED_TRACE (std::format (" use_stream={}" , use_stream));
376+ test::ThreadExecutor executor;
377+ ICEBERG_UNWRAP_OR_FAIL (auto group,
378+ ManifestGroup::Make (file_io_, schema_, GetSpecsById (),
379+ {data_manifest}, {delete_manifest}));
380+ group->Select ({" file_path" });
381+ if (use_executor) {
382+ group->PlanWith (std::ref (executor));
383+ }
384+
385+ std::vector<std::shared_ptr<FileScanTask>> tasks;
386+ if (use_stream) {
387+ ICEBERG_UNWRAP_OR_FAIL (auto stream, std::move (*group).PlanFilesStream ());
388+ ICEBERG_UNWRAP_OR_FAIL (tasks, stream->ToVector ());
389+ } else {
390+ ICEBERG_UNWRAP_OR_FAIL (tasks, std::move (*group).PlanFiles ());
391+ }
392+ ASSERT_EQ (tasks.size (), 1 );
393+ EXPECT_EQ (tasks.front ()->data_file ()->partition , part_value);
394+ ASSERT_EQ (tasks.front ()->delete_files ().size (), 1 );
395+ EXPECT_EQ (tasks.front ()->delete_files ().front ()->file_path ,
396+ " /path/to/equality-delete.parquet" );
397+ EXPECT_TRUE (tasks.front ()->data_file ()->lower_bounds .empty ());
398+ EXPECT_TRUE (tasks.front ()->data_file ()->upper_bounds .empty ());
399+ }
400+ }
401+ }
376402
377- ICEBERG_UNWRAP_OR_FAIL (auto tasks, std::move (*group).PlanFiles ());
378- ASSERT_EQ (tasks.size (), 1 );
379- ASSERT_EQ (tasks.front ()->delete_files ().size (), 1 );
380- EXPECT_EQ (tasks.front ()->delete_files ().front ()->file_path ,
381- " /path/to/equality-delete.parquet" );
382- EXPECT_TRUE (tasks.front ()->data_file ()->lower_bounds .empty ());
383- EXPECT_TRUE (tasks.front ()->data_file ()->upper_bounds .empty ());
403+ TEST_P (ManifestGroupTest, PlanFilesStreamPreservesPartitionWithPositionDeletes) {
404+ auto version = GetParam ();
405+ if (version < 2 ) {
406+ GTEST_SKIP () << " Position deletes only supported in V2+" ;
407+ }
408+
409+ constexpr int64_t kSnapshotId = 1000L ;
410+ const auto part_value = PartitionValues ({Literal::Int (0 )});
411+ auto data_manifest = WriteDataManifest (
412+ version, kSnapshotId ,
413+ {MakeEntry (ManifestStatus::kAdded , kSnapshotId , /* sequence_number=*/ 1 ,
414+ MakeDataFile (" /path/to/data.parquet" , part_value,
415+ partitioned_spec_->spec_id ()))},
416+ partitioned_spec_);
417+ auto delete_manifest = WriteDeleteManifest (
418+ version, kSnapshotId ,
419+ {MakeEntry (ManifestStatus::kAdded , kSnapshotId , /* sequence_number=*/ 2 ,
420+ MakePositionDeleteFile (" /path/to/position-delete.parquet" , part_value,
421+ partitioned_spec_->spec_id ()))},
422+ partitioned_spec_);
423+
424+ for (bool use_executor : {false , true }) {
425+ SCOPED_TRACE (std::format (" use_executor={}" , use_executor));
426+ test::ThreadExecutor executor;
427+ ICEBERG_UNWRAP_OR_FAIL (auto group,
428+ ManifestGroup::Make (file_io_, schema_, GetSpecsById (),
429+ {data_manifest}, {delete_manifest}));
430+ group->Select ({" file_path" });
431+ if (use_executor) {
432+ group->PlanWith (std::ref (executor));
433+ }
434+
435+ ICEBERG_UNWRAP_OR_FAIL (auto stream, std::move (*group).PlanFilesStream ());
436+ ICEBERG_UNWRAP_OR_FAIL (auto tasks, stream->ToVector ());
437+ ASSERT_EQ (tasks.size (), 1 );
438+ EXPECT_EQ (tasks.front ()->data_file ()->partition , part_value);
439+ ASSERT_EQ (tasks.front ()->delete_files ().size (), 1 );
440+ EXPECT_EQ (tasks.front ()->delete_files ().front ()->file_path ,
441+ " /path/to/position-delete.parquet" );
442+ }
384443}
385444
386445TEST_P (ManifestGroupTest, IgnoreDeleted) {
0 commit comments