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 69caca0ecf API, Core: Use Supplier for FileIO on Scan (#15646)
69caca0ecf is described below

commit 69caca0ecfe1b2f4a60b4164c24ea65853c23857
Author: Eduard Tudenhoefner <[email protected]>
AuthorDate: Wed Mar 18 09:38:02 2026 +0100

    API, Core: Use Supplier for FileIO on Scan (#15646)
---
 api/src/main/java/org/apache/iceberg/BatchScan.java       |  5 +++--
 .../main/java/org/apache/iceberg/BatchScanAdapter.java    |  5 +++--
 api/src/main/java/org/apache/iceberg/Scan.java            |  5 +++--
 core/src/main/java/org/apache/iceberg/BaseScan.java       | 13 +++++++++++--
 .../main/java/org/apache/iceberg/rest/RESTTableScan.java  | 11 +++++++----
 .../org/apache/iceberg/rest/TestRESTScanPlanning.java     | 15 +++++++++------
 6 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/api/src/main/java/org/apache/iceberg/BatchScan.java 
b/api/src/main/java/org/apache/iceberg/BatchScan.java
index bd53fe97a3..76577eee02 100644
--- a/api/src/main/java/org/apache/iceberg/BatchScan.java
+++ b/api/src/main/java/org/apache/iceberg/BatchScan.java
@@ -18,6 +18,7 @@
  */
 package org.apache.iceberg;
 
+import java.util.function.Supplier;
 import org.apache.iceberg.io.FileIO;
 
 /** API for configuring a batch scan. */
@@ -73,7 +74,7 @@ public interface BatchScan extends Scan<BatchScan, ScanTask, 
ScanTaskGroup<ScanT
 
   /** Returns the {@link FileIO} instance to use when reading data files for 
this scan. */
   @Override
-  default FileIO io() {
-    return table().io();
+  default Supplier<FileIO> fileIO() {
+    return table()::io;
   }
 }
diff --git a/api/src/main/java/org/apache/iceberg/BatchScanAdapter.java 
b/api/src/main/java/org/apache/iceberg/BatchScanAdapter.java
index cccd1cd162..8af1144dec 100644
--- a/api/src/main/java/org/apache/iceberg/BatchScanAdapter.java
+++ b/api/src/main/java/org/apache/iceberg/BatchScanAdapter.java
@@ -20,6 +20,7 @@ package org.apache.iceberg;
 
 import java.util.Collection;
 import java.util.concurrent.ExecutorService;
+import java.util.function.Supplier;
 import org.apache.iceberg.expressions.Expression;
 import org.apache.iceberg.io.CloseableIterable;
 import org.apache.iceberg.io.FileIO;
@@ -40,8 +41,8 @@ public class BatchScanAdapter implements BatchScan {
   }
 
   @Override
-  public FileIO io() {
-    return scan.io();
+  public Supplier<FileIO> fileIO() {
+    return scan.fileIO();
   }
 
   @Override
diff --git a/api/src/main/java/org/apache/iceberg/Scan.java 
b/api/src/main/java/org/apache/iceberg/Scan.java
index 4bd7717fd1..e3c6849501 100644
--- a/api/src/main/java/org/apache/iceberg/Scan.java
+++ b/api/src/main/java/org/apache/iceberg/Scan.java
@@ -20,6 +20,7 @@ package org.apache.iceberg;
 
 import java.util.Collection;
 import java.util.concurrent.ExecutorService;
+import java.util.function.Supplier;
 import org.apache.iceberg.expressions.Expression;
 import org.apache.iceberg.io.CloseableIterable;
 import org.apache.iceberg.io.FileIO;
@@ -211,7 +212,7 @@ public interface Scan<ThisT, T extends ScanTask, G extends 
ScanTaskGroup<T>> {
   }
 
   /** Returns the {@link FileIO} instance to use when reading data files for 
this scan. */
-  default FileIO io() {
-    throw new UnsupportedOperationException("io() is not implemented: added in 
1.11.0");
+  default Supplier<FileIO> fileIO() {
+    throw new UnsupportedOperationException("fileIO() is not implemented: 
added in 1.11.0");
   }
 }
diff --git a/core/src/main/java/org/apache/iceberg/BaseScan.java 
b/core/src/main/java/org/apache/iceberg/BaseScan.java
index 53f3782b38..242a5aaacc 100644
--- a/core/src/main/java/org/apache/iceberg/BaseScan.java
+++ b/core/src/main/java/org/apache/iceberg/BaseScan.java
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import org.apache.iceberg.expressions.Binder;
 import org.apache.iceberg.expressions.Expression;
@@ -102,11 +103,19 @@ abstract class BaseScan<ThisT, T extends ScanTask, G 
extends ScanTaskGroup<T>>
     return table;
   }
 
-  @Override
-  public FileIO io() {
+  /**
+   * @deprecated since 1.11.0, will be removed in 1.12.0; use {@link 
BaseScan#fileIO()} instead.
+   */
+  @Deprecated
+  protected FileIO io() {
     return table.io();
   }
 
+  @Override
+  public Supplier<FileIO> fileIO() {
+    return table::io;
+  }
+
   protected Schema tableSchema() {
     return schema;
   }
diff --git a/core/src/main/java/org/apache/iceberg/rest/RESTTableScan.java 
b/core/src/main/java/org/apache/iceberg/rest/RESTTableScan.java
index 5eaa4c2f27..1adfb17c9f 100644
--- a/core/src/main/java/org/apache/iceberg/rest/RESTTableScan.java
+++ b/core/src/main/java/org/apache/iceberg/rest/RESTTableScan.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import org.apache.iceberg.CatalogProperties;
 import org.apache.iceberg.CatalogUtil;
@@ -129,10 +130,12 @@ class RESTTableScan extends DataTableScan {
   }
 
   @Override
-  public FileIO io() {
-    Preconditions.checkState(
-        null != scanFileIO, "FileIO is not available: planFiles() must be 
called first");
-    return scanFileIO;
+  public Supplier<FileIO> fileIO() {
+    return () -> {
+      Preconditions.checkState(
+          null != scanFileIO, "FileIO is not available: planFiles() must be 
called first");
+      return scanFileIO;
+    };
   }
 
   @Override
diff --git 
a/core/src/test/java/org/apache/iceberg/rest/TestRESTScanPlanning.java 
b/core/src/test/java/org/apache/iceberg/rest/TestRESTScanPlanning.java
index cdde30abe0..206ff61945 100644
--- a/core/src/test/java/org/apache/iceberg/rest/TestRESTScanPlanning.java
+++ b/core/src/test/java/org/apache/iceberg/rest/TestRESTScanPlanning.java
@@ -1093,18 +1093,20 @@ public class TestRESTScanPlanning extends 
TestBaseWithRESTServer {
     
assertThat(table.io().properties()).doesNotContainKey(RESTCatalogProperties.REST_SCAN_PLAN_ID);
 
     TableScan tableScan = table.newScan();
-    assertThatThrownBy(tableScan::io)
+    assertThatThrownBy(() -> tableScan.fileIO().get())
         .isInstanceOf(IllegalStateException.class)
         .hasMessage("FileIO is not available: planFiles() must be called 
first");
 
     // make sure remote scan planning is called and FileIO gets the planId
     assertThat(tableScan.planFiles()).hasSize(1);
     
assertThat(table.io().properties()).doesNotContainKey(RESTCatalogProperties.REST_SCAN_PLAN_ID);
-    
assertThat(tableScan.io().properties()).containsKey(RESTCatalogProperties.REST_SCAN_PLAN_ID);
-    String planId = 
tableScan.io().properties().get(RESTCatalogProperties.REST_SCAN_PLAN_ID);
+    assertThat(tableScan.fileIO().get().properties())
+        .containsKey(RESTCatalogProperties.REST_SCAN_PLAN_ID);
+    String planId =
+        
tableScan.fileIO().get().properties().get(RESTCatalogProperties.REST_SCAN_PLAN_ID);
 
     TableScan newScan = table.newScan();
-    assertThatThrownBy(newScan::io)
+    assertThatThrownBy(() -> newScan.fileIO().get())
         .isInstanceOf(IllegalStateException.class)
         .hasMessage("FileIO is not available: planFiles() must be called 
first");
 
@@ -1113,8 +1115,9 @@ public class TestRESTScanPlanning extends 
TestBaseWithRESTServer {
     
assertThat(table.io().properties()).doesNotContainKey(RESTCatalogProperties.REST_SCAN_PLAN_ID);
 
     // make sure planIds are different for each scan
-    
assertThat(newScan.io().properties()).containsKey(RESTCatalogProperties.REST_SCAN_PLAN_ID);
-    
assertThat(newScan.io().properties().get(RESTCatalogProperties.REST_SCAN_PLAN_ID))
+    assertThat(newScan.fileIO().get().properties())
+        .containsKey(RESTCatalogProperties.REST_SCAN_PLAN_ID);
+    
assertThat(newScan.fileIO().get().properties().get(RESTCatalogProperties.REST_SCAN_PLAN_ID))
         .isNotEqualTo(planId);
   }
 

Reply via email to