WZhuo commented on code in PR #437:
URL: https://github.com/apache/iceberg-cpp/pull/437#discussion_r2646576737


##########
src/iceberg/table_metadata.cc:
##########
@@ -608,7 +631,124 @@ Status TableMetadataBuilder::Impl::RemoveProperties(
   return {};
 }
 
-std::unique_ptr<TableMetadata> TableMetadataBuilder::Impl::Build() {
+Status TableMetadataBuilder::Impl::SetCurrentSchema(int32_t schema_id) {
+  if (schema_id == kLastAdded) {
+    if (!last_added_schema_id_.has_value()) {
+      return InvalidArgument("Cannot set last added schema: no schema has been 
added");
+    }
+    return SetCurrentSchema(last_added_schema_id_.value());
+  }
+
+  if (metadata_.current_schema_id == schema_id) {
+    return {};
+  }
+
+  auto it = schemas_by_id_.find(schema_id);
+  if (it == schemas_by_id_.end()) {
+    return InvalidArgument("Cannot set current schema to unknown schema: {}", 
schema_id);
+  }
+  const auto& schema = it->second;
+
+  // Rebuild all partition specs for the new current schema
+  std::vector<std::shared_ptr<PartitionSpec>> updated_specs;
+  for (const auto& spec : metadata_.partition_specs) {
+    ICEBERG_ASSIGN_OR_RAISE(auto updated_spec, UpdateSpecSchema(*schema, 
*spec));
+    updated_specs.push_back(std::move(updated_spec));
+  }
+  metadata_.partition_specs = std::move(updated_specs);
+  specs_by_id_.clear();
+  for (const auto& spec : metadata_.partition_specs) {
+    specs_by_id_.emplace(spec->spec_id(), spec);
+  }
+
+  // Rebuild all sort orders for the new current schema
+  std::vector<std::shared_ptr<SortOrder>> updated_orders;
+  for (const auto& order : metadata_.sort_orders) {
+    ICEBERG_ASSIGN_OR_RAISE(auto updated_order, UpdateSortOrderSchema(*schema, 
*order));
+    updated_orders.push_back(std::move(updated_order));
+  }
+  metadata_.sort_orders = std::move(updated_orders);
+  sort_orders_by_id_.clear();
+  for (const auto& order : metadata_.sort_orders) {
+    sort_orders_by_id_.emplace(order->order_id(), order);
+  }
+
+  // Set the current schema ID
+  metadata_.current_schema_id = schema_id;
+
+  // Record the change
+  if (last_added_schema_id_.has_value() && last_added_schema_id_.value() == 
schema_id) {
+    changes_.push_back(std::make_unique<table::SetCurrentSchema>(kLastAdded));
+  } else {
+    changes_.push_back(std::make_unique<table::SetCurrentSchema>(schema_id));
+  }
+
+  return {};
+}
+
+Status TableMetadataBuilder::Impl::RemoveSchemas(const std::vector<int32_t>& 
schema_ids) {
+  std::unordered_set<int32_t> schema_ids_to_remove(schema_ids.begin(), 
schema_ids.end());
+  auto current_schema_id = 
metadata_.current_schema_id.value_or(Schema::kInitialSchemaId);
+  if (!schema_ids_to_remove.contains(current_schema_id)) {
+    return InvalidArgument("Cannot remove current schema: {}", 
current_schema_id);
+  }
+
+  if (!schema_ids_to_remove.empty()) {
+    metadata_.schemas = metadata_.schemas | std::views::filter([&](const auto& 
schema) {
+                          return !schema_ids_to_remove.contains(
+                              
schema->schema_id().value_or(Schema::kInitialSchemaId));
+                        }) |
+                        
std::ranges::to<std::vector<std::shared_ptr<Schema>>>();
+    changes_.push_back(
+        
std::make_unique<table::RemoveSchemas>(std::move(schema_ids_to_remove)));
+  }
+
+  return {};
+}
+
+Result<int32_t> TableMetadataBuilder::Impl::AddSchema(const Schema& schema,
+                                                      int32_t 
new_last_column_id) {
+  if (new_last_column_id < metadata_.last_column_id) {
+    return InvalidArgument("Invalid last column ID: {} < {} (previous last 
column ID)",
+                           new_last_column_id, metadata_.last_column_id);
+  }
+
+  ICEBERG_RETURN_UNEXPECTED(schema.Validate(metadata_.format_version));
+
+  auto new_schema_id = ReuseOrCreateNewSchemaId(schema);
+  if (schemas_by_id_.find(new_schema_id) != schemas_by_id_.end()) {

Review Comment:
   It also check the metadata_.last_column_id equals to new_last_column_id in 
Java implement, does it matter?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to