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 f17dd4d2 feat: Support `TimestampNs` and TimestampTzNs` in bucket
transform (#1150)
f17dd4d2 is described below
commit f17dd4d230116e16401733857e474083924a634c
Author: Jonathan Chen <[email protected]>
AuthorDate: Tue Apr 1 23:35:02 2025 -0400
feat: Support `TimestampNs` and TimestampTzNs` in bucket transform (#1150)
## Which issue does this PR close?
- Closes #1110 .
## What changes are included in this PR?
Add bucket transforms for `TimestampNs` and TimestampTzNs`
## Are these changes tested?
Unit tests
---------
Co-authored-by: Renjie Liu <[email protected]>
---
crates/iceberg/src/transform/bucket.rs | 82 ++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+)
diff --git a/crates/iceberg/src/transform/bucket.rs
b/crates/iceberg/src/transform/bucket.rs
index ce39826b..b64a4631 100644
--- a/crates/iceberg/src/transform/bucket.rs
+++ b/crates/iceberg/src/transform/bucket.rs
@@ -167,6 +167,16 @@ impl TransformFunction for Bucket {
.downcast_ref::<arrow_array::TimestampMicrosecondArray>()
.unwrap()
.unary(|v| self.bucket_timestamp(v)),
+ DataType::Time64(TimeUnit::Nanosecond) => input
+ .as_any()
+ .downcast_ref::<arrow_array::Time64NanosecondArray>()
+ .unwrap()
+ .unary(|v| self.bucket_time(v / 1000)),
+ DataType::Timestamp(TimeUnit::Nanosecond, _) => input
+ .as_any()
+ .downcast_ref::<arrow_array::TimestampNanosecondArray>()
+ .unwrap()
+ .unary(|v| self.bucket_timestamp(v / 1000)),
DataType::Utf8 => arrow_array::Int32Array::from_iter(
input
.as_any()
@@ -228,6 +238,13 @@ impl TransformFunction for Bucket {
(PrimitiveType::Date, PrimitiveLiteral::Int(v)) =>
self.bucket_date(*v),
(PrimitiveType::Time, PrimitiveLiteral::Long(v)) =>
self.bucket_time(*v),
(PrimitiveType::Timestamp, PrimitiveLiteral::Long(v)) =>
self.bucket_timestamp(*v),
+ (PrimitiveType::Timestamptz, PrimitiveLiteral::Long(v)) =>
self.bucket_timestamp(*v),
+ (PrimitiveType::TimestampNs, PrimitiveLiteral::Long(v)) => {
+ self.bucket_timestamp(*v / 1000)
+ }
+ (PrimitiveType::TimestamptzNs, PrimitiveLiteral::Long(v)) => {
+ self.bucket_timestamp(*v / 1000)
+ }
(PrimitiveType::String, PrimitiveLiteral::String(v)) =>
self.bucket_str(v.as_str()),
(PrimitiveType::Uuid, PrimitiveLiteral::UInt128(v)) => {
self.bucket_bytes(uuid::Uuid::from_u128(*v).as_ref())
@@ -250,6 +267,9 @@ impl TransformFunction for Bucket {
#[cfg(test)]
mod test {
+ use std::sync::Arc;
+
+ use arrow_array::{ArrayRef, Int32Array, TimestampMicrosecondArray,
TimestampNanosecondArray};
use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime};
use super::Bucket;
@@ -888,4 +908,66 @@ mod test {
Datum::int(32)
);
}
+
+ #[test]
+ fn test_timestamptz_literal() {
+ let bucket = Bucket::new(100);
+ assert_eq!(
+ bucket
+
.transform_literal(&Datum::timestamptz_micros(1510871468000000))
+ .unwrap()
+ .unwrap(),
+ Datum::int(7)
+ );
+ }
+
+ #[test]
+ fn test_timestamp_ns_literal() {
+ let bucket = Bucket::new(100);
+ let ns_value = 1510871468000000i64 * 1000;
+ assert_eq!(
+ bucket
+ .transform_literal(&Datum::timestamp_nanos(ns_value))
+ .unwrap()
+ .unwrap(),
+ Datum::int(7)
+ );
+ }
+
+ #[test]
+ fn test_timestamptz_ns_literal() {
+ let bucket = Bucket::new(100);
+ let ns_value = 1510871468000000i64 * 1000;
+ assert_eq!(
+ bucket
+ .transform_literal(&Datum::timestamptz_nanos(ns_value))
+ .unwrap()
+ .unwrap(),
+ Datum::int(7)
+ );
+ }
+
+ #[test]
+ fn test_transform_timestamp_nanos_and_micros_array_equivalence() {
+ let bucket = Bucket::new(100);
+ let micros_value = 1510871468000000;
+ let nanos_value = micros_value * 1000;
+
+ let micro_array =
TimestampMicrosecondArray::from_iter_values(vec![micros_value]);
+ let nano_array =
TimestampNanosecondArray::from_iter_values(vec![nanos_value]);
+
+ let transformed_micro: ArrayRef =
bucket.transform(Arc::new(micro_array)).unwrap();
+ let transformed_nano: ArrayRef =
bucket.transform(Arc::new(nano_array)).unwrap();
+
+ let micro_result = transformed_micro
+ .as_any()
+ .downcast_ref::<Int32Array>()
+ .unwrap();
+ let nano_result = transformed_nano
+ .as_any()
+ .downcast_ref::<Int32Array>()
+ .unwrap();
+
+ assert_eq!(micro_result.value(0), nano_result.value(0));
+ }
}