blob: 01612d765ecfe34b1ef4664af3b0b8a3ab971faf [file] [log] [blame]
/*
* 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/table_update.h"
#include "iceberg/schema.h"
#include "iceberg/snapshot.h"
#include "iceberg/sort_order.h"
#include "iceberg/statistics_file.h"
#include "iceberg/table_metadata.h"
#include "iceberg/table_requirements.h"
#include "iceberg/util/checked_cast.h"
#include "iceberg/util/macros.h"
namespace iceberg {
TableUpdate::~TableUpdate() = default;
}
namespace iceberg::table {
// AssignUUID
void AssignUUID::ApplyTo(TableMetadataBuilder& builder) const {
builder.AssignUUID(uuid_);
}
void AssignUUID::GenerateRequirements(TableUpdateContext& context) const {
// AssignUUID does not generate additional requirements.
}
bool AssignUUID::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kAssignUUID) {
return false;
}
const auto& other_assign = internal::checked_cast<const AssignUUID&>(other);
return uuid_ == other_assign.uuid_;
}
std::unique_ptr<TableUpdate> AssignUUID::Clone() const {
return std::make_unique<AssignUUID>(uuid_);
}
// UpgradeFormatVersion
void UpgradeFormatVersion::ApplyTo(TableMetadataBuilder& builder) const {
builder.UpgradeFormatVersion(format_version_);
}
void UpgradeFormatVersion::GenerateRequirements(TableUpdateContext& context) const {
// UpgradeFormatVersion doesn't generate any requirements
}
bool UpgradeFormatVersion::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kUpgradeFormatVersion) {
return false;
}
const auto& other_upgrade = internal::checked_cast<const UpgradeFormatVersion&>(other);
return format_version_ == other_upgrade.format_version_;
}
std::unique_ptr<TableUpdate> UpgradeFormatVersion::Clone() const {
return std::make_unique<UpgradeFormatVersion>(format_version_);
}
// AddSchema
void AddSchema::ApplyTo(TableMetadataBuilder& builder) const {
builder.AddSchema(schema_);
}
void AddSchema::GenerateRequirements(TableUpdateContext& context) const {
context.RequireLastAssignedFieldIdUnchanged();
}
bool AddSchema::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kAddSchema) {
return false;
}
const auto& other_add = internal::checked_cast<const AddSchema&>(other);
if (!schema_ != !other_add.schema_) {
return false;
}
if (schema_ && !(*schema_ == *other_add.schema_)) {
return false;
}
return last_column_id_ == other_add.last_column_id_;
}
std::unique_ptr<TableUpdate> AddSchema::Clone() const {
return std::make_unique<AddSchema>(schema_, last_column_id_);
}
// SetCurrentSchema
void SetCurrentSchema::ApplyTo(TableMetadataBuilder& builder) const {
builder.SetCurrentSchema(schema_id_);
}
void SetCurrentSchema::GenerateRequirements(TableUpdateContext& context) const {
context.RequireCurrentSchemaIdUnchanged();
}
bool SetCurrentSchema::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kSetCurrentSchema) {
return false;
}
const auto& other_set = internal::checked_cast<const SetCurrentSchema&>(other);
return schema_id_ == other_set.schema_id_;
}
std::unique_ptr<TableUpdate> SetCurrentSchema::Clone() const {
return std::make_unique<SetCurrentSchema>(schema_id_);
}
// AddPartitionSpec
void AddPartitionSpec::ApplyTo(TableMetadataBuilder& builder) const {
builder.AddPartitionSpec(spec_);
}
void AddPartitionSpec::GenerateRequirements(TableUpdateContext& context) const {
context.RequireLastAssignedPartitionIdUnchanged();
}
bool AddPartitionSpec::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kAddPartitionSpec) {
return false;
}
const auto& other_add = internal::checked_cast<const AddPartitionSpec&>(other);
if (!spec_ != !other_add.spec_) {
return false;
}
if (spec_ && *spec_ != *other_add.spec_) {
return false;
}
return true;
}
std::unique_ptr<TableUpdate> AddPartitionSpec::Clone() const {
return std::make_unique<AddPartitionSpec>(spec_);
}
// SetDefaultPartitionSpec
void SetDefaultPartitionSpec::ApplyTo(TableMetadataBuilder& builder) const {
builder.SetDefaultPartitionSpec(spec_id_);
}
void SetDefaultPartitionSpec::GenerateRequirements(TableUpdateContext& context) const {
context.RequireDefaultSpecIdUnchanged();
}
bool SetDefaultPartitionSpec::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kSetDefaultPartitionSpec) {
return false;
}
const auto& other_set = internal::checked_cast<const SetDefaultPartitionSpec&>(other);
return spec_id_ == other_set.spec_id_;
}
std::unique_ptr<TableUpdate> SetDefaultPartitionSpec::Clone() const {
return std::make_unique<SetDefaultPartitionSpec>(spec_id_);
}
// RemovePartitionSpecs
void RemovePartitionSpecs::ApplyTo(TableMetadataBuilder& builder) const {
builder.RemovePartitionSpecs(spec_ids_);
}
void RemovePartitionSpecs::GenerateRequirements(TableUpdateContext& context) const {
context.RequireDefaultSpecIdUnchanged();
context.RequireNoBranchesChanged();
}
bool RemovePartitionSpecs::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kRemovePartitionSpecs) {
return false;
}
const auto& other_remove = internal::checked_cast<const RemovePartitionSpecs&>(other);
return spec_ids_ == other_remove.spec_ids_;
}
std::unique_ptr<TableUpdate> RemovePartitionSpecs::Clone() const {
return std::make_unique<RemovePartitionSpecs>(spec_ids_);
}
// RemoveSchemas
void RemoveSchemas::ApplyTo(TableMetadataBuilder& builder) const {
builder.RemoveSchemas(schema_ids_);
}
void RemoveSchemas::GenerateRequirements(TableUpdateContext& context) const {
context.RequireCurrentSchemaIdUnchanged();
context.RequireNoBranchesChanged();
}
bool RemoveSchemas::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kRemoveSchemas) {
return false;
}
const auto& other_remove = internal::checked_cast<const RemoveSchemas&>(other);
return schema_ids_ == other_remove.schema_ids_;
}
std::unique_ptr<TableUpdate> RemoveSchemas::Clone() const {
return std::make_unique<RemoveSchemas>(schema_ids_);
}
// AddSortOrder
void AddSortOrder::ApplyTo(TableMetadataBuilder& builder) const {
builder.AddSortOrder(sort_order_);
}
void AddSortOrder::GenerateRequirements(TableUpdateContext& context) const {
// AddSortOrder doesn't generate any requirements
}
bool AddSortOrder::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kAddSortOrder) {
return false;
}
const auto& other_add = internal::checked_cast<const AddSortOrder&>(other);
if (!sort_order_ != !other_add.sort_order_) {
return false;
}
if (sort_order_ && !(*sort_order_ == *other_add.sort_order_)) {
return false;
}
return true;
}
std::unique_ptr<TableUpdate> AddSortOrder::Clone() const {
return std::make_unique<AddSortOrder>(sort_order_);
}
// SetDefaultSortOrder
void SetDefaultSortOrder::ApplyTo(TableMetadataBuilder& builder) const {
builder.SetDefaultSortOrder(sort_order_id_);
}
void SetDefaultSortOrder::GenerateRequirements(TableUpdateContext& context) const {
context.RequireDefaultSortOrderIdUnchanged();
}
bool SetDefaultSortOrder::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kSetDefaultSortOrder) {
return false;
}
const auto& other_set = internal::checked_cast<const SetDefaultSortOrder&>(other);
return sort_order_id_ == other_set.sort_order_id_;
}
std::unique_ptr<TableUpdate> SetDefaultSortOrder::Clone() const {
return std::make_unique<SetDefaultSortOrder>(sort_order_id_);
}
// AddSnapshot
void AddSnapshot::ApplyTo(TableMetadataBuilder& builder) const {
builder.AddSnapshot(snapshot_);
}
void AddSnapshot::GenerateRequirements(TableUpdateContext& context) const {
// AddSnapshot doesn't generate any requirements
}
bool AddSnapshot::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kAddSnapshot) {
return false;
}
const auto& other_add = internal::checked_cast<const AddSnapshot&>(other);
if (!snapshot_ != !other_add.snapshot_) {
return false;
}
if (snapshot_ && *snapshot_ != *other_add.snapshot_) {
return false;
}
return true;
}
std::unique_ptr<TableUpdate> AddSnapshot::Clone() const {
return std::make_unique<AddSnapshot>(snapshot_);
}
// RemoveSnapshots
void RemoveSnapshots::ApplyTo(TableMetadataBuilder& builder) const {
builder.RemoveSnapshots(snapshot_ids_);
}
void RemoveSnapshots::GenerateRequirements(TableUpdateContext& context) const {
// RemoveSnapshots doesn't generate any requirements
}
bool RemoveSnapshots::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kRemoveSnapshots) {
return false;
}
const auto& other_remove = internal::checked_cast<const RemoveSnapshots&>(other);
return snapshot_ids_ == other_remove.snapshot_ids_;
}
std::unique_ptr<TableUpdate> RemoveSnapshots::Clone() const {
return std::make_unique<RemoveSnapshots>(snapshot_ids_);
}
// RemoveSnapshotRef
void RemoveSnapshotRef::ApplyTo(TableMetadataBuilder& builder) const {
builder.RemoveRef(ref_name_);
}
void RemoveSnapshotRef::GenerateRequirements(TableUpdateContext& context) const {
// RemoveSnapshotRef doesn't generate any requirements
}
bool RemoveSnapshotRef::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kRemoveSnapshotRef) {
return false;
}
const auto& other_remove = internal::checked_cast<const RemoveSnapshotRef&>(other);
return ref_name_ == other_remove.ref_name_;
}
std::unique_ptr<TableUpdate> RemoveSnapshotRef::Clone() const {
return std::make_unique<RemoveSnapshotRef>(ref_name_);
}
// SetSnapshotRef
void SetSnapshotRef::ApplyTo(TableMetadataBuilder& builder) const {
std::shared_ptr<SnapshotRef> ref;
if (type_ == SnapshotRefType::kBranch) {
ICEBERG_ASSIGN_OR_THROW(
ref, SnapshotRef::MakeBranch(snapshot_id_, min_snapshots_to_keep_,
max_snapshot_age_ms_, max_ref_age_ms_));
} else {
ICEBERG_ASSIGN_OR_THROW(ref, SnapshotRef::MakeTag(snapshot_id_, max_ref_age_ms_));
}
builder.SetRef(ref_name_, std::move(ref));
}
void SetSnapshotRef::GenerateRequirements(TableUpdateContext& context) const {
bool added = context.AddChangedRef(ref_name_);
if (added && context.base() != nullptr && !context.is_replace()) {
const auto& refs = context.base()->refs;
auto it = refs.find(ref_name_);
// Require that the ref does not exist (nullopt) or is the same as the base snapshot
std::optional<int64_t> base_snapshot_id =
(it != refs.end()) ? std::make_optional(it->second->snapshot_id) : std::nullopt;
context.AddRequirement(
std::make_unique<table::AssertRefSnapshotID>(ref_name_, base_snapshot_id));
}
}
bool SetSnapshotRef::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kSetSnapshotRef) {
return false;
}
const auto& other_set = internal::checked_cast<const SetSnapshotRef&>(other);
return ref_name_ == other_set.ref_name_ && snapshot_id_ == other_set.snapshot_id_ &&
type_ == other_set.type_ &&
min_snapshots_to_keep_ == other_set.min_snapshots_to_keep_ &&
max_snapshot_age_ms_ == other_set.max_snapshot_age_ms_ &&
max_ref_age_ms_ == other_set.max_ref_age_ms_;
}
std::unique_ptr<TableUpdate> SetSnapshotRef::Clone() const {
return std::make_unique<SetSnapshotRef>(ref_name_, snapshot_id_, type_,
min_snapshots_to_keep_, max_snapshot_age_ms_,
max_ref_age_ms_);
}
// SetProperties
void SetProperties::ApplyTo(TableMetadataBuilder& builder) const {
builder.SetProperties(updated_);
}
void SetProperties::GenerateRequirements(TableUpdateContext& context) const {
// SetProperties doesn't generate any requirements
}
bool SetProperties::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kSetProperties) {
return false;
}
const auto& other_set = internal::checked_cast<const SetProperties&>(other);
return updated_ == other_set.updated_;
}
std::unique_ptr<TableUpdate> SetProperties::Clone() const {
return std::make_unique<SetProperties>(updated_);
}
// RemoveProperties
void RemoveProperties::ApplyTo(TableMetadataBuilder& builder) const {
builder.RemoveProperties(removed_);
}
void RemoveProperties::GenerateRequirements(TableUpdateContext& context) const {
// RemoveProperties doesn't generate any requirements
}
bool RemoveProperties::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kRemoveProperties) {
return false;
}
const auto& other_remove = internal::checked_cast<const RemoveProperties&>(other);
return removed_ == other_remove.removed_;
}
std::unique_ptr<TableUpdate> RemoveProperties::Clone() const {
return std::make_unique<RemoveProperties>(removed_);
}
// SetLocation
void SetLocation::ApplyTo(TableMetadataBuilder& builder) const {
builder.SetLocation(location_);
}
void SetLocation::GenerateRequirements(TableUpdateContext& context) const {
// SetLocation doesn't generate any requirements
}
bool SetLocation::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kSetLocation) {
return false;
}
const auto& other_set = internal::checked_cast<const SetLocation&>(other);
return location_ == other_set.location_;
}
std::unique_ptr<TableUpdate> SetLocation::Clone() const {
return std::make_unique<SetLocation>(location_);
}
// SetStatistics
int64_t SetStatistics::snapshot_id() const { return statistics_file_->snapshot_id; }
void SetStatistics::ApplyTo(TableMetadataBuilder& builder) const {
builder.SetStatistics(statistics_file_);
}
void SetStatistics::GenerateRequirements(TableUpdateContext& context) const {
// SetStatistics doesn't generate any requirements
}
bool SetStatistics::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kSetStatistics) {
return false;
}
const auto& other_set = internal::checked_cast<const SetStatistics&>(other);
if (!statistics_file_ != !other_set.statistics_file_) {
return false;
}
if (statistics_file_ && !(*statistics_file_ == *other_set.statistics_file_)) {
return false;
}
return true;
}
std::unique_ptr<TableUpdate> SetStatistics::Clone() const {
return std::make_unique<SetStatistics>(statistics_file_);
}
// RemoveStatistics
void RemoveStatistics::ApplyTo(TableMetadataBuilder& builder) const {
builder.RemoveStatistics(snapshot_id_);
}
void RemoveStatistics::GenerateRequirements(TableUpdateContext& context) const {
// RemoveStatistics doesn't generate any requirements
}
bool RemoveStatistics::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kRemoveStatistics) {
return false;
}
const auto& other_remove = internal::checked_cast<const RemoveStatistics&>(other);
return snapshot_id_ == other_remove.snapshot_id_;
}
std::unique_ptr<TableUpdate> RemoveStatistics::Clone() const {
return std::make_unique<RemoveStatistics>(snapshot_id_);
}
// SetPartitionStatistics
int64_t SetPartitionStatistics::snapshot_id() const {
return partition_statistics_file_->snapshot_id;
}
void SetPartitionStatistics::ApplyTo(TableMetadataBuilder& builder) const {
builder.SetPartitionStatistics(partition_statistics_file_);
}
void SetPartitionStatistics::GenerateRequirements(TableUpdateContext& context) const {
// SetPartitionStatistics doesn't generate any requirements
}
bool SetPartitionStatistics::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kSetPartitionStatistics) {
return false;
}
const auto& other_set = internal::checked_cast<const SetPartitionStatistics&>(other);
if (!partition_statistics_file_ != !other_set.partition_statistics_file_) {
return false;
}
if (partition_statistics_file_ &&
!(*partition_statistics_file_ == *other_set.partition_statistics_file_)) {
return false;
}
return true;
}
std::unique_ptr<TableUpdate> SetPartitionStatistics::Clone() const {
return std::make_unique<SetPartitionStatistics>(partition_statistics_file_);
}
// RemovePartitionStatistics
void RemovePartitionStatistics::ApplyTo(TableMetadataBuilder& builder) const {
builder.RemovePartitionStatistics(snapshot_id_);
}
void RemovePartitionStatistics::GenerateRequirements(TableUpdateContext& context) const {
// RemovePartitionStatistics doesn't generate any requirements
}
bool RemovePartitionStatistics::Equals(const TableUpdate& other) const {
if (other.kind() != Kind::kRemovePartitionStatistics) {
return false;
}
const auto& other_remove =
internal::checked_cast<const RemovePartitionStatistics&>(other);
return snapshot_id_ == other_remove.snapshot_id_;
}
std::unique_ptr<TableUpdate> RemovePartitionStatistics::Clone() const {
return std::make_unique<RemovePartitionStatistics>(snapshot_id_);
}
} // namespace iceberg::table