Skip to content

Commit 24ec964

Browse files
Sandeep GottimukkalaSandeep Gottimukkala
authored andcommitted
feat(rest): add scan plan endpoints to REST catalog client
- Add PlanTableScan, FetchPlanningResult, CancelPlanning, FetchScanTasks methods to RestCatalog, wiring them to the corresponding REST endpoints - Add scan plan endpoint definitions and resource path helpers - Add ScanPlanErrorHandler with proper 404/406 error dispatch (NoSuchPlanIdException, NoSuchPlanTaskException, etc.) - Add PlanTableScanRequest/FetchScanTasksRequest serialization helpers - Add kNoSuchPlanId and kNoSuchPlanTask ErrorKind values - Add DataFileFromJson and FileScanTasksFromJson overloads with partition spec and schema support - Add endpoint and integration tests for all 4 scan plan operations
1 parent 17ae164 commit 24ec964

13 files changed

Lines changed: 1382 additions & 0 deletions

src/iceberg/catalog/rest/endpoint.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,26 @@ class ICEBERG_REST_EXPORT Endpoint {
128128
return {HttpMethod::kPost, "/v1/{prefix}/transactions/commit"};
129129
}
130130

131+
// Scan planning endpoints
132+
static Endpoint PlanTableScan() {
133+
return {HttpMethod::kPost, "/v1/{prefix}/namespaces/{namespace}/tables/{table}/plan"};
134+
}
135+
136+
static Endpoint FetchPlanningResult() {
137+
return {HttpMethod::kGet,
138+
"/v1/{prefix}/namespaces/{namespace}/tables/{table}/plan/{plan-id}"};
139+
}
140+
141+
static Endpoint CancelPlanning() {
142+
return {HttpMethod::kDelete,
143+
"/v1/{prefix}/namespaces/{namespace}/tables/{table}/plan/{plan-id}"};
144+
}
145+
146+
static Endpoint FetchScanTasks() {
147+
return {HttpMethod::kPost,
148+
"/v1/{prefix}/namespaces/{namespace}/tables/{table}/tasks"};
149+
}
150+
131151
private:
132152
Endpoint(HttpMethod method, std::string_view path) : method_(method), path_(path) {}
133153

src/iceberg/catalog/rest/error_handlers.cc

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ namespace {
3030
constexpr std::string_view kIllegalArgumentException = "IllegalArgumentException";
3131
constexpr std::string_view kNoSuchNamespaceException = "NoSuchNamespaceException";
3232
constexpr std::string_view kNamespaceNotEmptyException = "NamespaceNotEmptyException";
33+
constexpr std::string_view kNoSuchTableException = "NoSuchTableException";
34+
constexpr std::string_view kNoSuchPlanIdException = "NoSuchPlanIdException";
35+
constexpr std::string_view kNoSuchPlanTaskException = "NoSuchPlanTaskException";
3336

3437
} // namespace
3538

@@ -183,4 +186,52 @@ Status ViewCommitErrorHandler::Accept(const ErrorResponse& error) const {
183186
return DefaultErrorHandler::Accept(error);
184187
}
185188

189+
const std::shared_ptr<PlanErrorHandler>& PlanErrorHandler::Instance() {
190+
static const std::shared_ptr<PlanErrorHandler> instance{new PlanErrorHandler()};
191+
return instance;
192+
}
193+
194+
Status PlanErrorHandler::Accept(const ErrorResponse& error) const {
195+
switch (error.code) {
196+
case 404:
197+
if (error.type == kNoSuchNamespaceException) {
198+
return NoSuchNamespace(error.message);
199+
}
200+
if (error.type == kNoSuchTableException) {
201+
return NoSuchTable(error.message);
202+
}
203+
if (error.type == kNoSuchPlanIdException) {
204+
return NoSuchPlanId(error.message);
205+
}
206+
return NotFound(error.message);
207+
case 406:
208+
return NotSupported(error.message);
209+
}
210+
211+
return DefaultErrorHandler::Accept(error);
212+
}
213+
214+
const std::shared_ptr<PlanTaskErrorHandler>& PlanTaskErrorHandler::Instance() {
215+
static const std::shared_ptr<PlanTaskErrorHandler> instance{new PlanTaskErrorHandler()};
216+
return instance;
217+
}
218+
219+
Status PlanTaskErrorHandler::Accept(const ErrorResponse& error) const {
220+
switch (error.code) {
221+
case 404:
222+
if (error.type == kNoSuchNamespaceException) {
223+
return NoSuchNamespace(error.message);
224+
}
225+
if (error.type == kNoSuchTableException) {
226+
return NoSuchTable(error.message);
227+
}
228+
if (error.type == kNoSuchPlanTaskException) {
229+
return NoSuchPlanTask(error.message);
230+
}
231+
return NotFound(error.message);
232+
}
233+
234+
return DefaultErrorHandler::Accept(error);
235+
}
236+
186237
} // namespace iceberg::rest

src/iceberg/catalog/rest/error_handlers.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,26 @@ class ICEBERG_REST_EXPORT ViewCommitErrorHandler final : public DefaultErrorHand
127127
constexpr ViewCommitErrorHandler() = default;
128128
};
129129

130+
/// \brief Plan operation error handler.
131+
class ICEBERG_REST_EXPORT PlanErrorHandler final : public DefaultErrorHandler {
132+
public:
133+
static const std::shared_ptr<PlanErrorHandler>& Instance();
134+
135+
Status Accept(const ErrorResponse& error) const override;
136+
137+
private:
138+
constexpr PlanErrorHandler() = default;
139+
};
140+
141+
/// \brief Fetch scan tasks operation error handler.
142+
class ICEBERG_REST_EXPORT PlanTaskErrorHandler final : public DefaultErrorHandler {
143+
public:
144+
static const std::shared_ptr<PlanTaskErrorHandler>& Instance();
145+
146+
Status Accept(const ErrorResponse& error) const override;
147+
148+
private:
149+
constexpr PlanTaskErrorHandler() = default;
150+
};
151+
130152
} // namespace iceberg::rest

0 commit comments

Comments
 (0)