Skip to content

Commit 7a3bd35

Browse files
Sandeep GottimukkalaSandeep Gottimukkala
authored andcommitted
feat(rest): add scan plan endpoint support to REST catalog client
When a table is loaded from a REST catalog that advertises the PlanTableScan endpoint, NewScan() now returns a RestTableScanBuilder whose Build() produces a RestTableScan. PlanFiles() on that scan delegates manifest resolution to the server via POST /plan, GET /plan/{id} (with exponential backoff), POST /tasks/{id}, and DELETE /plan/{id} (best-effort cancel), instead of reading manifests locally. - Add RestTable, RestTableScanBuilder, RestTableScan and RestScanContext - Promote DataTableScan::PlanFiles and TableScanBuilder::Build to virtual - Convert RestCatalog::client_ and paths_ to shared_ptr so RestScanContext can share ownership with live scans
1 parent bb5cab5 commit 7a3bd35

9 files changed

Lines changed: 535 additions & 8 deletions

File tree

‎src/iceberg/catalog/rest/CMakeLists.txt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ set(ICEBERG_REST_SOURCES
3333
resource_paths.cc
3434
rest_catalog.cc
3535
rest_file_io.cc
36+
rest_table.cc
37+
rest_table_scan.cc
3638
rest_util.cc
3739
types.cc)
3840

‎src/iceberg/catalog/rest/meson.build‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ iceberg_rest_sources = files(
3030
'resource_paths.cc',
3131
'rest_catalog.cc',
3232
'rest_file_io.cc',
33+
'rest_table.cc',
34+
'rest_table_scan.cc',
3335
'rest_util.cc',
3436
'types.cc',
3537
)
@@ -94,6 +96,8 @@ install_headers(
9496
'resource_paths.h',
9597
'rest_catalog.h',
9698
'rest_file_io.h',
99+
'rest_table.h',
100+
'rest_table_scan.h',
97101
'rest_util.h',
98102
'type_fwd.h',
99103
'types.h',

‎src/iceberg/catalog/rest/rest_catalog.cc‎

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "iceberg/catalog/rest/json_serde_internal.h"
4040
#include "iceberg/catalog/rest/resource_paths.h"
4141
#include "iceberg/catalog/rest/rest_file_io.h"
42+
#include "iceberg/catalog/rest/rest_table.h"
4243
#include "iceberg/catalog/rest/rest_util.h"
4344
#include "iceberg/catalog/rest/types.h"
4445
#include "iceberg/json_serde_internal.h"
@@ -451,7 +452,7 @@ Result<std::shared_ptr<RestCatalog>> RestCatalog::Make(
451452
// Get snapshot loading mode
452453
ICEBERG_ASSIGN_OR_RAISE(auto snapshot_mode, final_config.SnapshotLoadingMode());
453454

454-
auto client = std::make_unique<HttpClient>(final_config.ExtractHeaders());
455+
auto client = std::make_shared<HttpClient>(final_config.ExtractHeaders());
455456
ICEBERG_ASSIGN_OR_RAISE(auto catalog_session,
456457
auth_manager->CatalogSession(*client, final_config.configs()));
457458

@@ -466,8 +467,8 @@ Result<std::shared_ptr<RestCatalog>> RestCatalog::Make(
466467
}
467468

468469
RestCatalog::RestCatalog(RestCatalogProperties config, std::shared_ptr<FileIO> file_io,
469-
std::unique_ptr<HttpClient> client,
470-
std::unique_ptr<ResourcePaths> paths,
470+
std::shared_ptr<HttpClient> client,
471+
std::shared_ptr<ResourcePaths> paths,
471472
std::unordered_set<Endpoint> endpoints,
472473
std::unique_ptr<auth::AuthManager> auth_manager,
473474
std::shared_ptr<auth::AuthSession> catalog_session,
@@ -873,6 +874,20 @@ Result<std::shared_ptr<Table>> RestCatalog::MakeTableFromLoadResult(
873874
TableAuthSession(identifier, table_config, std::move(contextual_session)));
874875
auto table_catalog = std::make_shared<TableScopedCatalog>(
875876
shared_from_this(), context, identifier, table_config, table_session);
877+
878+
if (supported_endpoints_.contains(Endpoint::PlanTableScan())) {
879+
RestScanContext rest_ctx{
880+
.client = client_,
881+
.paths = paths_,
882+
.session = table_session,
883+
.supported_endpoints = supported_endpoints_,
884+
.identifier = identifier,
885+
};
886+
return RestTable::Make(identifier, std::move(result.metadata),
887+
std::move(result.metadata_location), std::move(table_io),
888+
std::move(table_catalog), std::move(rest_ctx));
889+
}
890+
876891
return Table::Make(identifier, std::move(result.metadata),
877892
std::move(result.metadata_location), std::move(table_io),
878893
std::move(table_catalog));

‎src/iceberg/catalog/rest/rest_catalog.h‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class ICEBERG_REST_EXPORT RestCatalog final
6363
class TableScopedCatalog;
6464

6565
RestCatalog(RestCatalogProperties config, std::shared_ptr<FileIO> file_io,
66-
std::unique_ptr<HttpClient> client, std::unique_ptr<ResourcePaths> paths,
66+
std::shared_ptr<HttpClient> client, std::shared_ptr<ResourcePaths> paths,
6767
std::unordered_set<Endpoint> endpoints,
6868
std::unique_ptr<auth::AuthManager> auth_manager,
6969
std::shared_ptr<auth::AuthSession> catalog_session,
@@ -173,8 +173,8 @@ class ICEBERG_REST_EXPORT RestCatalog final
173173

174174
RestCatalogProperties config_;
175175
std::shared_ptr<FileIO> file_io_;
176-
std::unique_ptr<HttpClient> client_;
177-
std::unique_ptr<ResourcePaths> paths_;
176+
std::shared_ptr<HttpClient> client_;
177+
std::shared_ptr<ResourcePaths> paths_;
178178
std::string name_;
179179
std::unordered_set<Endpoint> supported_endpoints_;
180180
std::unique_ptr<auth::AuthManager> auth_manager_;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#include "iceberg/catalog/rest/rest_table.h"
21+
22+
#include <memory>
23+
#include <utility>
24+
25+
#include "iceberg/catalog/rest/rest_table_scan.h"
26+
#include "iceberg/result.h"
27+
#include "iceberg/table_metadata.h"
28+
#include "iceberg/util/macros.h"
29+
30+
namespace iceberg::rest {
31+
32+
RestTable::RestTable(TableIdentifier identifier, std::shared_ptr<TableMetadata> metadata,
33+
std::string metadata_location, std::shared_ptr<FileIO> io,
34+
std::shared_ptr<Catalog> catalog, RestScanContext rest_context)
35+
: Table(std::move(identifier), std::move(metadata), std::move(metadata_location),
36+
std::move(io), std::move(catalog)),
37+
rest_context_(std::move(rest_context)) {}
38+
39+
RestTable::~RestTable() = default;
40+
41+
Result<std::shared_ptr<RestTable>> RestTable::Make(TableIdentifier identifier,
42+
std::shared_ptr<TableMetadata> metadata,
43+
std::string metadata_location,
44+
std::shared_ptr<FileIO> io,
45+
std::shared_ptr<Catalog> catalog,
46+
RestScanContext rest_context) {
47+
if (metadata == nullptr) {
48+
return InvalidArgument("Metadata cannot be null");
49+
}
50+
return std::shared_ptr<RestTable>(
51+
new RestTable(std::move(identifier), std::move(metadata),
52+
std::move(metadata_location), std::move(io), std::move(catalog),
53+
std::move(rest_context)));
54+
}
55+
56+
Result<std::unique_ptr<DataTableScanBuilder>> RestTable::NewScan() const {
57+
return std::make_unique<RestTableScanBuilder>(metadata_, io_, rest_context_);
58+
}
59+
60+
} // namespace iceberg::rest
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#pragma once
21+
22+
#include <memory>
23+
#include <string>
24+
25+
#include "iceberg/catalog/rest/iceberg_rest_export.h"
26+
#include "iceberg/catalog/rest/rest_table_scan.h"
27+
#include "iceberg/result.h"
28+
#include "iceberg/table.h"
29+
#include "iceberg/type_fwd.h"
30+
31+
/// \file iceberg/catalog/rest/rest_table.h
32+
/// A Table subclass that uses server-side distributed scan planning via the REST catalog.
33+
34+
namespace iceberg::rest {
35+
36+
/// \brief A Table whose NewScan() returns a RestTableScanBuilder, delegating
37+
/// PlanFiles() to the REST catalog server's scan planning endpoints.
38+
class ICEBERG_REST_EXPORT RestTable final : public Table {
39+
public:
40+
static Result<std::shared_ptr<RestTable>> Make(TableIdentifier identifier,
41+
std::shared_ptr<TableMetadata> metadata,
42+
std::string metadata_location,
43+
std::shared_ptr<FileIO> io,
44+
std::shared_ptr<Catalog> catalog,
45+
RestScanContext rest_context);
46+
47+
~RestTable() override;
48+
49+
/// \brief Returns a RestTableScanBuilder that will delegate PlanFiles() to the
50+
/// REST catalog server.
51+
Result<std::unique_ptr<DataTableScanBuilder>> NewScan() const override;
52+
53+
private:
54+
RestTable(TableIdentifier identifier, std::shared_ptr<TableMetadata> metadata,
55+
std::string metadata_location, std::shared_ptr<FileIO> io,
56+
std::shared_ptr<Catalog> catalog, RestScanContext rest_context);
57+
58+
RestScanContext rest_context_;
59+
};
60+
61+
} // namespace iceberg::rest

0 commit comments

Comments
 (0)