Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rust/arrow/src/datatypes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ pub enum IntervalUnit {
/// Indicates the number of elapsed whole months, stored as 4-byte integers.
YearMonth,
/// Indicates the number of elapsed days and milliseconds,
/// stored as 2 contiguous 32-bit integers (8-bytes in total).
/// stored as 2 contiguous 32-bit integers (days, milliseconds) (8-bytes in total).
DayTime,
}

Expand Down
70 changes: 69 additions & 1 deletion rust/arrow/src/util/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
//! purposes. See the `pretty` crate for additional functions for
//! record batch pretty printing.

use crate::array;
use crate::array::Array;
use crate::datatypes::{
ArrowNativeType, ArrowPrimitiveType, DataType, Int16Type, Int32Type, Int64Type,
Int8Type, TimeUnit, UInt16Type, UInt32Type, UInt64Type, UInt8Type,
};
use crate::{array, datatypes::IntervalUnit};

use array::DictionaryArray;

Expand All @@ -44,6 +44,66 @@ macro_rules! make_string {
}};
}

macro_rules! make_string_interval_year_month {
($column: ident, $row: ident) => {{
let array = $column
.as_any()
.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);

format!(
"{} years {} mons 0 days 0 hours 0 mins 0.00 secs",
years, month,
)
};

Ok(s)
}};
}

macro_rules! make_string_interval_day_time {
($column: ident, $row: ident) => {{
let array = $column
.as_any()
.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 secs = milliseconds_part / 1000;
let mins = secs / 60;
let hours = mins / 60;

let secs = secs - (mins * 60);
let mins = mins - (hours * 60);

format!(
"0 years 0 mons {} days {} hours {} mins {}.{:02} secs",
days_parts,
hours,
mins,
secs,
(milliseconds_part % 1000),
)
};

Ok(s)
}};
}

macro_rules! make_string_date {
($array_type:ty, $column: ident, $row: ident) => {{
let array = $column.as_any().downcast_ref::<$array_type>().unwrap();
Expand Down Expand Up @@ -180,6 +240,14 @@ pub fn array_value_to_string(column: &array::ArrayRef, row: usize) -> Result<Str
DataType::Time64(unit) if *unit == TimeUnit::Nanosecond => {
make_string_time!(array::Time64NanosecondArray, column, row)
}
DataType::Interval(unit) => match unit {
IntervalUnit::DayTime => {
make_string_interval_day_time!(column, row)
}
IntervalUnit::YearMonth => {
make_string_interval_year_month!(column, row)
}
},
DataType::List(_) => make_string_from_list!(column, row),
DataType::Dictionary(index_type, _value_type) => match **index_type {
DataType::Int8 => dict_array_value_to_string::<Int8Type>(column, row),
Expand Down
46 changes: 41 additions & 5 deletions rust/datafusion/src/scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@

use std::{convert::TryFrom, fmt, iter::repeat, sync::Arc};

use arrow::array::{
Array, BooleanArray, Date32Array, Float32Array, Float64Array, Int16Array, Int32Array,
Int64Array, Int8Array, LargeStringArray, ListArray, StringArray, UInt16Array,
UInt32Array, UInt64Array, UInt8Array,
};
use arrow::array::{
Int16Builder, Int32Builder, Int64Builder, Int8Builder, ListBuilder,
TimestampMicrosecondArray, TimestampNanosecondArray, UInt16Builder, UInt32Builder,
Expand All @@ -33,6 +28,15 @@ use arrow::{
array::ArrayRef,
datatypes::{DataType, Field},
};
use arrow::{
array::{
Array, BooleanArray, Date32Array, Float32Array, Float64Array, Int16Array,
Int32Array, Int64Array, Int8Array, IntervalDayTimeArray, IntervalYearMonthArray,
LargeStringArray, ListArray, StringArray, UInt16Array, UInt32Array, UInt64Array,
UInt8Array,
},
datatypes::IntervalUnit,
};

use crate::error::{DataFusionError, Result};
use arrow::datatypes::TimeUnit;
Expand Down Expand Up @@ -75,6 +79,10 @@ pub enum ScalarValue {
TimeMicrosecond(Option<i64>),
/// Timestamp Nanoseconds
TimeNanosecond(Option<i64>),
/// Interval with YearMonth unit
IntervalYearMonth(Option<i32>),
/// Interval with DayTime unit
IntervalDayTime(Option<i64>),
}

macro_rules! typed_cast {
Expand Down Expand Up @@ -148,6 +156,10 @@ impl ScalarValue {
DataType::List(Box::new(Field::new("item", data_type.clone(), true)))
}
ScalarValue::Date32(_) => DataType::Date32,
ScalarValue::IntervalYearMonth(_) => {
DataType::Interval(IntervalUnit::YearMonth)
}
ScalarValue::IntervalDayTime(_) => DataType::Interval(IntervalUnit::DayTime),
}
}

Expand Down Expand Up @@ -317,6 +329,22 @@ impl ScalarValue {
}
None => Arc::new(repeat(None).take(size).collect::<Date32Array>()),
},
ScalarValue::IntervalDayTime(e) => match e {
Some(value) => Arc::new(IntervalDayTimeArray::from_iter_values(
repeat(*value).take(size),
)),
None => {
Arc::new(repeat(None).take(size).collect::<IntervalDayTimeArray>())
}
},
ScalarValue::IntervalYearMonth(e) => match e {
Some(value) => Arc::new(IntervalYearMonthArray::from_iter_values(
repeat(*value).take(size),
)),
None => {
Arc::new(repeat(None).take(size).collect::<IntervalYearMonthArray>())
}
},
}
}

Expand Down Expand Up @@ -552,6 +580,8 @@ impl fmt::Display for ScalarValue {
None => write!(f, "NULL")?,
},
ScalarValue::Date32(e) => format_option!(f, e)?,
ScalarValue::IntervalDayTime(e) => format_option!(f, e)?,
ScalarValue::IntervalYearMonth(e) => format_option!(f, e)?,
};
Ok(())
}
Expand Down Expand Up @@ -579,6 +609,12 @@ impl fmt::Debug for ScalarValue {
ScalarValue::LargeUtf8(Some(_)) => write!(f, "LargeUtf8(\"{}\")", self),
ScalarValue::List(_, _) => write!(f, "List([{}])", self),
ScalarValue::Date32(_) => write!(f, "Date32(\"{}\")", self),
ScalarValue::IntervalDayTime(_) => {
write!(f, "IntervalDayTime(\"{}\")", self)
}
ScalarValue::IntervalYearMonth(_) => {
write!(f, "IntervalYearMonth(\"{}\")", self)
}
}
}
}
Expand Down
Loading