|
26 | 26 |
|
27 | 27 | #include "iceberg/catalog/rest/json_serde_internal.h" |
28 | 28 | #include "iceberg/catalog/rest/types.h" |
| 29 | +#include "iceberg/expression/json_serde_internal.h" |
29 | 30 | #include "iceberg/json_serde_internal.h" |
30 | 31 | #include "iceberg/partition_spec.h" |
| 32 | +#include "iceberg/schema.h" |
31 | 33 | #include "iceberg/sort_order.h" |
32 | 34 | #include "iceberg/table_identifier.h" |
33 | 35 | #include "iceberg/table_requirement.h" |
@@ -78,6 +80,21 @@ constexpr std::string_view kExpiresIn = "expires_in"; |
78 | 80 | constexpr std::string_view kIssuedTokenType = "issued_token_type"; |
79 | 81 | constexpr std::string_view kRefreshToken = "refresh_token"; |
80 | 82 | constexpr std::string_view kOAuthScope = "scope"; |
| 83 | +constexpr std::string_view kPlanStatus = "status"; |
| 84 | +constexpr std::string_view kPlanId = "plan-id"; |
| 85 | +constexpr std::string_view kPlanTasks = "plan-tasks"; |
| 86 | +constexpr std::string_view kFileScanTasks = "file-scan-tasks"; |
| 87 | +constexpr std::string_view kDeleteFiles = "delete-files"; |
| 88 | +constexpr std::string_view kSnapshotId = "snapshot-id"; |
| 89 | +constexpr std::string_view kSelect = "select"; |
| 90 | +constexpr std::string_view kFilter = "filter"; |
| 91 | +constexpr std::string_view kCaseSensitive = "case-sensitive"; |
| 92 | +constexpr std::string_view kUseSnapshotSchema = "use-snapshot-schema"; |
| 93 | +constexpr std::string_view kStartSnapshotId = "start-snapshot-id"; |
| 94 | +constexpr std::string_view kEndSnapshotId = "end-snapshot-id"; |
| 95 | +constexpr std::string_view kStatsFields = "stats-fields"; |
| 96 | +constexpr std::string_view kMinRowsRequired = "min-rows-required"; |
| 97 | +constexpr std::string_view kPlanTask = "plan-task"; |
81 | 98 |
|
82 | 99 | } // namespace |
83 | 100 |
|
@@ -506,6 +523,114 @@ Result<OAuthTokenResponse> OAuthTokenResponseFromJson(const nlohmann::json& json |
506 | 523 | return response; |
507 | 524 | } |
508 | 525 |
|
| 526 | +Result<nlohmann::json> ToJson(const PlanTableScanRequest& request) { |
| 527 | + nlohmann::json json; |
| 528 | + if (request.snapshot_id.has_value()) { |
| 529 | + json[kSnapshotId] = request.snapshot_id.value(); |
| 530 | + } |
| 531 | + if (!request.select.empty()) { |
| 532 | + json[kSelect] = request.select; |
| 533 | + } |
| 534 | + if (request.filter) { |
| 535 | + ICEBERG_ASSIGN_OR_RAISE(auto filter_json, iceberg::ToJson(*request.filter)); |
| 536 | + json[kFilter] = std::move(filter_json); |
| 537 | + } |
| 538 | + json[kCaseSensitive] = request.case_sensitive; |
| 539 | + json[kUseSnapshotSchema] = request.use_snapshot_schema; |
| 540 | + if (request.start_snapshot_id.has_value()) { |
| 541 | + json[kStartSnapshotId] = request.start_snapshot_id.value(); |
| 542 | + } |
| 543 | + if (request.end_snapshot_id.has_value()) { |
| 544 | + json[kEndSnapshotId] = request.end_snapshot_id.value(); |
| 545 | + } |
| 546 | + if (!request.statsFields.empty()) { |
| 547 | + json[kStatsFields] = request.statsFields; |
| 548 | + } |
| 549 | + if (request.min_rows_required.has_value()) { |
| 550 | + json[kMinRowsRequired] = request.min_rows_required.value(); |
| 551 | + } |
| 552 | + return json; |
| 553 | +} |
| 554 | + |
| 555 | +nlohmann::json ToJson(const FetchScanTasksRequest& request) { |
| 556 | + nlohmann::json json; |
| 557 | + json[kPlanTask] = request.planTask; |
| 558 | + return json; |
| 559 | +} |
| 560 | + |
| 561 | +Status BaseScanTaskResponseFromJson( |
| 562 | + const nlohmann::json& json, BaseScanTaskResponse* response, |
| 563 | + const std::unordered_map<int32_t, std::shared_ptr<PartitionSpec>>& partition_specs_by_id, |
| 564 | + const Schema& schema) { |
| 565 | + // 1. plan_tasks |
| 566 | + ICEBERG_ASSIGN_OR_RAISE(auto plan_tasks, |
| 567 | + GetJsonValue<nlohmann::json>(json, kPlanTasks)); |
| 568 | + if (!plan_tasks.is_array()) { |
| 569 | + return JsonParseError("Cannot parse plan tasks from non-array: {}", |
| 570 | + SafeDumpJson(plan_tasks)); |
| 571 | + } |
| 572 | + ICEBERG_ASSIGN_OR_RAISE(response->plan_tasks, |
| 573 | + GetTypedJsonValue<std::vector<std::string>>(plan_tasks)); |
| 574 | + |
| 575 | + // 2. delete_files |
| 576 | + ICEBERG_ASSIGN_OR_RAISE(auto delete_files_json, |
| 577 | + GetJsonValue<nlohmann::json>(json, kDeleteFiles)); |
| 578 | + if (!delete_files_json.is_array()) { |
| 579 | + return JsonParseError("Cannot parse delete files from non-array: {}", |
| 580 | + SafeDumpJson(delete_files_json)); |
| 581 | + } |
| 582 | + for (const auto& entry_json : delete_files_json) { |
| 583 | + ICEBERG_ASSIGN_OR_RAISE(auto delete_file, |
| 584 | + DataFileFromJson(entry_json, partition_specs_by_id, schema)); |
| 585 | + response->delete_files.push_back(std::move(delete_file)); |
| 586 | + } |
| 587 | + |
| 588 | + // 3. file_scan_tasks |
| 589 | + ICEBERG_ASSIGN_OR_RAISE(auto file_scan_tasks_json, |
| 590 | + GetJsonValue<nlohmann::json>(json, kFileScanTasks)); |
| 591 | + ICEBERG_ASSIGN_OR_RAISE( |
| 592 | + response->file_scan_tasks, |
| 593 | + FileScanTasksFromJson(file_scan_tasks_json, response->delete_files, |
| 594 | + partition_specs_by_id, schema)); |
| 595 | + return {}; |
| 596 | +} |
| 597 | + |
| 598 | +Result<PlanTableScanResponse> PlanTableScanResponseFromJson( |
| 599 | + const nlohmann::json& json, |
| 600 | + const std::unordered_map<int32_t, std::shared_ptr<PartitionSpec>>& partition_specs_by_id, |
| 601 | + const Schema& schema) { |
| 602 | + PlanTableScanResponse response; |
| 603 | + ICEBERG_ASSIGN_OR_RAISE(response.plan_status, |
| 604 | + GetJsonValue<std::string>(json, kPlanStatus)); |
| 605 | + ICEBERG_ASSIGN_OR_RAISE(response.plan_id, GetJsonValue<std::string>(json, kPlanId)); |
| 606 | + ICEBERG_RETURN_UNEXPECTED( |
| 607 | + BaseScanTaskResponseFromJson(json, &response, partition_specs_by_id, schema)); |
| 608 | + return response; |
| 609 | +} |
| 610 | + |
| 611 | +Result<FetchPlanningResultResponse> FetchPlanningResultResponseFromJson( |
| 612 | + const nlohmann::json& json, |
| 613 | + const std::unordered_map<int32_t, std::shared_ptr<PartitionSpec>>& partition_specs_by_id, |
| 614 | + const Schema& schema) { |
| 615 | + FetchPlanningResultResponse response; |
| 616 | + ICEBERG_ASSIGN_OR_RAISE(auto status_str, |
| 617 | + GetJsonValue<std::string>(json, kPlanStatus)); |
| 618 | + response.plan_status = PlanStatus(PlanStatus::FromString(status_str)); |
| 619 | + ICEBERG_RETURN_UNEXPECTED( |
| 620 | + BaseScanTaskResponseFromJson(json, &response, partition_specs_by_id, schema)); |
| 621 | + return response; |
| 622 | +} |
| 623 | + |
| 624 | +Result<FetchScanTasksResponse> FetchScanTasksResponseFromJson( |
| 625 | + const nlohmann::json& json, |
| 626 | + const std::unordered_map<int32_t, std::shared_ptr<PartitionSpec>>& partition_specs_by_id, |
| 627 | + const Schema& schema) { |
| 628 | + FetchScanTasksResponse response; |
| 629 | + ICEBERG_RETURN_UNEXPECTED( |
| 630 | + BaseScanTaskResponseFromJson(json, &response, partition_specs_by_id, schema)); |
| 631 | + return response; |
| 632 | +} |
| 633 | + |
509 | 634 | #define ICEBERG_DEFINE_FROM_JSON(Model) \ |
510 | 635 | template <> \ |
511 | 636 | Result<Model> FromJson<Model>(const nlohmann::json& json) { \ |
|
0 commit comments