diff --git a/crates/iceberg/src/transaction/append.rs b/crates/iceberg/src/transaction/append.rs index 6e719163d..f248543df 100644 --- a/crates/iceberg/src/transaction/append.rs +++ b/crates/iceberg/src/transaction/append.rs @@ -208,6 +208,36 @@ mod tests { ); } + #[tokio::test] + async fn test_append_snapshot_properties() { + let table = make_v2_minimal_table(); + let tx = Transaction::new(&table); + + let mut snapshot_properties = HashMap::new(); + snapshot_properties.insert("key".to_string(), "val".to_string()); + + let action = tx + .fast_append() + .set_snapshot_properties(snapshot_properties); + let mut action_commit = Arc::new(action).commit(&table).await.unwrap(); + let updates = action_commit.take_updates(); + + // Check customized properties is contained in snapshot summary properties. + let new_snapshot = if let TableUpdate::AddSnapshot { snapshot } = &updates[0] { + snapshot + } else { + unreachable!() + }; + assert_eq!( + new_snapshot + .summary() + .additional_properties + .get("key") + .unwrap(), + "val" + ); + } + #[tokio::test] async fn test_fast_append_file_with_incompatible_partition_value() { let table = make_v2_minimal_table(); diff --git a/crates/iceberg/src/transaction/snapshot.rs b/crates/iceberg/src/transaction/snapshot.rs index 092f9fb2d..48dc2b5b9 100644 --- a/crates/iceberg/src/transaction/snapshot.rs +++ b/crates/iceberg/src/transaction/snapshot.rs @@ -254,7 +254,7 @@ impl<'a> SnapshotProducer<'a> { if added_data_files.is_empty() { return Err(Error::new( ErrorKind::PreconditionFailed, - "No added data files found when write a manifest file", + "No added data files found when write an added manifest file", )); } @@ -284,13 +284,30 @@ impl<'a> SnapshotProducer<'a> { snapshot_produce_operation: &OP, manifest_process: &MP, ) -> Result> { - let added_manifest = self.write_added_manifest().await?; + // Assert current snapshot producer contains new content to add to new snapshot. + // + // TODO: Allowing snapshot property setup with no added data files is a workaround. + // We should clean it up after all necessary actions are supported. + // For details, please refer to https://github.com/apache/iceberg-rust/issues/1548 + if self.added_data_files.is_empty() && self.snapshot_properties.is_empty() { + return Err(Error::new( + ErrorKind::PreconditionFailed, + "No added data files or added snapshot properties found when write a manifest file", + )); + } + let existing_manifests = snapshot_produce_operation.existing_manifest(self).await?; + let mut manifest_files = existing_manifests; + + // Process added entries. + if !self.added_data_files.is_empty() { + let added_manifest = self.write_added_manifest().await?; + manifest_files.push(added_manifest); + } + // # TODO // Support process delete entries. - let mut manifest_files = vec![added_manifest]; - manifest_files.extend(existing_manifests); let manifest_files = manifest_process.process_manifests(self, manifest_files); Ok(manifest_files) }