From 03d8d0ee7eda7827a3e8c75db7e64e00aa9eea2e Mon Sep 17 00:00:00 2001 From: PierreDubrulle Date: Sun, 12 Nov 2023 18:37:28 +0100 Subject: [PATCH] Skip serializing optional fields if they're null Fixes #1847 --- .../deltalake-core/src/operations/update.rs | 1 - crates/deltalake-core/src/table/mod.rs | 35 ++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/crates/deltalake-core/src/operations/update.rs b/crates/deltalake-core/src/operations/update.rs index 559f28868d..9f51912579 100644 --- a/crates/deltalake-core/src/operations/update.rs +++ b/crates/deltalake-core/src/operations/update.rs @@ -737,7 +737,6 @@ mod tests { .with_update("value", col("value") + lit(1)) .await .unwrap(); - assert_eq!(table.version(), 1); assert_eq!(table.get_file_uris().count(), 1); assert_eq!(metrics.num_added_files, 1); diff --git a/crates/deltalake-core/src/table/mod.rs b/crates/deltalake-core/src/table/mod.rs index cd0f1808f5..33fdea2ad0 100644 --- a/crates/deltalake-core/src/table/mod.rs +++ b/crates/deltalake-core/src/table/mod.rs @@ -47,14 +47,18 @@ pub struct CheckPoint { pub(crate) version: i64, // 20 digits decimals /// The number of actions that are stored in the checkpoint. pub(crate) size: i64, + #[serde(skip_serializing_if = "Option::is_none")] /// The number of fragments if the last checkpoint was written in multiple parts. This field is optional. pub(crate) parts: Option, // 10 digits decimals + #[serde(skip_serializing_if = "Option::is_none")] /// The number of bytes of the checkpoint. This field is optional. pub(crate) size_in_bytes: Option, + #[serde(skip_serializing_if = "Option::is_none")] /// The number of AddFile actions in the checkpoint. This field is optional. pub(crate) num_of_add_files: Option, } +#[derive(Default)] /// Builder for CheckPoint pub struct CheckPointBuilder { /// Delta table version @@ -118,7 +122,7 @@ impl CheckPoint { Self { version, size, - parts, + parts: parts.or(None), size_in_bytes: None, num_of_add_files: None, } @@ -909,6 +913,35 @@ mod tests { drop(tmp_dir); } + #[tokio::test] + async fn checkpoint_without_added_files_and_no_parts() { + let (dt, tmp_dir) = create_test_table().await; + let check_point = CheckPointBuilder::new(0, 0).build(); + let checkpoint_data_paths = dt.get_checkpoint_data_paths(&check_point); + assert_eq!(checkpoint_data_paths.len(), 1); + assert_eq!( + serde_json::to_string(&check_point).unwrap(), + "{\"version\":0,\"size\":0}" + ); + drop(tmp_dir); + } + + #[tokio::test] + async fn checkpoint_with_added_files() { + let num_of_file_added: i64 = 4; + let (dt, tmp_dir) = create_test_table().await; + let check_point = CheckPointBuilder::new(0, 0) + .with_num_of_add_files(num_of_file_added) + .build(); + let checkpoint_data_paths = dt.get_checkpoint_data_paths(&check_point); + assert_eq!(checkpoint_data_paths.len(), 1); + assert_eq!( + serde_json::to_string(&check_point).unwrap(), + "{\"version\":0,\"size\":0,\"num_of_add_files\":4}" + ); + drop(tmp_dir); + } + #[cfg(any(feature = "s3", feature = "s3-native-tls"))] #[test] fn normalize_table_uri_s3() {