This is an automated email from the ASF dual-hosted git repository.

CTTY 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 aa58d2fdd feat(partition): adjust transform boundary for timestamp 
types (#2422)
aa58d2fdd is described below

commit aa58d2fdde4516cd6c1081d5c43c42dde6775955
Author: dentiny <[email protected]>
AuthorDate: Tue May 19 15:46:17 2026 -0700

    feat(partition): adjust transform boundary for timestamp types (#2422)
    
    ## Which issue does this PR close?
    
    - Closes https://github.com/apache/iceberg-rust/issues/2421
    
    ## What changes are included in this PR?
    
    This PR implements boundary adjustment for timestamp types, which could
    potentially avoid scan unnecessary extra partition; hopefully my issue
    description is clear enough.
    
    ## Are these changes tested?
    
    Yes.
---
 crates/iceberg/src/spec/transform.rs | 58 ++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/crates/iceberg/src/spec/transform.rs 
b/crates/iceberg/src/spec/transform.rs
index 73fd290ee..97ab638e7 100644
--- a/crates/iceberg/src/spec/transform.rs
+++ b/crates/iceberg/src/spec/transform.rs
@@ -667,6 +667,15 @@ impl Transform {
                 (PrimitiveType::Timestamp, PrimitiveLiteral::Long(v)) => {
                     Some(Datum::timestamp_micros(v - 1))
                 }
+                (PrimitiveType::Timestamptz, PrimitiveLiteral::Long(v)) => {
+                    Some(Datum::timestamptz_micros(v - 1))
+                }
+                (PrimitiveType::TimestampNs, PrimitiveLiteral::Long(v)) => {
+                    Some(Datum::timestamp_nanos(v - 1))
+                }
+                (PrimitiveType::TimestamptzNs, PrimitiveLiteral::Long(v)) => {
+                    Some(Datum::timestamptz_nanos(v - 1))
+                }
                 _ => Some(datum.to_owned()),
             },
             PredicateOperator::GreaterThan => match (datum.data_type(), 
datum.literal()) {
@@ -679,6 +688,15 @@ impl Transform {
                 (PrimitiveType::Timestamp, PrimitiveLiteral::Long(v)) => {
                     Some(Datum::timestamp_micros(v + 1))
                 }
+                (PrimitiveType::Timestamptz, PrimitiveLiteral::Long(v)) => {
+                    Some(Datum::timestamptz_micros(v + 1))
+                }
+                (PrimitiveType::TimestampNs, PrimitiveLiteral::Long(v)) => {
+                    Some(Datum::timestamp_nanos(v + 1))
+                }
+                (PrimitiveType::TimestamptzNs, PrimitiveLiteral::Long(v)) => {
+                    Some(Datum::timestamptz_nanos(v + 1))
+                }
                 _ => Some(datum.to_owned()),
             },
             PredicateOperator::Eq
@@ -1062,3 +1080,43 @@ enum AdjustedProjection {
     Single(Datum),
     Set(FnvHashSet<Datum>),
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    fn check_boundary(op: PredicateOperator, input: Datum, expected: Datum) {
+        let result = Transform::adjust_boundary(&op, &input).unwrap().unwrap();
+        assert_eq!(result, expected);
+    }
+
+    #[test]
+    fn test_adjust_boundary_timestamp_types() {
+        for (datum, dec, inc) in [
+            (
+                Datum::timestamptz_micros(1000),
+                Datum::timestamptz_micros(999),
+                Datum::timestamptz_micros(1001),
+            ),
+            (
+                Datum::timestamp_nanos(5000),
+                Datum::timestamp_nanos(4999),
+                Datum::timestamp_nanos(5001),
+            ),
+            (
+                Datum::timestamptz_nanos(5000),
+                Datum::timestamptz_nanos(4999),
+                Datum::timestamptz_nanos(5001),
+            ),
+        ] {
+            check_boundary(PredicateOperator::LessThan, datum.clone(), dec);
+            check_boundary(PredicateOperator::GreaterThan, datum.clone(), inc);
+            check_boundary(
+                PredicateOperator::LessThanOrEq,
+                datum.clone(),
+                datum.clone(),
+            );
+            check_boundary(PredicateOperator::GreaterThanOrEq, datum.clone(), 
datum);
+        }
+    }
+}

Reply via email to