2929#include " iceberg/catalog/rest/http_client.h"
3030#include " iceberg/catalog/rest/json_serde_internal.h"
3131#include " iceberg/catalog/rest/resource_paths.h"
32+ #include " iceberg/catalog/rest/rest_file_io.h"
3233#include " iceberg/catalog/rest/types.h"
3334#include " iceberg/json_serde_internal.h"
3435#include " iceberg/partition_spec.h"
@@ -115,8 +116,7 @@ Result<std::vector<std::shared_ptr<FileScanTask>>> RestTableScan::PlanTableScan(
115116 }
116117 }
117118
118- ICEBERG_ASSIGN_OR_RAISE (auto path,
119- rest_context_.paths ->Plan (rest_context_.identifier ));
119+ ICEBERG_ASSIGN_OR_RAISE (auto path, rest_context_.paths ->Plan (rest_context_.identifier ));
120120 ICEBERG_ASSIGN_OR_RAISE (auto request_json, ToJson (request));
121121 ICEBERG_ASSIGN_OR_RAISE (auto json_request, ToJsonString (request_json));
122122 ICEBERG_ASSIGN_OR_RAISE (
@@ -132,6 +132,7 @@ Result<std::vector<std::shared_ptr<FileScanTask>>> RestTableScan::PlanTableScan(
132132
133133 switch (result.plan_status ) {
134134 case PlanStatus::kCompleted : {
135+ ICEBERG_RETURN_UNEXPECTED (ApplyStorageCredentials (result.storage_credentials ));
135136 auto tasks = ResolveScanTasks (result.plan_tasks , result.file_scan_tasks , specs);
136137 if (!tasks.has_value ()) CancelPlanning (plan_id);
137138 return tasks;
@@ -140,7 +141,7 @@ Result<std::vector<std::shared_ptr<FileScanTask>>> RestTableScan::PlanTableScan(
140141 return FetchPlanningResult (plan_id, specs);
141142 case PlanStatus::kFailed :
142143 return IOError (" Scan planning failed: {}" ,
143- result.error ? result.error ->message : " unknown error" );
144+ result.error ? result.error ->message : " unknown error" );
144145 case PlanStatus::kCancelled :
145146 return IOError (" Scan planning was cancelled for plan_id={}" , plan_id);
146147 }
@@ -171,6 +172,7 @@ Result<std::vector<std::shared_ptr<FileScanTask>>> RestTableScan::FetchPlanningR
171172
172173 switch (result.plan_status ) {
173174 case PlanStatus::kCompleted : {
175+ ICEBERG_RETURN_UNEXPECTED (ApplyStorageCredentials (result.storage_credentials ));
174176 auto tasks = ResolveScanTasks (result.plan_tasks , result.file_scan_tasks , specs);
175177 if (!tasks.has_value ()) CancelPlanning (plan_id);
176178 return tasks;
@@ -181,9 +183,8 @@ Result<std::vector<std::shared_ptr<FileScanTask>>> RestTableScan::FetchPlanningR
181183 .count ();
182184 if (elapsed_ms >= kMaxWaitTimeMs ) {
183185 CancelPlanning (plan_id);
184- return IOError (
185- " Scan planning timed out after {}ms waiting for plan_id={}" , elapsed_ms,
186- plan_id);
186+ return IOError (" Scan planning timed out after {}ms waiting for plan_id={}" ,
187+ elapsed_ms, plan_id);
187188 }
188189 std::this_thread::sleep_for (std::chrono::milliseconds (delay_ms));
189190 delay_ms = std::min (delay_ms * 2 , kMaxSleepMs );
@@ -192,15 +193,15 @@ Result<std::vector<std::shared_ptr<FileScanTask>>> RestTableScan::FetchPlanningR
192193 case PlanStatus::kFailed :
193194 CancelPlanning (plan_id);
194195 return IOError (" Scan planning failed: {}" ,
195- result.error ? result.error ->message : " unknown error" );
196+ result.error ? result.error ->message : " unknown error" );
196197 case PlanStatus::kCancelled :
197198 return IOError (" Scan planning was cancelled for plan_id={}" , plan_id);
198199 }
199200 }
200201
201202 CancelPlanning (plan_id);
202- return IOError (" Scan planning exceeded max retries ({}) for plan_id={}" ,
203- kMaxRetries , plan_id);
203+ return IOError (" Scan planning exceeded max retries ({}) for plan_id={}" , kMaxRetries ,
204+ plan_id);
204205}
205206
206207Result<std::vector<std::shared_ptr<FileScanTask>>> RestTableScan::FetchScanTasks (
@@ -212,15 +213,15 @@ Result<std::vector<std::shared_ptr<FileScanTask>>> RestTableScan::FetchScanTasks
212213 rest_context_.paths ->FetchScanTasks (rest_context_.identifier ));
213214 FetchScanTasksRequest request{.planTask = plan_task};
214215 ICEBERG_ASSIGN_OR_RAISE (auto json_request, ToJsonString (ToJson (request)));
215- ICEBERG_ASSIGN_OR_RAISE (
216- const auto response,
217- rest_context_.client ->Post (path, json_request, /* headers=*/ {},
218- *PlanTaskErrorHandler::Instance (),
219- *rest_context_.session ));
216+ ICEBERG_ASSIGN_OR_RAISE (const auto response,
217+ rest_context_.client ->Post (path, json_request, /* headers=*/ {},
218+ *PlanTaskErrorHandler::Instance (),
219+ *rest_context_.session ));
220220 ICEBERG_ASSIGN_OR_RAISE (auto json, FromJsonString (response.body ()));
221221 ICEBERG_ASSIGN_OR_RAISE (auto result,
222222 FetchScanTasksResponseFromJson (json, specs, *schema_));
223223 ICEBERG_RETURN_UNEXPECTED (result.Validate ());
224+ ICEBERG_RETURN_UNEXPECTED (ApplyStorageCredentials (result.storage_credentials ));
224225
225226 return ResolveScanTasks (result.plan_tasks , result.file_scan_tasks , specs);
226227}
@@ -253,18 +254,31 @@ void RestTableScan::CancelPlanning(const std::string& plan_id) const {
253254 if (!path.has_value ()) return ;
254255
255256 // Best-effort: ignore errors.
256- std::ignore = rest_context_.client ->Delete (*path, /* params=*/ {}, /* headers=*/ {},
257- *PlanErrorHandler::Instance (),
258- *rest_context_.session );
257+ std::ignore =
258+ rest_context_.client ->Delete (*path, /* params=*/ {}, /* headers=*/ {},
259+ *PlanErrorHandler::Instance (), *rest_context_.session );
260+ }
261+
262+ const std::shared_ptr<FileIO>& RestTableScan::effective_io () const {
263+ return scan_io_ ? scan_io_ : io_;
264+ }
265+
266+ Status RestTableScan::ApplyStorageCredentials (
267+ const std::vector<StorageCredential>& credentials) const {
268+ if (credentials.empty ()) return {};
269+ ICEBERG_ASSIGN_OR_RAISE (
270+ auto io, MakeTableFileIO (rest_context_.catalog_config , rest_context_.table_config ,
271+ credentials));
272+ scan_io_ = std::move (io);
273+ return {};
259274}
260275
261276// RestTableScanBuilder
262277
263- RestTableScanBuilder::RestTableScanBuilder (std::shared_ptr<TableMetadata> metadata,
264- std::shared_ptr<FileIO> io,
265- std::string table_name,
266- std::shared_ptr<MetricsReporter> metrics_reporter,
267- RestScanContext rest_context)
278+ RestTableScanBuilder::RestTableScanBuilder (
279+ std::shared_ptr<TableMetadata> metadata, std::shared_ptr<FileIO> io,
280+ std::string table_name, std::shared_ptr<MetricsReporter> metrics_reporter,
281+ RestScanContext rest_context)
268282 : DataTableScanBuilder(std::move(metadata), std::move(io), std::move(table_name),
269283 std::move(metrics_reporter)),
270284 rest_context_(std::move(rest_context)) {}
0 commit comments