You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by tu...@apache.org on 2022/11/26 13:18:29 UTC
[arrow-rs] branch master updated: Support Duration in array_value_to_string (#3183)
This is an automated email from the ASF dual-hosted git repository.
tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/master by this push:
new 8c6e57960 Support Duration in array_value_to_string (#3183)
8c6e57960 is described below
commit 8c6e57960f92c0fad9982caba32f226e318313d9
Author: Vrishabh <ps...@gmail.com>
AuthorDate: Sat Nov 26 18:48:24 2022 +0530
Support Duration in array_value_to_string (#3183)
* Improve array_value_to_string
* Fix fmt issues
* Reverting to safe calls
---
arrow-cast/src/display.rs | 252 +++++++++++++++++++++++-----------------------
1 file changed, 128 insertions(+), 124 deletions(-)
diff --git a/arrow-cast/src/display.rs b/arrow-cast/src/display.rs
index 434f750af..287065eb6 100644
--- a/arrow-cast/src/display.rs
+++ b/arrow-cast/src/display.rs
@@ -32,13 +32,7 @@ macro_rules! make_string {
($array_type:ty, $column: ident, $row: ident) => {{
let array = $column.as_any().downcast_ref::<$array_type>().unwrap();
- let s = if array.is_null($row) {
- "".to_string()
- } else {
- array.value($row).to_string()
- };
-
- Ok(s)
+ Ok(array.value($row).to_string())
}};
}
@@ -49,20 +43,14 @@ macro_rules! make_string_interval_year_month {
.downcast_ref::<array::IntervalYearMonthArray>()
.unwrap();
- let s = if array.is_null($row) {
- "NULL".to_string()
- } else {
- let interval = array.value($row) as f64;
- let years = (interval / 12_f64).floor();
- let month = interval - (years * 12_f64);
+ let interval = array.value($row) as f64;
+ let years = (interval / 12_f64).floor();
+ let month = interval - (years * 12_f64);
- format!(
- "{} years {} mons 0 days 0 hours 0 mins 0.00 secs",
- years, month,
- )
- };
-
- Ok(s)
+ Ok(format!(
+ "{} years {} mons 0 days 0 hours 0 mins 0.00 secs",
+ years, month,
+ ))
}};
}
@@ -73,32 +61,26 @@ macro_rules! make_string_interval_day_time {
.downcast_ref::<array::IntervalDayTimeArray>()
.unwrap();
- let s = if array.is_null($row) {
- "NULL".to_string()
- } else {
- let value: u64 = array.value($row) as u64;
-
- let days_parts: i32 = ((value & 0xFFFFFFFF00000000) >> 32) as i32;
- let milliseconds_part: i32 = (value & 0xFFFFFFFF) as i32;
+ let value: u64 = array.value($row) as u64;
- let secs = milliseconds_part / 1000;
- let mins = secs / 60;
- let hours = mins / 60;
+ let days_parts: i32 = ((value & 0xFFFFFFFF00000000) >> 32) as i32;
+ let milliseconds_part: i32 = (value & 0xFFFFFFFF) as i32;
- let secs = secs - (mins * 60);
- let mins = mins - (hours * 60);
+ let secs = milliseconds_part / 1000;
+ let mins = secs / 60;
+ let hours = mins / 60;
- format!(
- "0 years 0 mons {} days {} hours {} mins {}.{:03} secs",
- days_parts,
- hours,
- mins,
- secs,
- (milliseconds_part % 1000),
- )
- };
+ let secs = secs - (mins * 60);
+ let mins = mins - (hours * 60);
- Ok(s)
+ Ok(format!(
+ "0 years 0 mons {} days {} hours {} mins {}.{:03} secs",
+ days_parts,
+ hours,
+ mins,
+ secs,
+ (milliseconds_part % 1000),
+ ))
}};
}
@@ -109,35 +91,29 @@ macro_rules! make_string_interval_month_day_nano {
.downcast_ref::<array::IntervalMonthDayNanoArray>()
.unwrap();
- let s = if array.is_null($row) {
- "NULL".to_string()
- } else {
- let value: u128 = array.value($row) as u128;
-
- let months_part: i32 =
- ((value & 0xFFFFFFFF000000000000000000000000) >> 96) as i32;
- let days_part: i32 = ((value & 0xFFFFFFFF0000000000000000) >> 64) as i32;
- let nanoseconds_part: i64 = (value & 0xFFFFFFFFFFFFFFFF) as i64;
-
- let secs = nanoseconds_part / 1000000000;
- let mins = secs / 60;
- let hours = mins / 60;
-
- let secs = secs - (mins * 60);
- let mins = mins - (hours * 60);
-
- format!(
- "0 years {} mons {} days {} hours {} mins {}.{:09} secs",
- months_part,
- days_part,
- hours,
- mins,
- secs,
- (nanoseconds_part % 1000000000),
- )
- };
+ let value: u128 = array.value($row) as u128;
- Ok(s)
+ let months_part: i32 =
+ ((value & 0xFFFFFFFF000000000000000000000000) >> 96) as i32;
+ let days_part: i32 = ((value & 0xFFFFFFFF0000000000000000) >> 64) as i32;
+ let nanoseconds_part: i64 = (value & 0xFFFFFFFFFFFFFFFF) as i64;
+
+ let secs = nanoseconds_part / 1000000000;
+ let mins = secs / 60;
+ let hours = mins / 60;
+
+ let secs = secs - (mins * 60);
+ let mins = mins - (hours * 60);
+
+ Ok(format!(
+ "0 years {} mons {} days {} hours {} mins {}.{:09} secs",
+ months_part,
+ days_part,
+ hours,
+ mins,
+ secs,
+ (nanoseconds_part % 1000000000),
+ ))
}};
}
@@ -145,16 +121,10 @@ macro_rules! make_string_date {
($array_type:ty, $column: ident, $row: ident) => {{
let array = $column.as_any().downcast_ref::<$array_type>().unwrap();
- let s = if array.is_null($row) {
- "".to_string()
- } else {
- array
- .value_as_date($row)
- .map(|d| d.to_string())
- .unwrap_or_else(|| "ERROR CONVERTING DATE".to_string())
- };
-
- Ok(s)
+ Ok(array
+ .value_as_date($row)
+ .map(|d| d.to_string())
+ .unwrap_or_else(|| "ERROR CONVERTING DATE".to_string()))
}};
}
@@ -162,16 +132,10 @@ macro_rules! make_string_time {
($array_type:ty, $column: ident, $row: ident) => {{
let array = $column.as_any().downcast_ref::<$array_type>().unwrap();
- let s = if array.is_null($row) {
- "".to_string()
- } else {
- array
- .value_as_time($row)
- .map(|d| d.to_string())
- .unwrap_or_else(|| "ERROR CONVERTING DATE".to_string())
- };
-
- Ok(s)
+ Ok(array
+ .value_as_time($row)
+ .map(|d| d.to_string())
+ .unwrap_or_else(|| "ERROR CONVERTING DATE".to_string()))
}};
}
@@ -179,16 +143,10 @@ macro_rules! make_string_datetime {
($array_type:ty, $column: ident, $row: ident) => {{
let array = $column.as_any().downcast_ref::<$array_type>().unwrap();
- let s = if array.is_null($row) {
- "".to_string()
- } else {
- array
- .value_as_datetime($row)
- .map(|d| format!("{:?}", d))
- .unwrap_or_else(|| "ERROR CONVERTING DATE".to_string())
- };
-
- Ok(s)
+ Ok(array
+ .value_as_datetime($row)
+ .map(|d| format!("{:?}", d))
+ .unwrap_or_else(|| "ERROR CONVERTING DATE".to_string()))
}};
}
@@ -196,19 +154,15 @@ macro_rules! make_string_datetime_with_tz {
($array_type:ty, $tz_string: ident, $column: ident, $row: ident) => {{
let array = $column.as_any().downcast_ref::<$array_type>().unwrap();
- let s = if array.is_null($row) {
- "".to_string()
- } else {
- match $tz_string.parse::<Tz>() {
- Ok(tz) => array
- .value_as_datetime_with_tz($row, tz)
- .map(|d| format!("{}", d.to_rfc3339()))
- .unwrap_or_else(|| "ERROR CONVERTING DATE".to_string()),
- Err(_) => array
- .value_as_datetime($row)
- .map(|d| format!("{:?} (Unknown Time Zone '{}')", d, $tz_string))
- .unwrap_or_else(|| "ERROR CONVERTING DATE".to_string()),
- }
+ let s = match $tz_string.parse::<Tz>() {
+ Ok(tz) => array
+ .value_as_datetime_with_tz($row, tz)
+ .map(|d| format!("{}", d.to_rfc3339()))
+ .unwrap_or_else(|| "ERROR CONVERTING DATE".to_string()),
+ Err(_) => array
+ .value_as_datetime($row)
+ .map(|d| format!("{:?} (Unknown Time Zone '{}')", d, $tz_string))
+ .unwrap_or_else(|| "ERROR CONVERTING DATE".to_string()),
};
Ok(s)
@@ -220,19 +174,13 @@ macro_rules! make_string_hex {
($array_type:ty, $column: ident, $row: ident) => {{
let array = $column.as_any().downcast_ref::<$array_type>().unwrap();
- let s = if array.is_null($row) {
- "".to_string()
- } else {
- let mut tmp = "".to_string();
+ let mut tmp = "".to_string();
- for character in array.value($row) {
- let _ = write!(tmp, "{:02x}", character);
- }
-
- tmp
- };
+ for character in array.value($row) {
+ let _ = write!(tmp, "{:02x}", character);
+ }
- Ok(s)
+ Ok(tmp)
}};
}
@@ -284,6 +232,17 @@ macro_rules! make_string_from_fixed_size_list {
}};
}
+macro_rules! make_string_from_duration {
+ ($array_type:ty, $column: ident, $row: ident) => {{
+ let array = $column.as_any().downcast_ref::<$array_type>().unwrap();
+
+ Ok(array
+ .value_as_duration($row)
+ .map(|d| d.to_string())
+ .unwrap_or_else(|| "ERROR CONVERTING DATE".to_string()))
+ }};
+}
+
#[inline(always)]
pub fn make_string_from_decimal(
column: &Arc<dyn Array>,
@@ -474,6 +433,20 @@ pub fn array_value_to_string(
DataType::Union(field_vec, type_ids, mode) => {
union_to_string(column, row, field_vec, type_ids, mode)
}
+ DataType::Duration(unit) => match *unit {
+ TimeUnit::Second => {
+ make_string_from_duration!(array::DurationSecondArray, column, row)
+ }
+ TimeUnit::Millisecond => {
+ make_string_from_duration!(array::DurationMillisecondArray, column, row)
+ }
+ TimeUnit::Microsecond => {
+ make_string_from_duration!(array::DurationMicrosecondArray, column, row)
+ }
+ TimeUnit::Nanosecond => {
+ make_string_from_duration!(array::DurationNanosecondArray, column, row)
+ }
+ },
_ => Err(ArrowError::InvalidArgumentError(format!(
"Pretty printing not implemented for {:?} type",
column.data_type()
@@ -549,3 +522,34 @@ pub fn lexical_to_string<N: lexical_core::ToLexical>(n: N) -> String {
String::from_utf8_unchecked(buf)
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_array_value_to_string_duration() {
+ let ns_array =
+ Arc::new(DurationNanosecondArray::from(vec![Some(1), None])) as ArrayRef;
+ assert_eq!(
+ array_value_to_string(&ns_array, 0).unwrap(),
+ "PT0.000000001S"
+ );
+ assert_eq!(array_value_to_string(&ns_array, 1).unwrap(), "");
+
+ let us_array =
+ Arc::new(DurationMicrosecondArray::from(vec![Some(1), None])) as ArrayRef;
+ assert_eq!(array_value_to_string(&us_array, 0).unwrap(), "PT0.000001S");
+ assert_eq!(array_value_to_string(&us_array, 1).unwrap(), "");
+
+ let ms_array =
+ Arc::new(DurationMillisecondArray::from(vec![Some(1), None])) as ArrayRef;
+ assert_eq!(array_value_to_string(&ms_array, 0).unwrap(), "PT0.001S");
+ assert_eq!(array_value_to_string(&ms_array, 1).unwrap(), "");
+
+ let s_array =
+ Arc::new(DurationSecondArray::from(vec![Some(1), None])) as ArrayRef;
+ assert_eq!(array_value_to_string(&s_array, 0).unwrap(), "PT1S");
+ assert_eq!(array_value_to_string(&s_array, 1).unwrap(), "");
+ }
+}