Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/iceberg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,15 @@ set(ICEBERG_SOURCES
file_io_registry.cc
file_reader.cc
file_writer.cc
inspect/branches_table.cc
inspect/files_table.cc
inspect/history_table.cc
inspect/manifests_table.cc
inspect/metadata_table.cc
inspect/metadata_table_util_internal.cc
inspect/partitions_table.cc
inspect/snapshots_table.cc
inspect/tags_table.cc
inheritable_metadata.cc
json_serde.cc
location_provider.cc
Expand Down
2 changes: 2 additions & 0 deletions src/iceberg/arrow_row_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ ArrowRowBuilder::~ArrowRowBuilder() {

int64_t ArrowRowBuilder::num_columns() const { return array_.n_children; }

int64_t ArrowRowBuilder::num_rows() const { return array_.length; }

ArrowArray* ArrowRowBuilder::column(int64_t index) {
if (index < 0 || index >= array_.n_children) {
return nullptr;
Expand Down
3 changes: 3 additions & 0 deletions src/iceberg/arrow_row_builder_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ class ICEBERG_EXPORT ArrowRowBuilder {
/// \brief The number of top-level columns in the batch.
int64_t num_columns() const;

/// \brief The number of completed rows in the batch.
int64_t num_rows() const;

/// \brief Access the nanoarrow child builder for a top-level column.
///
/// \param index Zero-based column index. Returns nullptr if out of range.
Expand Down
108 changes: 108 additions & 0 deletions src/iceberg/inspect/branches_table.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#include "iceberg/inspect/branches_table.h"

#include <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "iceberg/arrow_row_builder_internal.h"
#include "iceberg/inspect/metadata_table_stream_internal.h"
#include "iceberg/schema.h"
#include "iceberg/schema_field.h"
#include "iceberg/snapshot.h"
#include "iceberg/table.h"
#include "iceberg/table_metadata.h"
#include "iceberg/type.h"
#include "iceberg/util/macros.h"

namespace iceberg {
namespace {

struct BranchRow {
std::string name;
int64_t snapshot_id;
std::optional<int64_t> max_ref_age_ms;
std::optional<int32_t> min_snapshots_to_keep;
std::optional<int64_t> max_snapshot_age_ms;
};

Status AppendOptional(ArrowArray* array, const auto& value) {
if (!value.has_value()) {
return AppendNull(array);
}
return AppendInt(array, static_cast<int64_t>(*value));
}

Status AppendBranch(ArrowRowBuilder& builder, const BranchRow& branch) {
ICEBERG_RETURN_UNEXPECTED(AppendString(builder.column(0), branch.name));
ICEBERG_RETURN_UNEXPECTED(AppendInt(builder.column(1), branch.snapshot_id));
ICEBERG_RETURN_UNEXPECTED(AppendOptional(builder.column(2), branch.max_ref_age_ms));
ICEBERG_RETURN_UNEXPECTED(
AppendOptional(builder.column(3), branch.min_snapshots_to_keep));
ICEBERG_RETURN_UNEXPECTED(
AppendOptional(builder.column(4), branch.max_snapshot_age_ms));
return builder.FinishRow();
}

} // namespace

BranchesTable::BranchesTable(std::shared_ptr<Table> table)
: MetadataTable(std::move(table)) {}

BranchesTable::~BranchesTable() = default;

const std::shared_ptr<Schema>& BranchesTable::schema() const {
static const auto schema = std::make_shared<Schema>(std::vector<SchemaField>{
SchemaField::MakeRequired(1, "name", string()),
SchemaField::MakeRequired(2, "snapshot_id", int64()),
SchemaField::MakeOptional(3, "max_reference_age_in_ms", int64()),
SchemaField::MakeOptional(4, "min_snapshots_to_keep", int32()),
SchemaField::MakeOptional(5, "max_snapshot_age_in_ms", int64()),
});
return schema;
}

Result<std::unique_ptr<BranchesTable>> BranchesTable::Make(std::shared_ptr<Table> table) {
ICEBERG_PRECHECK(table != nullptr, "Table cannot be null");
return std::unique_ptr<BranchesTable>(new BranchesTable(std::move(table)));
}

Result<ArrowArrayStream> BranchesTable::Scan() {
std::vector<BranchRow> rows;
for (const auto& [name, ref] : source_table()->metadata()->refs) {
if (ref == nullptr || ref->type() != SnapshotRefType::kBranch) {
continue;
}
const auto& retention = std::get<SnapshotRef::Branch>(ref->retention);
rows.push_back(BranchRow{.name = name,
.snapshot_id = ref->snapshot_id,
.max_ref_age_ms = retention.max_ref_age_ms,
.min_snapshots_to_keep = retention.min_snapshots_to_keep,
.max_snapshot_age_ms = retention.max_snapshot_age_ms});
}
std::ranges::sort(rows, {}, &BranchRow::name);
return internal::MakeMetadataTableStream(*schema(), std::move(rows), AppendBranch);
}

} // namespace iceberg
51 changes: 51 additions & 0 deletions src/iceberg/inspect/branches_table.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#pragma once

/// \file iceberg/inspect/branches_table.h
/// \brief Define the branches metadata table.

#include <memory>

#include "iceberg/iceberg_export.h"
#include "iceberg/inspect/metadata_table.h"
#include "iceberg/result.h"
#include "iceberg/type_fwd.h"

namespace iceberg {

/// \brief Metadata table containing the table's branch snapshot references.
class ICEBERG_EXPORT BranchesTable : public MetadataTable {
public:
static Result<std::unique_ptr<BranchesTable>> Make(std::shared_ptr<Table> table);

~BranchesTable() override;

Kind kind() const noexcept override { return Kind::kBranches; }

const std::shared_ptr<Schema>& schema() const override;

Result<ArrowArrayStream> Scan() override;

private:
explicit BranchesTable(std::shared_ptr<Table> table);
};

} // namespace iceberg
75 changes: 75 additions & 0 deletions src/iceberg/inspect/files_table.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#include "iceberg/inspect/files_table.h"

#include <memory>
#include <utility>

#include "iceberg/inspect/metadata_table_stream_internal.h"
#include "iceberg/inspect/metadata_table_util_internal.h"
#include "iceberg/schema.h"
#include "iceberg/table.h"
#include "iceberg/type.h"
#include "iceberg/util/macros.h"

namespace iceberg {

FilesTable::FilesTable(std::shared_ptr<Table> table, std::shared_ptr<Schema> schema,
std::shared_ptr<Schema> table_schema,
std::shared_ptr<StructType> partition_type)
: TimeTravelMetadataTable(std::move(table)),
schema_(std::move(schema)),
table_schema_(std::move(table_schema)),
partition_type_(std::move(partition_type)) {}

FilesTable::~FilesTable() = default;

const std::shared_ptr<Schema>& FilesTable::schema() const { return schema_; }

Result<std::unique_ptr<FilesTable>> FilesTable::Make(std::shared_ptr<Table> table) {
ICEBERG_PRECHECK(table != nullptr, "Table cannot be null");
ICEBERG_ASSIGN_OR_RAISE(auto table_schema, table->schema());
ICEBERG_ASSIGN_OR_RAISE(auto partition_type, internal::UnifiedPartitionType(*table));
ICEBERG_ASSIGN_OR_RAISE(auto schema,
internal::FilesTableSchema(*table_schema, partition_type));
return std::unique_ptr<FilesTable>(new FilesTable(std::move(table), std::move(schema),
std::move(table_schema),
std::move(partition_type)));
}

Result<ArrowArrayStream> FilesTable::ScanSnapshot(
const SnapshotSelection& snapshot_selection) {
ICEBERG_ASSIGN_OR_RAISE(auto snapshot, internal::ResolveMetadataTableSnapshot(
*source_table(), snapshot_selection));
ICEBERG_ASSIGN_OR_RAISE(auto files, internal::LoadLiveFiles(*source_table(), snapshot));
auto schema = schema_;
auto table_schema = table_schema_;
auto partition_type = partition_type_;
return internal::MakeMetadataTableStream(
*schema_, std::move(files),
[schema = std::move(schema), table_schema = std::move(table_schema),
partition_type = std::move(partition_type)](ArrowRowBuilder& builder,
const internal::LiveFile& file) {
return internal::AppendDataFile(builder, *schema, *table_schema, *partition_type,
file);
});
}

} // namespace iceberg
59 changes: 59 additions & 0 deletions src/iceberg/inspect/files_table.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#pragma once

/// \file iceberg/inspect/files_table.h
/// \brief Define the files metadata table.

#include <memory>

#include "iceberg/iceberg_export.h"
#include "iceberg/inspect/metadata_table.h"
#include "iceberg/result.h"
#include "iceberg/type_fwd.h"

namespace iceberg {

/// \brief Metadata table containing live data and delete files in a snapshot.
class ICEBERG_EXPORT FilesTable : public TimeTravelMetadataTable {
public:
static Result<std::unique_ptr<FilesTable>> Make(std::shared_ptr<Table> table);

~FilesTable() override;

Kind kind() const noexcept override { return Kind::kFiles; }

const std::shared_ptr<Schema>& schema() const override;

protected:
Result<ArrowArrayStream> ScanSnapshot(
const SnapshotSelection& snapshot_selection) override;

private:
FilesTable(std::shared_ptr<Table> table, std::shared_ptr<Schema> schema,
std::shared_ptr<Schema> table_schema,
std::shared_ptr<StructType> partition_type);

std::shared_ptr<Schema> schema_;
std::shared_ptr<Schema> table_schema_;
std::shared_ptr<StructType> partition_type_;
};

} // namespace iceberg
33 changes: 14 additions & 19 deletions src/iceberg/inspect/history_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,32 @@
#include "iceberg/schema.h"
#include "iceberg/schema_field.h"
#include "iceberg/table.h"
#include "iceberg/table_identifier.h"
#include "iceberg/type.h"
#include "iceberg/util/macros.h"

namespace iceberg {
namespace {

std::shared_ptr<Schema> MakeHistoryTableSchema() {
return std::make_shared<Schema>(std::vector<SchemaField>{
HistoryTable::HistoryTable(std::shared_ptr<Table> table)
: MetadataTable(std::move(table)) {}

HistoryTable::~HistoryTable() = default;

const std::shared_ptr<Schema>& HistoryTable::schema() const {
static const auto schema = std::make_shared<Schema>(std::vector<SchemaField>{
SchemaField::MakeRequired(1, "made_current_at", timestamp_tz()),
SchemaField::MakeRequired(2, "snapshot_id", int64()),
SchemaField::MakeOptional(3, "parent_id", int64()),
SchemaField::MakeRequired(4, "is_current_ancestor", boolean())});
return schema;
}

TableIdentifier MakeHistoryTableName(const TableIdentifier& source_name) {
return TableIdentifier{.ns = source_name.ns, .name = source_name.name + ".history"};
}

} // namespace

HistoryTable::HistoryTable(std::shared_ptr<Table> table)
: MetadataTable(table, MakeHistoryTableName(table->name()),
MakeHistoryTableSchema()) {}

HistoryTable::~HistoryTable() = default;

Result<std::unique_ptr<HistoryTable>> HistoryTable::Make(std::shared_ptr<Table> table) {
if (table == nullptr) [[unlikely]] {
return InvalidArgument("Table cannot be null");
}
ICEBERG_PRECHECK(table != nullptr, "Table cannot be null");
return std::unique_ptr<HistoryTable>(new HistoryTable(std::move(table)));
}

Result<ArrowArrayStream> HistoryTable::Scan() {
return NotSupported("Scan is not supported for the history table");
}

} // namespace iceberg
4 changes: 4 additions & 0 deletions src/iceberg/inspect/history_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ class ICEBERG_EXPORT HistoryTable : public MetadataTable {

Kind kind() const noexcept override { return Kind::kHistory; }

const std::shared_ptr<Schema>& schema() const override;

Result<ArrowArrayStream> Scan() override;

private:
explicit HistoryTable(std::shared_ptr<Table> table);
};
Expand Down
Loading