You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by xu...@apache.org on 2024/12/17 01:40:33 UTC
(iceberg-rust) branch main updated: feat: Add RemovePartitionSpecs table update (#804)
This is an automated email from the ASF dual-hosted git repository.
xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-rust.git
The following commit(s) were added to refs/heads/main by this push:
new fa8c9485 feat: Add RemovePartitionSpecs table update (#804)
fa8c9485 is described below
commit fa8c948538ebb7792365a295cc0ffa9b7fd0a127
Author: Christian <ch...@hansetag.com>
AuthorDate: Tue Dec 17 02:40:27 2024 +0100
feat: Add RemovePartitionSpecs table update (#804)
* RemovePartitionSpecs update
* address comments
* fix comments
---
crates/iceberg/src/catalog/mod.rs | 24 +++++++++++
crates/iceberg/src/spec/table_metadata_builder.rs | 52 +++++++++++++++++++++++
2 files changed, 76 insertions(+)
diff --git a/crates/iceberg/src/catalog/mod.rs b/crates/iceberg/src/catalog/mod.rs
index ffafc66f..cbda6c90 100644
--- a/crates/iceberg/src/catalog/mod.rs
+++ b/crates/iceberg/src/catalog/mod.rs
@@ -440,6 +440,12 @@ pub enum TableUpdate {
/// Properties to remove
removals: Vec<String>,
},
+ /// Remove partition specs
+ #[serde(rename_all = "kebab-case")]
+ RemovePartitionSpecs {
+ /// Partition spec ids to remove.
+ spec_ids: Vec<i32>,
+ },
/// Set statistics for a snapshot
#[serde(with = "_serde_set_statistics")]
SetStatistics {
@@ -494,6 +500,9 @@ impl TableUpdate {
TableUpdate::UpgradeFormatVersion { format_version } => {
builder.upgrade_format_version(format_version)
}
+ TableUpdate::RemovePartitionSpecs { spec_ids } => {
+ builder.remove_partition_specs(&spec_ids)
+ }
TableUpdate::SetStatistics { statistics } => Ok(builder.set_statistics(statistics)),
TableUpdate::RemoveStatistics { snapshot_id } => {
Ok(builder.remove_statistics(snapshot_id))
@@ -1910,6 +1919,21 @@ mod tests {
);
}
+ #[test]
+ fn test_remove_partition_specs_update() {
+ test_serde_json(
+ r#"
+{
+ "action": "remove-partition-specs",
+ "spec-ids": [1, 2]
+}
+ "#,
+ TableUpdate::RemovePartitionSpecs {
+ spec_ids: vec![1, 2],
+ },
+ );
+ }
+
#[test]
fn test_set_statistics_file() {
test_serde_json(
diff --git a/crates/iceberg/src/spec/table_metadata_builder.rs b/crates/iceberg/src/spec/table_metadata_builder.rs
index 5b4ff123..4e8c1ae7 100644
--- a/crates/iceberg/src/spec/table_metadata_builder.rs
+++ b/crates/iceberg/src/spec/table_metadata_builder.rs
@@ -784,6 +784,36 @@ impl TableMetadataBuilder {
.set_default_partition_spec(Self::LAST_ADDED)
}
+ /// Remove partition specs by their ids from the table metadata.
+ /// Does nothing if a spec id is not present. Active partition specs
+ /// should not be removed.
+ ///
+ /// # Errors
+ /// - Cannot remove the default partition spec.
+ pub fn remove_partition_specs(mut self, spec_ids: &[i32]) -> Result<Self> {
+ if spec_ids.contains(&self.metadata.default_spec.spec_id()) {
+ return Err(Error::new(
+ ErrorKind::DataInvalid,
+ "Cannot remove default partition spec",
+ ));
+ }
+
+ let mut removed_specs = Vec::with_capacity(spec_ids.len());
+ spec_ids.iter().for_each(|id| {
+ if self.metadata.partition_specs.remove(id).is_some() {
+ removed_specs.push(*id);
+ }
+ });
+
+ if !removed_specs.is_empty() {
+ self.changes.push(TableUpdate::RemovePartitionSpecs {
+ spec_ids: removed_specs,
+ });
+ }
+
+ Ok(self)
+ }
+
/// Add a sort order to the table metadata.
///
/// The spec is bound eagerly to the current schema and must be valid for it.
@@ -1584,6 +1614,21 @@ mod tests {
pretty_assertions::assert_eq!(build_result.changes[0], TableUpdate::AddSpec {
spec: expected_change
});
+
+ // Remove the spec
+ let build_result = build_result
+ .metadata
+ .into_builder(Some(
+ "s3://bucket/test/location/metadata/metadata1.json".to_string(),
+ ))
+ .remove_partition_specs(&[1])
+ .unwrap()
+ .build()
+ .unwrap();
+
+ assert_eq!(build_result.changes.len(), 1);
+ assert_eq!(build_result.metadata.partition_specs.len(), 1);
+ assert!(build_result.metadata.partition_spec_by_id(1).is_none());
}
#[test]
@@ -2193,6 +2238,13 @@ mod tests {
.contains("Cannot add snapshot with sequence number"));
}
+ #[test]
+ fn test_default_spec_cannot_be_removed() {
+ let builder = builder_without_changes(FormatVersion::V2);
+
+ builder.remove_partition_specs(&[0]).unwrap_err();
+ }
+
#[test]
fn test_statistics() {
let builder = builder_without_changes(FormatVersion::V2);