This is an automated email from the ASF dual-hosted git repository.
liurenjie1024 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 bdb8bf7c feat: support more partition transformations for
PartitionSpec::partition_to_path (#1730)
bdb8bf7c is described below
commit bdb8bf7c6a55d30ae474b12535b22024144dea56
Author: Mrinal Paliwal <[email protected]>
AuthorDate: Sat Oct 11 09:13:31 2025 +0530
feat: support more partition transformations for
PartitionSpec::partition_to_path (#1730)
## Which issue does this PR close?
- Closes #1729 .
## What changes are included in this PR?
- Support more transformation types in `Transform::to_human_string`
- Change visibility of few methods to pub
## Are these changes tested?
Updated existing unit test
Co-authored-by: Renjie Liu <[email protected]>
---
crates/iceberg/src/spec/partition.rs | 20 +++++++++++++++++---
crates/iceberg/src/spec/transform.rs | 24 +++++++++++-------------
crates/iceberg/src/spec/values.rs | 2 +-
3 files changed, 29 insertions(+), 17 deletions(-)
diff --git a/crates/iceberg/src/spec/partition.rs
b/crates/iceberg/src/spec/partition.rs
index 128db338..b594895c 100644
--- a/crates/iceberg/src/spec/partition.rs
+++ b/crates/iceberg/src/spec/partition.rs
@@ -155,7 +155,9 @@ impl PartitionSpec {
true
}
- pub(crate) fn partition_to_path(&self, data: &Struct, schema: SchemaRef)
-> String {
+ /// Returns partition path string containing partition type and partition
+ /// value as key-value pairs.
+ pub fn partition_to_path(&self, data: &Struct, schema: SchemaRef) ->
String {
let partition_type = self.partition_type(&schema).unwrap();
let field_types = partition_type.fields();
@@ -1813,6 +1815,9 @@ mod tests {
.with_fields(vec![
NestedField::required(1, "id",
Type::Primitive(PrimitiveType::Int)).into(),
NestedField::required(2, "name",
Type::Primitive(PrimitiveType::String)).into(),
+ NestedField::required(3, "timestamp",
Type::Primitive(PrimitiveType::Timestamp))
+ .into(),
+ NestedField::required(4, "empty",
Type::Primitive(PrimitiveType::String)).into(),
])
.build()
.unwrap();
@@ -1822,14 +1827,23 @@ mod tests {
.unwrap()
.add_partition_field("name", "name", Transform::Identity)
.unwrap()
+ .add_partition_field("timestamp", "ts_hour", Transform::Hour)
+ .unwrap()
+ .add_partition_field("empty", "empty_void", Transform::Void)
+ .unwrap()
.build()
.unwrap();
- let data = Struct::from_iter([Some(Literal::int(42)),
Some(Literal::string("alice"))]);
+ let data = Struct::from_iter([
+ Some(Literal::int(42)),
+ Some(Literal::string("alice")),
+ Some(Literal::int(1000)),
+ Some(Literal::string("empty")),
+ ]);
assert_eq!(
spec.partition_to_path(&data, schema.into()),
- "id=42/name=alice"
+ "id=42/name=alice/ts_hour=1000/empty_void=null"
);
}
}
diff --git a/crates/iceberg/src/spec/transform.rs
b/crates/iceberg/src/spec/transform.rs
index 8b6d2225..d69d15c2 100644
--- a/crates/iceberg/src/spec/transform.rs
+++ b/crates/iceberg/src/spec/transform.rs
@@ -137,19 +137,17 @@ pub enum Transform {
impl Transform {
/// Returns a human-readable String representation of a transformed value.
pub fn to_human_string(&self, field_type: &Type, value: Option<&Literal>)
-> String {
- if let Some(value) = value {
- if let Some(value) = value.as_primitive_literal() {
- let field_type = field_type.as_primitive_type().unwrap();
- let datum = Datum::new(field_type.clone(), value);
- match self {
- Self::Identity => datum.to_human_string(),
- Self::Void => "null".to_string(),
- _ => {
- todo!()
- }
- }
- } else {
- "null".to_string()
+ let Some(value) = value else {
+ return "null".to_string();
+ };
+
+ if let Some(value) = value.as_primitive_literal() {
+ let field_type = field_type.as_primitive_type().unwrap();
+ let datum = Datum::new(field_type.clone(), value);
+
+ match self {
+ Self::Void => "null".to_string(),
+ _ => datum.to_human_string(),
}
} else {
"null".to_string()
diff --git a/crates/iceberg/src/spec/values.rs
b/crates/iceberg/src/spec/values.rs
index 7f214810..8d56604b 100644
--- a/crates/iceberg/src/spec/values.rs
+++ b/crates/iceberg/src/spec/values.rs
@@ -1271,7 +1271,7 @@ impl Datum {
///
/// For string literals, this returns the raw string value without quotes.
/// For all other literals, it falls back to [`to_string()`].
- pub(crate) fn to_human_string(&self) -> String {
+ pub fn to_human_string(&self) -> String {
match self.literal() {
PrimitiveLiteral::String(s) => s.to_string(),
_ => self.to_string(),