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);
}