Skip to content

Commit 323aebe

Browse files
author
shuxu.li
committed
feat: Refresh method support for table
1 parent b70644f commit 323aebe

File tree

5 files changed

+92
-13
lines changed

5 files changed

+92
-13
lines changed

src/iceberg/catalog/in_memory_catalog.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ class ICEBERG_EXPORT InMemoryNamespace {
109109
/// ErrorKind::kNoSuchTable if the table does not exist.
110110
Status UnregisterTable(const TableIdentifier& table_ident);
111111

112+
/// \brief Updates the metadata location of an existing table.
113+
///
114+
/// \param table_ident The fully qualified identifier of the table.
115+
/// \param metadata_location The path to the table's metadata.
116+
/// \return Status::OK if the table metadata location is updated;
117+
/// Error otherwise.
118+
Status UpdateTableMetaLocation(const TableIdentifier& table_ident,
119+
const std::string& metadata_location);
120+
112121
/// \brief Checks if a table exists in the specified namespace.
113122
///
114123
/// \param table_ident The identifier of the table to check.
@@ -297,6 +306,17 @@ Status InMemoryNamespace::UnregisterTable(TableIdentifier const& table_ident) {
297306
return {};
298307
}
299308

309+
Status InMemoryNamespace::UpdateTableMetaLocation(const TableIdentifier& table_ident,
310+
const std::string& metadata_location) {
311+
const auto ns = GetNamespace(this, table_ident.ns);
312+
ICEBERG_RETURN_UNEXPECTED(ns);
313+
if (!ns.value()->table_metadata_locations_.contains(table_ident.name)) {
314+
return NotFound("{} does not exist", table_ident.name);
315+
}
316+
ns.value()->table_metadata_locations_[table_ident.name] = metadata_location;
317+
return {};
318+
}
319+
300320
Result<bool> InMemoryNamespace::TableExists(TableIdentifier const& table_ident) const {
301321
const auto ns = GetNamespace(this, table_ident.ns);
302322
ICEBERG_RETURN_UNEXPECTED(ns);
@@ -446,4 +466,10 @@ std::unique_ptr<TableBuilder> InMemoryCatalog::BuildTable(
446466
throw IcebergError("not implemented");
447467
}
448468

469+
Status InMemoryCatalog::UpdateTableMetaLocationInternal(
470+
const TableIdentifier& identifier, const std::string& metadata_location) {
471+
std::unique_lock lock(mutex_);
472+
return root_namespace_->UpdateTableMetaLocation(identifier, metadata_location);
473+
}
474+
449475
} // namespace iceberg

src/iceberg/catalog/in_memory_catalog.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ class ICEBERG_EXPORT InMemoryCatalog
9393
std::unique_ptr<iceberg::TableBuilder> BuildTable(const TableIdentifier& identifier,
9494
const Schema& schema) const override;
9595

96+
protected:
97+
Status UpdateTableMetaLocationInternal(const TableIdentifier& identifier,
98+
const std::string& metadata_location);
99+
96100
private:
97101
std::string catalog_name_;
98102
std::unordered_map<std::string, std::string> properties_;

src/iceberg/table.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ const std::string& Table::uuid() const { return metadata_->table_uuid; }
3535

3636
Status Table::Refresh() {
3737
if (!catalog_) {
38-
return InvalidArgument("Cannot refresh table metadata without a catalog");
38+
return InvalidArgument("Refresh is not supported for table without a catalog");
3939
}
4040

41-
ICEBERG_ASSIGN_OR_RAISE(auto fresh, catalog_->LoadTable(identifier_));
42-
if (metadata_location_ != fresh->metadata_location_) {
43-
metadata_ = std::move(fresh->metadata_);
44-
metadata_location_ = std::move(fresh->metadata_location_);
45-
io_ = std::move(fresh->io_);
41+
ICEBERG_ASSIGN_OR_RAISE(auto refreshed_table, catalog_->LoadTable(identifier_));
42+
if (metadata_location_ != refreshed_table->metadata_location_) {
43+
metadata_ = std::move(refreshed_table->metadata_);
44+
metadata_location_ = std::move(refreshed_table->metadata_location_);
45+
io_ = std::move(refreshed_table->io_);
4646

4747
schemas_map_.reset();
4848
partition_spec_map_.reset();

test/in_memory_catalog_test.cc

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
* under the License.
1818
*/
1919

20-
#include "iceberg/catalog/in_memory_catalog.h"
21-
2220
#include <filesystem>
2321

2422
#include <arrow/filesystem/localfs.h>
@@ -29,6 +27,7 @@
2927
#include "iceberg/table.h"
3028
#include "iceberg/table_metadata.h"
3129
#include "matchers.h"
30+
#include "mock_catalog.h"
3231
#include "test_common.h"
3332

3433
namespace iceberg {
@@ -39,8 +38,8 @@ class InMemoryCatalogTest : public ::testing::Test {
3938
file_io_ = std::make_shared<iceberg::arrow::ArrowFileSystemFileIO>(
4039
std::make_shared<::arrow::fs::LocalFileSystem>());
4140
std::unordered_map<std::string, std::string> properties = {{"prop1", "val1"}};
42-
catalog_ = std::make_shared<InMemoryCatalog>("test_catalog", file_io_,
43-
"/tmp/warehouse/", properties);
41+
catalog_ = std::make_shared<MockInMemoryCatalog>("test_catalog", file_io_,
42+
"/tmp/warehouse/", properties);
4443
}
4544

4645
void TearDown() override {
@@ -74,7 +73,7 @@ class InMemoryCatalogTest : public ::testing::Test {
7473
}
7574

7675
std::shared_ptr<FileIO> file_io_;
77-
std::shared_ptr<InMemoryCatalog> catalog_;
76+
std::shared_ptr<MockInMemoryCatalog> catalog_;
7877
// Used to store temporary paths created during the test
7978
std::vector<std::string> created_temp_paths_;
8079
};
@@ -121,6 +120,7 @@ TEST_F(InMemoryCatalogTest, RefreshTable) {
121120
std::unique_ptr<TableMetadata> metadata;
122121
ASSERT_NO_FATAL_FAILURE(ReadTableMetadata("TableMetadataV2Valid.json", &metadata));
123122

123+
metadata->current_snapshot_id = 3051729675574597004;
124124
auto table_location = GenerateTestTableLocation(tableIdent.name);
125125
auto metadata_location = std::format("{}v0.metadata.json", table_location);
126126
auto status = TableMetadataUtil::Write(*file_io_, metadata_location, *metadata);
@@ -129,9 +129,18 @@ TEST_F(InMemoryCatalogTest, RefreshTable) {
129129
auto table = catalog_->RegisterTable(tableIdent, metadata_location);
130130
EXPECT_THAT(table, IsOk());
131131
ASSERT_TRUE(table.value()->current_snapshot().has_value());
132-
ASSERT_EQ(table.value()->current_snapshot().value()->snapshot_id, 3055729675574597004);
132+
ASSERT_EQ(table.value()->current_snapshot().value()->snapshot_id, 3051729675574597004);
133+
134+
// update table version to 3055729675574597004
135+
metadata_location = std::format("{}v1.metadata.json", table_location);
136+
metadata->current_snapshot_id = 3055729675574597004;
137+
status = TableMetadataUtil::Write(*file_io_, metadata_location, *metadata);
138+
EXPECT_THAT(status, IsOk());
139+
140+
// update table metadata location in catalog
141+
status = catalog_->UpdateTableMetaLocation(tableIdent, metadata_location);
142+
EXPECT_THAT(status, IsOk());
133143

134-
// Now we don't support commit method in catalog, so here only test refresh with the
135144
// same version
136145
status = table.value()->Refresh();
137146
EXPECT_THAT(status, IsOk());

test/mock_catalog.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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 "iceberg/catalog/in_memory_catalog.h"
23+
24+
namespace iceberg {
25+
26+
class ICEBERG_EXPORT MockInMemoryCatalog : public InMemoryCatalog {
27+
public:
28+
MockInMemoryCatalog(std::string const& name, std::shared_ptr<FileIO> const& file_io,
29+
std::string const& warehouse_location,
30+
std::unordered_map<std::string, std::string> const& properties)
31+
: InMemoryCatalog(name, file_io, warehouse_location, properties) {}
32+
33+
/// \brief Directly sets the metadata location of a table.
34+
/// \note This should only be used in unit tests.
35+
Status UpdateTableMetaLocation(const TableIdentifier& identifier,
36+
const std::string& metadata_location) {
37+
return UpdateTableMetaLocationInternal(identifier, metadata_location);
38+
}
39+
};
40+
} // namespace iceberg

0 commit comments

Comments
 (0)