2121
2222#include < algorithm>
2323#include < iterator> // IWYU pragma: keep
24+ #include < memory>
2425
25- #include " iceberg/exception.h"
2626#include " iceberg/table.h"
27+ #include " iceberg/table_identifier.h"
2728#include " iceberg/table_metadata.h"
29+ #include " iceberg/table_requirement.h"
30+ #include " iceberg/table_update.h"
2831#include " iceberg/util/macros.h"
2932
3033namespace iceberg {
@@ -121,6 +124,13 @@ class ICEBERG_EXPORT InMemoryNamespace {
121124 // / \return The metadata location if the table exists; error otherwise.
122125 Result<std::string> GetTableMetadataLocation (const TableIdentifier& table_ident) const ;
123126
127+ // / \brief Updates the metadata location for the specified table.
128+ // /
129+ // / \param table_ident The identifier of the table.
130+ // / \param metadata_location The new metadata location.
131+ Status UpdateTableMetadataLocation (const TableIdentifier& table_ident,
132+ const std::string& metadata_location);
133+
124134 // / \brief Internal utility for retrieving a namespace node pointer from the tree.
125135 // /
126136 // / \tparam NamespacePtr The type of the namespace node pointer.
@@ -279,7 +289,7 @@ Result<std::vector<std::string>> InMemoryNamespace::ListTables(
279289 return table_names;
280290}
281291
282- Status InMemoryNamespace::RegisterTable (TableIdentifier const & table_ident,
292+ Status InMemoryNamespace::RegisterTable (const TableIdentifier & table_ident,
283293 const std::string& metadata_location) {
284294 const auto ns = GetNamespace (this , table_ident.ns );
285295 ICEBERG_RETURN_UNEXPECTED (ns);
@@ -290,21 +300,21 @@ Status InMemoryNamespace::RegisterTable(TableIdentifier const& table_ident,
290300 return {};
291301}
292302
293- Status InMemoryNamespace::UnregisterTable (TableIdentifier const & table_ident) {
303+ Status InMemoryNamespace::UnregisterTable (const TableIdentifier & table_ident) {
294304 const auto ns = GetNamespace (this , table_ident.ns );
295305 ICEBERG_RETURN_UNEXPECTED (ns);
296306 ns.value ()->table_metadata_locations_ .erase (table_ident.name );
297307 return {};
298308}
299309
300- Result<bool > InMemoryNamespace::TableExists (TableIdentifier const & table_ident) const {
310+ Result<bool > InMemoryNamespace::TableExists (const TableIdentifier & table_ident) const {
301311 const auto ns = GetNamespace (this , table_ident.ns );
302312 ICEBERG_RETURN_UNEXPECTED (ns);
303313 return ns.value ()->table_metadata_locations_ .contains (table_ident.name );
304314}
305315
306316Result<std::string> InMemoryNamespace::GetTableMetadataLocation (
307- TableIdentifier const & table_ident) const {
317+ const TableIdentifier & table_ident) const {
308318 const auto ns = GetNamespace (this , table_ident.ns );
309319 ICEBERG_RETURN_UNEXPECTED (ns);
310320 const auto it = ns.value ()->table_metadata_locations_ .find (table_ident.name );
@@ -314,17 +324,24 @@ Result<std::string> InMemoryNamespace::GetTableMetadataLocation(
314324 return it->second ;
315325}
316326
327+ Status InMemoryNamespace::UpdateTableMetadataLocation (
328+ const TableIdentifier& table_ident, const std::string& metadata_location) {
329+ ICEBERG_ASSIGN_OR_RAISE (auto ns, GetNamespace (this , table_ident.ns ));
330+ ns->table_metadata_locations_ [table_ident.name ] = metadata_location;
331+ return {};
332+ }
333+
317334std::shared_ptr<InMemoryCatalog> InMemoryCatalog::Make (
318- std::string const & name, std::shared_ptr<FileIO> const & file_io,
319- std::string const & warehouse_location,
320- std::unordered_map<std::string, std::string> const & properties) {
335+ const std::string& name, const std::shared_ptr<FileIO>& file_io,
336+ const std::string& warehouse_location,
337+ const std::unordered_map<std::string, std::string>& properties) {
321338 return std::make_shared<InMemoryCatalog>(name, file_io, warehouse_location, properties);
322339}
323340
324341InMemoryCatalog::InMemoryCatalog (
325- std::string const & name, std::shared_ptr<FileIO> const & file_io,
326- std::string const & warehouse_location,
327- std::unordered_map<std::string, std::string> const & properties)
342+ const std::string& name, const std::shared_ptr<FileIO>& file_io,
343+ const std::string& warehouse_location,
344+ const std::unordered_map<std::string, std::string>& properties)
328345 : catalog_name_(std::move(name)),
329346 properties_ (std::move(properties)),
330347 file_io_(std::move(file_io)),
@@ -394,7 +411,32 @@ Result<std::unique_ptr<Table>> InMemoryCatalog::UpdateTable(
394411 const TableIdentifier& identifier,
395412 const std::vector<std::unique_ptr<TableRequirement>>& requirements,
396413 const std::vector<std::unique_ptr<TableUpdate>>& updates) {
397- return NotImplemented (" update table" );
414+ std::unique_lock lock (mutex_);
415+ ICEBERG_ASSIGN_OR_RAISE (auto metadata_location,
416+ root_namespace_->GetTableMetadataLocation (identifier));
417+
418+ ICEBERG_ASSIGN_OR_RAISE (auto base,
419+ TableMetadataUtil::Read (*file_io_, metadata_location));
420+ base->metadata_file_location = std::move (metadata_location);
421+
422+ for (const auto & requirement : requirements) {
423+ ICEBERG_RETURN_UNEXPECTED (requirement->Validate (base.get ()));
424+ }
425+
426+ auto builder = TableMetadataBuilder::BuildFrom (base.get ());
427+ for (const auto & update : updates) {
428+ update->ApplyTo (*builder);
429+ }
430+ ICEBERG_ASSIGN_OR_RAISE (auto updated, builder->Build ());
431+
432+ ICEBERG_RETURN_UNEXPECTED (
433+ TableMetadataUtil::Write (*file_io_, base.get (), updated.get ()));
434+ ICEBERG_RETURN_UNEXPECTED (root_namespace_->UpdateTableMetadataLocation (
435+ identifier, updated->metadata_file_location ));
436+ TableMetadataUtil::DeleteRemovedMetadataFiles (*file_io_, base.get (), updated.get ());
437+
438+ return std::make_unique<Table>(identifier, std::move (updated), file_io_,
439+ std::static_pointer_cast<Catalog>(shared_from_this ()));
398440}
399441
400442Result<std::shared_ptr<Transaction>> InMemoryCatalog::StageCreateTable (
@@ -435,9 +477,9 @@ Result<std::unique_ptr<Table>> InMemoryCatalog::LoadTable(
435477
436478 ICEBERG_ASSIGN_OR_RAISE (auto metadata,
437479 TableMetadataUtil::Read (*file_io_, metadata_location.value ()));
480+ metadata->metadata_file_location = metadata_location.value ();
438481
439- return std::make_unique<Table>(identifier, std::move (metadata),
440- metadata_location.value (), file_io_,
482+ return std::make_unique<Table>(identifier, std::move (metadata), file_io_,
441483 std::static_pointer_cast<Catalog>(shared_from_this ()));
442484}
443485
0 commit comments