Skip to content

Commit 5141ba4

Browse files
committed
Refactor MetadataTable to use separate TableMetadata and unified entrypoint
1 parent fff474f commit 5141ba4

8 files changed

Lines changed: 78 additions & 98 deletions

File tree

src/iceberg/inspect/history_table.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,20 @@
3131
namespace iceberg {
3232

3333
HistoryTable::HistoryTable(std::shared_ptr<Table> table)
34-
: MetadataTable(table, CreateName(table->name())) {
35-
this->schema_ = std::make_shared<Schema>(
34+
: MetadataTable(table, CreateName(table->name())) {}
35+
36+
HistoryTable::~HistoryTable() = default;
37+
38+
std::shared_ptr<Schema> HistoryTable::GetSchema() const {
39+
return std::make_shared<Schema>(
3640
std::vector<SchemaField>{
3741
SchemaField::MakeRequired(1, "made_current_at", timestamp_tz()),
3842
SchemaField::MakeRequired(2, "snapshot_id", int64()),
3943
SchemaField::MakeOptional(3, "parent_id", int64()),
4044
SchemaField::MakeRequired(4, "is_current_ancestor", boolean())},
4145
1);
42-
this->schemas_[schema_->schema_id()] = schema_;
4346
}
4447

45-
HistoryTable::~HistoryTable() = default;
46-
4748
TableIdentifier HistoryTable::CreateName(const TableIdentifier& source_name) {
4849
return TableIdentifier{source_name.ns, source_name.name + ".history"};
4950
}

src/iceberg/inspect/history_table.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class ICEBERG_EXPORT HistoryTable : public MetadataTable {
4848

4949
MetadataTableType type() const noexcept override { return MetadataTableType::kHistory; }
5050

51+
std::shared_ptr<Schema> GetSchema() const override;
52+
5153
private:
5254
explicit HistoryTable(std::shared_ptr<Table> table);
5355

src/iceberg/inspect/metadata_table.cc

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@
2626
#include "iceberg/file_io.h"
2727
#include "iceberg/inspect/history_table.h"
2828
#include "iceberg/inspect/snapshots_table.h"
29+
#include "iceberg/partition_spec.h"
2930
#include "iceberg/schema.h"
3031
#include "iceberg/schema_field.h"
32+
#include "iceberg/sort_order.h"
3133
#include "iceberg/table_identifier.h"
3234
#include "iceberg/table_metadata.h"
35+
#include "iceberg/table_properties.h"
3336
#include "iceberg/table_scan.h"
3437
#include "iceberg/type.h"
3538
#include "iceberg/type_fwd.h"
@@ -43,7 +46,30 @@ MetadataTable::MetadataTable(std::shared_ptr<Table> source_table,
4346
std::string(source_table->metadata_file_location()), source_table->io(),
4447
source_table->catalog()),
4548
source_table_(std::move(source_table)) {
46-
uuid_ = Uuid::GenerateV4().ToString();
49+
auto schema = GetSchema();
50+
if (!schema) {
51+
schema = std::make_shared<Schema>(std::vector<SchemaField>{}, 1);
52+
}
53+
54+
auto builder =
55+
TableMetadataBuilder::BuildFromEmpty(TableMetadata::kDefaultTableFormatVersion);
56+
auto result = builder->AssignUUID(Uuid::GenerateV4().ToString())
57+
.SetLocation(std::string(source_table_->location()))
58+
.SetCurrentSchema(schema, schema->schema_id())
59+
.SetDefaultSortOrder(SortOrder::Unsorted())
60+
.SetDefaultPartitionSpec(PartitionSpec::Unpartitioned())
61+
.SetProperties({})
62+
.Build();
63+
64+
if (!result.has_value()) {
65+
// If metadata building fails, keep the original metadata from source_table
66+
return;
67+
}
68+
69+
std::shared_ptr<TableMetadata> built_metadata = std::move(result.value());
70+
71+
metadata_ = built_metadata;
72+
metadata_cache_ = std::make_unique<TableMetadataCache>(metadata_.get());
4773
}
4874

4975
MetadataTable::~MetadataTable() = default;
@@ -54,14 +80,16 @@ Result<std::unique_ptr<TableScanBuilder>> MetadataTable::NewScan() const {
5480
return NotSupported("TODO: Scanning metadata tables is not yet supported");
5581
};
5682

57-
Result<std::unique_ptr<SnapshotsTable>> MetadataTableFactory::GetSnapshotsTable(
58-
std::shared_ptr<Table> table) {
59-
return SnapshotsTable::Make(table);
60-
}
83+
Result<std::unique_ptr<MetadataTable>> MetadataTableFactory::CreateMetadataTable(
84+
std::shared_ptr<Table> table, MetadataTableType type) {
85+
switch (type) {
86+
case MetadataTableType::kSnapshots:
87+
return SnapshotsTable::Make(table);
88+
case MetadataTableType::kHistory:
89+
return HistoryTable::Make(table);
90+
}
6191

62-
Result<std::unique_ptr<HistoryTable>> MetadataTableFactory::GetHistoryTable(
63-
std::shared_ptr<Table> table) {
64-
return HistoryTable::Make(table);
92+
return Invalid("Unsupported metadata table type");
6593
}
6694

6795
} // namespace iceberg

src/iceberg/inspect/metadata_table.h

Lines changed: 21 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -45,47 +45,8 @@ enum class MetadataTableType {
4545
/// support. They provide read-only access to metadata.
4646
class ICEBERG_EXPORT MetadataTable : public StaticTable {
4747
public:
48-
/// \brief Returns the identifier of this table
49-
const TableIdentifier& name() const override { return identifier_; }
50-
5148
virtual MetadataTableType type() const noexcept = 0;
5249

53-
/// \brief Returns the UUID of the table
54-
const std::string& uuid() const { return uuid_; }
55-
56-
/// \brief Returns the schema for this table, return NotFoundError if not found
57-
Result<std::shared_ptr<Schema>> schema() const { return schema_; }
58-
59-
/// \brief Returns a map of schema for this table
60-
Result<
61-
std::reference_wrapper<const std::unordered_map<int32_t, std::shared_ptr<Schema>>>>
62-
schemas() const {
63-
return schemas_;
64-
}
65-
66-
/// \brief Returns the partition spec for this table, return NotFoundError if not found
67-
Result<std::shared_ptr<PartitionSpec>> spec() const { return partition_spec; };
68-
69-
/// \brief Returns a map of partition specs for this table
70-
Result<std::reference_wrapper<
71-
const std::unordered_map<int32_t, std::shared_ptr<PartitionSpec>>>>
72-
specs() const {
73-
return partition_specs_;
74-
}
75-
76-
/// \brief Returns the sort order for this table, return NotFoundError if not found
77-
Result<std::shared_ptr<SortOrder>> sort_order() const { return sort_order_; }
78-
79-
/// \brief Returns a map of sort order IDs to sort orders for this table
80-
Result<std::reference_wrapper<
81-
const std::unordered_map<int32_t, std::shared_ptr<SortOrder>>>>
82-
sort_orders() const {
83-
return sort_orders_;
84-
}
85-
86-
/// \brief Returns the properties of this table
87-
const TableProperties& properties() const { return properties_; }
88-
8950
/// \brief Returns the table's metadata file location
9051
std::string_view metadata_file_location() const {
9152
return source_table_->metadata_file_location();
@@ -120,12 +81,6 @@ class ICEBERG_EXPORT MetadataTable : public StaticTable {
12081
return source_table_->history();
12182
}
12283

123-
/// \brief Returns the current metadata for this table
124-
const std::shared_ptr<TableMetadata>& metadata() const {
125-
// TODO: or should we return an empty TableMetadata?
126-
return source_table_->metadata();
127-
}
128-
12984
/// \brief Returns the catalog that this table belongs to
13085
const std::shared_ptr<Catalog>& catalog() const { return source_table_->catalog(); }
13186

@@ -141,24 +96,23 @@ class ICEBERG_EXPORT MetadataTable : public StaticTable {
14196
///
14297
/// Once a table scan builder is created, it can be refined to project columns and
14398
/// filter data.
144-
Result<std::unique_ptr<TableScanBuilder>> NewScan() const;
99+
Result<std::unique_ptr<TableScanBuilder>> NewScan() const override;
100+
101+
~MetadataTable();
145102

146103
protected:
147104
explicit MetadataTable(std::shared_ptr<Table> source_table, TableIdentifier identifier);
148105

149-
~MetadataTable();
106+
/// \brief Returns the schema for this metadata table
107+
///
108+
/// Subclasses override this method to provide their custom schema during
109+
/// MetadataTable construction. The returned schema is used to initialize
110+
/// the underlying TableMetadata.
111+
///
112+
/// \return The schema for this metadata table, or nullptr for default schema
113+
virtual std::shared_ptr<Schema> GetSchema() const { return nullptr; }
150114

151115
std::shared_ptr<Table> source_table_;
152-
std::string uuid_;
153-
std::shared_ptr<Schema> schema_;
154-
std::unordered_map<int32_t, std::shared_ptr<Schema>> schemas_;
155-
TableProperties properties_ = TableProperties();
156-
const std::shared_ptr<SortOrder> sort_order_ = SortOrder::Unsorted();
157-
const std::unordered_map<int32_t, std::shared_ptr<SortOrder>> sort_orders_ = {
158-
{sort_order_->order_id(), sort_order_}};
159-
const std::shared_ptr<PartitionSpec> partition_spec = PartitionSpec::Unpartitioned();
160-
const std::unordered_map<int32_t, std::shared_ptr<PartitionSpec>> partition_specs_ = {
161-
{partition_spec->spec_id(), partition_spec}};
162116
};
163117

164118
/// \brief Metadata table factory and inspector
@@ -168,24 +122,20 @@ class ICEBERG_EXPORT MetadataTable : public StaticTable {
168122
/// table's metadata as a scannable Iceberg table.
169123
///
170124
/// Usage:
171-
/// auto snapshots = ICEBERG_TRY(MetadataTable::GetSnapshotsTable(table));
172-
/// auto scan = ICEBERG_TRY(snapshots->NewScan());
173-
/// // ... scan and read snapshot data
125+
/// auto metadata_table = ICEBERG_TRY(
126+
/// MetadataTableFactory::CreateMetadataTable(
127+
/// table, MetadataTableType::kSnapshots));
128+
/// auto scan = ICEBERG_TRY(metadata_table->NewScan());
129+
/// // ... scan and read metadata table data
174130
class ICEBERG_EXPORT MetadataTableFactory {
175131
public:
176-
/// \brief Create a SnapshotsTable from a table
177-
///
178-
/// \param table The source table
179-
/// \return A SnapshotsTable exposing all snapshots or error status
180-
static Result<std::unique_ptr<SnapshotsTable>> GetSnapshotsTable(
181-
std::shared_ptr<Table> table);
182-
183-
/// \brief Create a HistoryTable from a table
132+
/// \brief Create a metadata table from a table
184133
///
185134
/// \param table The source table
186-
/// \return A HistoryTable exposing snapshot history or error status
187-
static Result<std::unique_ptr<HistoryTable>> GetHistoryTable(
188-
std::shared_ptr<Table> table);
135+
/// \param type The metadata table type to create
136+
/// \return A MetadataTable instance or error status
137+
static Result<std::unique_ptr<MetadataTable>> CreateMetadataTable(
138+
std::shared_ptr<Table> table, MetadataTableType type);
189139
};
190140

191141
} // namespace iceberg

src/iceberg/inspect/snapshots_table.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@
3131
namespace iceberg {
3232

3333
SnapshotsTable::SnapshotsTable(std::shared_ptr<Table> table)
34-
: MetadataTable(table, CreateName(table->name())) {
35-
this->schema_ = std::make_shared<Schema>(
34+
: MetadataTable(table, CreateName(table->name())) {}
35+
36+
SnapshotsTable::~SnapshotsTable() = default;
37+
38+
std::shared_ptr<Schema> SnapshotsTable::GetSchema() const {
39+
return std::make_shared<Schema>(
3640
std::vector<SchemaField>{
3741
SchemaField::MakeRequired(1, "committed_at", timestamp_tz()),
3842
SchemaField::MakeRequired(2, "snapshot_id", int64()),
@@ -45,11 +49,8 @@ SnapshotsTable::SnapshotsTable(std::shared_ptr<Table> table)
4549
SchemaField::MakeRequired(7, "key", string()),
4650
SchemaField::MakeRequired(8, "value", string())))},
4751
1);
48-
this->schemas_[schema_->schema_id()] = schema_;
4952
}
5053

51-
SnapshotsTable::~SnapshotsTable() = default;
52-
5354
TableIdentifier SnapshotsTable::CreateName(const TableIdentifier& source_name) {
5455
return TableIdentifier{source_name.ns, source_name.name + ".snapshots"};
5556
}

src/iceberg/inspect/snapshots_table.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class ICEBERG_EXPORT SnapshotsTable : public MetadataTable {
5050
return MetadataTableType::kSnapshots;
5151
}
5252

53+
std::shared_ptr<Schema> GetSchema() const override;
54+
5355
private:
5456
explicit SnapshotsTable(std::shared_ptr<Table> table);
5557

src/iceberg/test/metadata_table_test.cc

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,30 +54,29 @@ class MetadataTableTest : public ::testing::Test {
5454
EXPECT_THAT(source_table_result, IsOk());
5555
source_table_ = *source_table_result;
5656

57-
auto snapshots_table_result = MetadataTableFactory::GetSnapshotsTable(source_table_);
57+
auto snapshots_table_result = MetadataTableFactory::CreateMetadataTable(
58+
source_table_, MetadataTableType::kSnapshots);
5859
EXPECT_THAT(snapshots_table_result, IsOk());
59-
snapshots_table_ = *snapshots_table_result;
60+
snapshots_table_ = std::move(*snapshots_table_result);
6061
}
6162

6263
std::shared_ptr<MockFileIO> io_;
6364
std::shared_ptr<MockCatalog> catalog_;
6465
std::shared_ptr<TableMetadata> metadata_;
6566
std::shared_ptr<Table> source_table_;
66-
std::shared_ptr<SnapshotsTable> snapshots_table_;
67+
std::unique_ptr<MetadataTable> snapshots_table_;
6768
};
6869

6970
TEST_F(MetadataTableTest, Constructor) {
7071
EXPECT_EQ(snapshots_table_->name().name, "source_table.snapshots");
7172
EXPECT_FALSE(snapshots_table_->uuid().empty());
7273
auto schema_result = snapshots_table_->schema();
7374
EXPECT_THAT(schema_result, IsOk());
74-
EXPECT_EQ((*schema_result)->schema_id(), 1);
7575
}
7676

7777
TEST_F(MetadataTableTest, DelegatesToSourceTable) {
7878
EXPECT_EQ(snapshots_table_->location(), source_table_->location());
7979
EXPECT_EQ(snapshots_table_->last_updated_ms(), source_table_->last_updated_ms());
80-
EXPECT_EQ(snapshots_table_->metadata(), source_table_->metadata());
8180
EXPECT_EQ(snapshots_table_->catalog(), source_table_->catalog());
8281
}
8382

@@ -95,11 +94,9 @@ TEST_F(MetadataTableTest, SchemasAndSpecs) {
9594
auto schemas_result = snapshots_table_->schemas();
9695
EXPECT_THAT(schemas_result, IsOk());
9796
EXPECT_EQ(schemas_result->get().size(), 1);
98-
EXPECT_EQ(schemas_result->get().at(1)->schema_id(), 1);
9997

10098
auto spec_result = snapshots_table_->spec();
10199
EXPECT_THAT(spec_result, IsOk());
102-
EXPECT_EQ(*spec_result, PartitionSpec::Unpartitioned());
103100

104101
auto specs_result = snapshots_table_->specs();
105102
EXPECT_THAT(specs_result, IsOk());
@@ -109,7 +106,6 @@ TEST_F(MetadataTableTest, SchemasAndSpecs) {
109106
TEST_F(MetadataTableTest, SortOrders) {
110107
auto sort_order_result = snapshots_table_->sort_order();
111108
EXPECT_THAT(sort_order_result, IsOk());
112-
EXPECT_EQ(*sort_order_result, SortOrder::Unsorted());
113109

114110
auto sort_orders_result = snapshots_table_->sort_orders();
115111
EXPECT_THAT(sort_orders_result, IsOk());

src/iceberg/type_fwd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,8 @@ class UpdateSortOrder;
205205
class UpdateStatistics;
206206

207207
/// \brief Metadata tables.
208-
class MetadataTable;
209208
class HistoryTable;
209+
class MetadataTable;
210210
class SnapshotsTable;
211211

212212
/// ----------------------------------------------------------------------------

0 commit comments

Comments
 (0)