@@ -639,6 +639,31 @@ Result<std::vector<std::shared_ptr<FileScanTask>>> DataTableScan::PlanFiles() co
639639 return manifest_group->PlanFiles ();
640640}
641641
642+ // Friend function template for IncrementalScan that implements the shared PlanFiles
643+ // logic. It resolves the from/to snapshot range from the scan context and delegates
644+ // to the two-arg virtual PlanFiles() override in the concrete subclass.
645+ // Defined as a friend to access the protected two-arg PlanFiles().
646+ template <typename ScanTaskType>
647+ Result<std::vector<std::shared_ptr<ScanTaskType>>> PlanFiles (
648+ const IncrementalScan<ScanTaskType>& scan) {
649+ if (IsScanCurrentLineage (scan.context ())) {
650+ ICEBERG_ASSIGN_OR_RAISE (auto current_snapshot, scan.metadata ()->Snapshot ());
651+ if (current_snapshot == nullptr ) {
652+ return std::vector<std::shared_ptr<ScanTaskType>>{};
653+ }
654+ }
655+
656+ ICEBERG_ASSIGN_OR_RAISE (
657+ int64_t to_snapshot_id_inclusive,
658+ internal::ToSnapshotIdInclusive (scan.context (), *scan.metadata ()));
659+ ICEBERG_ASSIGN_OR_RAISE (
660+ std::optional<int64_t > from_snapshot_id_exclusive,
661+ internal::FromSnapshotIdExclusive (scan.context (), *scan.metadata (),
662+ to_snapshot_id_inclusive));
663+
664+ return scan.PlanFiles (from_snapshot_id_exclusive, to_snapshot_id_inclusive);
665+ }
666+
642667// IncrementalAppendScan implementation
643668
644669Result<std::unique_ptr<IncrementalAppendScan>> IncrementalAppendScan::Make (
@@ -651,6 +676,11 @@ Result<std::unique_ptr<IncrementalAppendScan>> IncrementalAppendScan::Make(
651676 std::move (metadata), std::move (schema), std::move (io), std::move (context)));
652677}
653678
679+ Result<std::vector<std::shared_ptr<FileScanTask>>> IncrementalAppendScan::PlanFiles ()
680+ const {
681+ return PlanFiles<FileScanTask>(*this );
682+ }
683+
654684Result<std::vector<std::shared_ptr<FileScanTask>>> IncrementalAppendScan::PlanFiles (
655685 std::optional<int64_t > from_snapshot_id_exclusive,
656686 int64_t to_snapshot_id_inclusive) const {
@@ -725,35 +755,15 @@ Result<std::unique_ptr<IncrementalChangelogScan>> IncrementalChangelogScan::Make
725755 return NotImplemented (" IncrementalChangelogScan is not implemented" );
726756}
727757
758+ Result<std::vector<std::shared_ptr<ChangelogScanTask>>>
759+ IncrementalChangelogScan::PlanFiles () const {
760+ return PlanFiles<ChangelogScanTask>(*this );
761+ }
762+
728763Result<std::vector<std::shared_ptr<ChangelogScanTask>>>
729764IncrementalChangelogScan::PlanFiles (std::optional<int64_t > from_snapshot_id_exclusive,
730765 int64_t to_snapshot_id_inclusive) const {
731766 return NotImplemented (" IncrementalChangelogScan::PlanFiles is not implemented" );
732767}
733768
734- // Explicit template implementations for IncrementalScan
735- // This moves the template implementation from header to source file
736- template <typename ScanTaskType>
737- Result<std::vector<std::shared_ptr<ScanTaskType>>>
738- IncrementalScan<ScanTaskType>::PlanFiles() const {
739- if (IsScanCurrentLineage (context_)) {
740- ICEBERG_ASSIGN_OR_RAISE (auto current_snapshot, metadata_->Snapshot ());
741- if (current_snapshot == nullptr ) {
742- return std::vector<std::shared_ptr<ScanTaskType>>{};
743- }
744- }
745-
746- ICEBERG_ASSIGN_OR_RAISE (int64_t to_snapshot_id_inclusive,
747- internal::ToSnapshotIdInclusive (context_, *metadata_));
748- ICEBERG_ASSIGN_OR_RAISE (
749- std::optional<int64_t > from_snapshot_id_exclusive,
750- internal::FromSnapshotIdExclusive (context_, *metadata_, to_snapshot_id_inclusive));
751-
752- return PlanFiles (from_snapshot_id_exclusive, to_snapshot_id_inclusive);
753- }
754-
755- // Explicitly instantiate the templates
756- template class IncrementalScan <FileScanTask>;
757- template class IncrementalScan <ChangelogScanTask>;
758-
759769} // namespace iceberg
0 commit comments