diff --git a/datafusion/common/src/scalar.rs b/datafusion/common/src/scalar.rs index e84ef545198e..96a52f858ed1 100644 --- a/datafusion/common/src/scalar.rs +++ b/datafusion/common/src/scalar.rs @@ -132,6 +132,14 @@ pub enum ScalarValue { /// Months and days are encoded as 32-bit signed integers. /// Nanoseconds is encoded as a 64-bit signed integer (no leap seconds). IntervalMonthDayNano(Option), + /// Duration in seconds + DurationSecond(Option), + /// Duration in milliseconds + DurationMillisecond(Option), + /// Duration in microseconds + DurationMicrosecond(Option), + /// Duration in nanoseconds + DurationNanosecond(Option), /// struct of nested ScalarValue Struct(Option>, Fields), /// Dictionary type: index type and value @@ -210,6 +218,14 @@ impl PartialEq for ScalarValue { (TimestampMicrosecond(_, _), _) => false, (TimestampNanosecond(v1, _), TimestampNanosecond(v2, _)) => v1.eq(v2), (TimestampNanosecond(_, _), _) => false, + (DurationSecond(v1), DurationSecond(v2)) => v1.eq(v2), + (DurationSecond(_), _) => false, + (DurationMillisecond(v1), DurationMillisecond(v2)) => v1.eq(v2), + (DurationMillisecond(_), _) => false, + (DurationMicrosecond(v1), DurationMicrosecond(v2)) => v1.eq(v2), + (DurationMicrosecond(_), _) => false, + (DurationNanosecond(v1), DurationNanosecond(v2)) => v1.eq(v2), + (DurationNanosecond(_), _) => false, (IntervalYearMonth(v1), IntervalYearMonth(v2)) => v1.eq(v2), (IntervalYearMonth(v1), IntervalDayTime(v2)) => { ym_to_milli(v1).eq(&dt_to_milli(v2)) @@ -357,6 +373,14 @@ impl PartialOrd for ScalarValue { mdn_to_nano(v1).partial_cmp(&dt_to_nano(v2)) } (IntervalMonthDayNano(_), _) => None, + (DurationSecond(v1), DurationSecond(v2)) => v1.partial_cmp(v2), + (DurationSecond(_), _) => None, + (DurationMillisecond(v1), DurationMillisecond(v2)) => v1.partial_cmp(v2), + (DurationMillisecond(_), _) => None, + (DurationMicrosecond(v1), DurationMicrosecond(v2)) => v1.partial_cmp(v2), + (DurationMicrosecond(_), _) => None, + (DurationNanosecond(v1), DurationNanosecond(v2)) => v1.partial_cmp(v2), + (DurationNanosecond(_), _) => None, (Struct(v1, t1), Struct(v2, t2)) => { if t1.eq(t2) { v1.partial_cmp(v2) @@ -1508,6 +1532,10 @@ impl std::hash::Hash for ScalarValue { TimestampMillisecond(v, _) => v.hash(state), TimestampMicrosecond(v, _) => v.hash(state), TimestampNanosecond(v, _) => v.hash(state), + DurationSecond(v) => v.hash(state), + DurationMillisecond(v) => v.hash(state), + DurationMicrosecond(v) => v.hash(state), + DurationNanosecond(v) => v.hash(state), IntervalYearMonth(v) => v.hash(state), IntervalDayTime(v) => v.hash(state), IntervalMonthDayNano(v) => v.hash(state), @@ -1984,6 +2012,16 @@ impl ScalarValue { ScalarValue::IntervalMonthDayNano(_) => { DataType::Interval(IntervalUnit::MonthDayNano) } + ScalarValue::DurationSecond(_) => DataType::Duration(TimeUnit::Second), + ScalarValue::DurationMillisecond(_) => { + DataType::Duration(TimeUnit::Millisecond) + } + ScalarValue::DurationMicrosecond(_) => { + DataType::Duration(TimeUnit::Microsecond) + } + ScalarValue::DurationNanosecond(_) => { + DataType::Duration(TimeUnit::Nanosecond) + } ScalarValue::Struct(_, fields) => DataType::Struct(fields.clone()), ScalarValue::Dictionary(k, v) => { DataType::Dictionary(k.clone(), Box::new(v.get_datatype())) @@ -2118,6 +2156,10 @@ impl ScalarValue { ScalarValue::IntervalYearMonth(v) => v.is_none(), ScalarValue::IntervalDayTime(v) => v.is_none(), ScalarValue::IntervalMonthDayNano(v) => v.is_none(), + ScalarValue::DurationSecond(v) => v.is_none(), + ScalarValue::DurationMillisecond(v) => v.is_none(), + ScalarValue::DurationMicrosecond(v) => v.is_none(), + ScalarValue::DurationNanosecond(v) => v.is_none(), ScalarValue::Struct(v, _) => v.is_none(), ScalarValue::Dictionary(_, v) => v.is_null(), } @@ -2897,6 +2939,34 @@ impl ScalarValue { e, size ), + ScalarValue::DurationSecond(e) => build_array_from_option!( + Duration, + TimeUnit::Second, + DurationSecondArray, + e, + size + ), + ScalarValue::DurationMillisecond(e) => build_array_from_option!( + Duration, + TimeUnit::Millisecond, + DurationMillisecondArray, + e, + size + ), + ScalarValue::DurationMicrosecond(e) => build_array_from_option!( + Duration, + TimeUnit::Microsecond, + DurationMicrosecondArray, + e, + size + ), + ScalarValue::DurationNanosecond(e) => build_array_from_option!( + Duration, + TimeUnit::Nanosecond, + DurationNanosecondArray, + e, + size + ), ScalarValue::Struct(values, fields) => match values { Some(values) => { let field_values: Vec<_> = fields @@ -3264,6 +3334,18 @@ impl ScalarValue { ScalarValue::IntervalMonthDayNano(val) => { eq_array_primitive!(array, index, IntervalMonthDayNanoArray, val) } + ScalarValue::DurationSecond(val) => { + eq_array_primitive!(array, index, DurationSecondArray, val) + } + ScalarValue::DurationMillisecond(val) => { + eq_array_primitive!(array, index, DurationMillisecondArray, val) + } + ScalarValue::DurationMicrosecond(val) => { + eq_array_primitive!(array, index, DurationMicrosecondArray, val) + } + ScalarValue::DurationNanosecond(val) => { + eq_array_primitive!(array, index, DurationNanosecondArray, val) + } ScalarValue::Struct(_, _) => unimplemented!(), ScalarValue::Dictionary(key_type, v) => { let (values_array, values_index) = match key_type.as_ref() { @@ -3313,7 +3395,11 @@ impl ScalarValue { | ScalarValue::Time64Nanosecond(_) | ScalarValue::IntervalYearMonth(_) | ScalarValue::IntervalDayTime(_) - | ScalarValue::IntervalMonthDayNano(_) => 0, + | ScalarValue::IntervalMonthDayNano(_) + | ScalarValue::DurationSecond(_) + | ScalarValue::DurationMillisecond(_) + | ScalarValue::DurationMicrosecond(_) + | ScalarValue::DurationNanosecond(_) => 0, ScalarValue::Utf8(s) | ScalarValue::LargeUtf8(s) => { s.as_ref().map(|s| s.capacity()).unwrap_or_default() } @@ -3699,6 +3785,10 @@ impl fmt::Display for ScalarValue { ScalarValue::IntervalDayTime(e) => format_option!(f, e)?, ScalarValue::IntervalYearMonth(e) => format_option!(f, e)?, ScalarValue::IntervalMonthDayNano(e) => format_option!(f, e)?, + ScalarValue::DurationSecond(e) => format_option!(f, e)?, + ScalarValue::DurationMillisecond(e) => format_option!(f, e)?, + ScalarValue::DurationMicrosecond(e) => format_option!(f, e)?, + ScalarValue::DurationNanosecond(e) => format_option!(f, e)?, ScalarValue::Struct(e, fields) => match e { Some(l) => write!( f, @@ -3781,6 +3871,16 @@ impl fmt::Debug for ScalarValue { ScalarValue::IntervalMonthDayNano(_) => { write!(f, "IntervalMonthDayNano(\"{self}\")") } + ScalarValue::DurationSecond(_) => write!(f, "DurationSecond(\"{self}\")"), + ScalarValue::DurationMillisecond(_) => { + write!(f, "DurationMillisecond(\"{self}\")") + } + ScalarValue::DurationMicrosecond(_) => { + write!(f, "DurationMicrosecond(\"{self}\")") + } + ScalarValue::DurationNanosecond(_) => { + write!(f, "DurationNanosecond(\"{self}\")") + } ScalarValue::Struct(e, fields) => { // Use Debug representation of field values match e { diff --git a/datafusion/proto/proto/datafusion.proto b/datafusion/proto/proto/datafusion.proto index de334dc4a5cc..fa37a591e719 100644 --- a/datafusion/proto/proto/datafusion.proto +++ b/datafusion/proto/proto/datafusion.proto @@ -904,6 +904,12 @@ message ScalarValue{ int64 date_64_value = 21; int32 interval_yearmonth_value = 24; int64 interval_daytime_value = 25; + + int64 duration_second_value = 35; + int64 duration_millisecond_value = 36; + int64 duration_microsecond_value = 37; + int64 duration_nanosecond_value = 38; + ScalarTimestampValue timestamp_value = 26; ScalarDictionaryValue dictionary_value = 27; bytes binary_value = 28; diff --git a/datafusion/proto/src/generated/pbjson.rs b/datafusion/proto/src/generated/pbjson.rs index 1cf08be321e1..ea16927a49e5 100644 --- a/datafusion/proto/src/generated/pbjson.rs +++ b/datafusion/proto/src/generated/pbjson.rs @@ -18938,6 +18938,18 @@ impl serde::Serialize for ScalarValue { scalar_value::Value::IntervalDaytimeValue(v) => { struct_ser.serialize_field("intervalDaytimeValue", ToString::to_string(&v).as_str())?; } + scalar_value::Value::DurationSecondValue(v) => { + struct_ser.serialize_field("durationSecondValue", ToString::to_string(&v).as_str())?; + } + scalar_value::Value::DurationMillisecondValue(v) => { + struct_ser.serialize_field("durationMillisecondValue", ToString::to_string(&v).as_str())?; + } + scalar_value::Value::DurationMicrosecondValue(v) => { + struct_ser.serialize_field("durationMicrosecondValue", ToString::to_string(&v).as_str())?; + } + scalar_value::Value::DurationNanosecondValue(v) => { + struct_ser.serialize_field("durationNanosecondValue", ToString::to_string(&v).as_str())?; + } scalar_value::Value::TimestampValue(v) => { struct_ser.serialize_field("timestampValue", v)?; } @@ -19016,6 +19028,14 @@ impl<'de> serde::Deserialize<'de> for ScalarValue { "intervalYearmonthValue", "interval_daytime_value", "intervalDaytimeValue", + "duration_second_value", + "durationSecondValue", + "duration_millisecond_value", + "durationMillisecondValue", + "duration_microsecond_value", + "durationMicrosecondValue", + "duration_nanosecond_value", + "durationNanosecondValue", "timestamp_value", "timestampValue", "dictionary_value", @@ -19057,6 +19077,10 @@ impl<'de> serde::Deserialize<'de> for ScalarValue { Date64Value, IntervalYearmonthValue, IntervalDaytimeValue, + DurationSecondValue, + DurationMillisecondValue, + DurationMicrosecondValue, + DurationNanosecondValue, TimestampValue, DictionaryValue, BinaryValue, @@ -19107,6 +19131,10 @@ impl<'de> serde::Deserialize<'de> for ScalarValue { "date64Value" | "date_64_value" => Ok(GeneratedField::Date64Value), "intervalYearmonthValue" | "interval_yearmonth_value" => Ok(GeneratedField::IntervalYearmonthValue), "intervalDaytimeValue" | "interval_daytime_value" => Ok(GeneratedField::IntervalDaytimeValue), + "durationSecondValue" | "duration_second_value" => Ok(GeneratedField::DurationSecondValue), + "durationMillisecondValue" | "duration_millisecond_value" => Ok(GeneratedField::DurationMillisecondValue), + "durationMicrosecondValue" | "duration_microsecond_value" => Ok(GeneratedField::DurationMicrosecondValue), + "durationNanosecondValue" | "duration_nanosecond_value" => Ok(GeneratedField::DurationNanosecondValue), "timestampValue" | "timestamp_value" => Ok(GeneratedField::TimestampValue), "dictionaryValue" | "dictionary_value" => Ok(GeneratedField::DictionaryValue), "binaryValue" | "binary_value" => Ok(GeneratedField::BinaryValue), @@ -19267,6 +19295,30 @@ impl<'de> serde::Deserialize<'de> for ScalarValue { } value__ = map.next_value::<::std::option::Option<::pbjson::private::NumberDeserialize<_>>>()?.map(|x| scalar_value::Value::IntervalDaytimeValue(x.0)); } + GeneratedField::DurationSecondValue => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("durationSecondValue")); + } + value__ = map.next_value::<::std::option::Option<::pbjson::private::NumberDeserialize<_>>>()?.map(|x| scalar_value::Value::DurationSecondValue(x.0)); + } + GeneratedField::DurationMillisecondValue => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("durationMillisecondValue")); + } + value__ = map.next_value::<::std::option::Option<::pbjson::private::NumberDeserialize<_>>>()?.map(|x| scalar_value::Value::DurationMillisecondValue(x.0)); + } + GeneratedField::DurationMicrosecondValue => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("durationMicrosecondValue")); + } + value__ = map.next_value::<::std::option::Option<::pbjson::private::NumberDeserialize<_>>>()?.map(|x| scalar_value::Value::DurationMicrosecondValue(x.0)); + } + GeneratedField::DurationNanosecondValue => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("durationNanosecondValue")); + } + value__ = map.next_value::<::std::option::Option<::pbjson::private::NumberDeserialize<_>>>()?.map(|x| scalar_value::Value::DurationNanosecondValue(x.0)); + } GeneratedField::TimestampValue => { if value__.is_some() { return Err(serde::de::Error::duplicate_field("timestampValue")); diff --git a/datafusion/proto/src/generated/prost.rs b/datafusion/proto/src/generated/prost.rs index 5f201b124d1b..e3f3f8b21e2b 100644 --- a/datafusion/proto/src/generated/prost.rs +++ b/datafusion/proto/src/generated/prost.rs @@ -1087,7 +1087,7 @@ pub struct ScalarFixedSizeBinary { pub struct ScalarValue { #[prost( oneof = "scalar_value::Value", - tags = "33, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 20, 21, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34" + tags = "33, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 20, 21, 24, 25, 35, 36, 37, 38, 26, 27, 28, 29, 30, 31, 32, 34" )] pub value: ::core::option::Option, } @@ -1142,6 +1142,14 @@ pub mod scalar_value { IntervalYearmonthValue(i32), #[prost(int64, tag = "25")] IntervalDaytimeValue(i64), + #[prost(int64, tag = "35")] + DurationSecondValue(i64), + #[prost(int64, tag = "36")] + DurationMillisecondValue(i64), + #[prost(int64, tag = "37")] + DurationMicrosecondValue(i64), + #[prost(int64, tag = "38")] + DurationNanosecondValue(i64), #[prost(message, tag = "26")] TimestampValue(super::ScalarTimestampValue), #[prost(message, tag = "27")] diff --git a/datafusion/proto/src/logical_plan/from_proto.rs b/datafusion/proto/src/logical_plan/from_proto.rs index b4a49713c244..c4dc8eb9b256 100644 --- a/datafusion/proto/src/logical_plan/from_proto.rs +++ b/datafusion/proto/src/logical_plan/from_proto.rs @@ -680,6 +680,10 @@ impl TryFrom<&protobuf::ScalarValue> for ScalarValue { } Value::IntervalYearmonthValue(v) => Self::IntervalYearMonth(Some(*v)), Value::IntervalDaytimeValue(v) => Self::IntervalDayTime(Some(*v)), + Value::DurationSecondValue(v) => Self::DurationSecond(Some(*v)), + Value::DurationMillisecondValue(v) => Self::DurationMillisecond(Some(*v)), + Value::DurationMicrosecondValue(v) => Self::DurationMicrosecond(Some(*v)), + Value::DurationNanosecondValue(v) => Self::DurationNanosecond(Some(*v)), Value::TimestampValue(v) => { let timezone = if v.timezone.is_empty() { None diff --git a/datafusion/proto/src/logical_plan/to_proto.rs b/datafusion/proto/src/logical_plan/to_proto.rs index 5b09aee91095..d81e92c3f3d3 100644 --- a/datafusion/proto/src/logical_plan/to_proto.rs +++ b/datafusion/proto/src/logical_plan/to_proto.rs @@ -1013,63 +1013,62 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { type Error = Error; fn try_from(val: &ScalarValue) -> Result { - use datafusion_common::scalar; use protobuf::scalar_value::Value; let data_type = val.get_datatype(); match val { - scalar::ScalarValue::Boolean(val) => { + ScalarValue::Boolean(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| Value::BoolValue(*s)) } - scalar::ScalarValue::Float32(val) => { + ScalarValue::Float32(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| Value::Float32Value(*s)) } - scalar::ScalarValue::Float64(val) => { + ScalarValue::Float64(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| Value::Float64Value(*s)) } - scalar::ScalarValue::Int8(val) => { + ScalarValue::Int8(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::Int8Value(*s as i32) }) } - scalar::ScalarValue::Int16(val) => { + ScalarValue::Int16(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::Int16Value(*s as i32) }) } - scalar::ScalarValue::Int32(val) => { + ScalarValue::Int32(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| Value::Int32Value(*s)) } - scalar::ScalarValue::Int64(val) => { + ScalarValue::Int64(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| Value::Int64Value(*s)) } - scalar::ScalarValue::UInt8(val) => { + ScalarValue::UInt8(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::Uint8Value(*s as u32) }) } - scalar::ScalarValue::UInt16(val) => { + ScalarValue::UInt16(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::Uint16Value(*s as u32) }) } - scalar::ScalarValue::UInt32(val) => { + ScalarValue::UInt32(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| Value::Uint32Value(*s)) } - scalar::ScalarValue::UInt64(val) => { + ScalarValue::UInt64(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| Value::Uint64Value(*s)) } - scalar::ScalarValue::Utf8(val) => { + ScalarValue::Utf8(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::Utf8Value(s.to_owned()) }) } - scalar::ScalarValue::LargeUtf8(val) => { + ScalarValue::LargeUtf8(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::LargeUtf8Value(s.to_owned()) }) } - scalar::ScalarValue::List(values, boxed_field) => { + ScalarValue::List(values, boxed_field) => { let is_null = values.is_none(); let values = if let Some(values) = values.as_ref() { @@ -1093,10 +1092,10 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { )), }) } - datafusion::scalar::ScalarValue::Date32(val) => { + ScalarValue::Date32(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| Value::Date32Value(*s)) } - datafusion::scalar::ScalarValue::TimestampMicrosecond(val, tz) => { + ScalarValue::TimestampMicrosecond(val, tz) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::TimestampValue(protobuf::ScalarTimestampValue { timezone: tz.as_deref().unwrap_or("").to_string(), @@ -1108,7 +1107,7 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { }) }) } - datafusion::scalar::ScalarValue::TimestampNanosecond(val, tz) => { + ScalarValue::TimestampNanosecond(val, tz) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::TimestampValue(protobuf::ScalarTimestampValue { timezone: tz.as_deref().unwrap_or("").to_string(), @@ -1120,7 +1119,7 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { }) }) } - datafusion::scalar::ScalarValue::Decimal128(val, p, s) => match *val { + ScalarValue::Decimal128(val, p, s) => match *val { Some(v) => { let array = v.to_be_bytes(); let vec_val: Vec = array.to_vec(); @@ -1138,10 +1137,10 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { )), }), }, - datafusion::scalar::ScalarValue::Date64(val) => { + ScalarValue::Date64(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| Value::Date64Value(*s)) } - datafusion::scalar::ScalarValue::TimestampSecond(val, tz) => { + ScalarValue::TimestampSecond(val, tz) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::TimestampValue(protobuf::ScalarTimestampValue { timezone: tz.as_deref().unwrap_or("").to_string(), @@ -1151,7 +1150,7 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { }) }) } - datafusion::scalar::ScalarValue::TimestampMillisecond(val, tz) => { + ScalarValue::TimestampMillisecond(val, tz) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::TimestampValue(protobuf::ScalarTimestampValue { timezone: tz.as_deref().unwrap_or("").to_string(), @@ -1163,31 +1162,31 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { }) }) } - datafusion::scalar::ScalarValue::IntervalYearMonth(val) => { + ScalarValue::IntervalYearMonth(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::IntervalYearmonthValue(*s) }) } - datafusion::scalar::ScalarValue::IntervalDayTime(val) => { + ScalarValue::IntervalDayTime(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::IntervalDaytimeValue(*s) }) } - datafusion::scalar::ScalarValue::Null => Ok(protobuf::ScalarValue { + ScalarValue::Null => Ok(protobuf::ScalarValue { value: Some(Value::NullValue((&data_type).try_into()?)), }), - scalar::ScalarValue::Binary(val) => { + ScalarValue::Binary(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::BinaryValue(s.to_owned()) }) } - scalar::ScalarValue::LargeBinary(val) => { + ScalarValue::LargeBinary(val) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::LargeBinaryValue(s.to_owned()) }) } - scalar::ScalarValue::FixedSizeBinary(length, val) => { + ScalarValue::FixedSizeBinary(length, val) => { create_proto_scalar(val.as_ref(), &data_type, |s| { Value::FixedSizeBinaryValue(protobuf::ScalarFixedSizeBinary { values: s.to_owned(), @@ -1196,7 +1195,7 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { }) } - datafusion::scalar::ScalarValue::Time32Second(v) => { + ScalarValue::Time32Second(v) => { create_proto_scalar(v.as_ref(), &data_type, |v| { Value::Time32Value(protobuf::ScalarTime32Value { value: Some( @@ -1206,7 +1205,7 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { }) } - datafusion::scalar::ScalarValue::Time32Millisecond(v) => { + ScalarValue::Time32Millisecond(v) => { create_proto_scalar(v.as_ref(), &data_type, |v| { Value::Time32Value(protobuf::ScalarTime32Value { value: Some( @@ -1218,7 +1217,7 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { }) } - datafusion::scalar::ScalarValue::Time64Microsecond(v) => { + ScalarValue::Time64Microsecond(v) => { create_proto_scalar(v.as_ref(), &data_type, |v| { Value::Time64Value(protobuf::ScalarTime64Value { value: Some( @@ -1230,7 +1229,7 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { }) } - datafusion::scalar::ScalarValue::Time64Nanosecond(v) => { + ScalarValue::Time64Nanosecond(v) => { create_proto_scalar(v.as_ref(), &data_type, |v| { Value::Time64Value(protobuf::ScalarTime64Value { value: Some( @@ -1242,7 +1241,7 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { }) } - datafusion::scalar::ScalarValue::IntervalMonthDayNano(v) => { + ScalarValue::IntervalMonthDayNano(v) => { let value = if let Some(v) = v { let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(*v); Value::IntervalMonthDayNano(protobuf::IntervalMonthDayNanoValue { @@ -1251,13 +1250,42 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { nanos, }) } else { - protobuf::scalar_value::Value::NullValue((&data_type).try_into()?) + Value::NullValue((&data_type).try_into()?) }; Ok(protobuf::ScalarValue { value: Some(value) }) } - datafusion::scalar::ScalarValue::Struct(values, fields) => { + ScalarValue::DurationSecond(v) => { + let value = match v { + Some(v) => Value::DurationSecondValue(*v), + None => Value::NullValue((&data_type).try_into()?), + }; + Ok(protobuf::ScalarValue { value: Some(value) }) + } + ScalarValue::DurationMillisecond(v) => { + let value = match v { + Some(v) => Value::DurationMillisecondValue(*v), + None => Value::NullValue((&data_type).try_into()?), + }; + Ok(protobuf::ScalarValue { value: Some(value) }) + } + ScalarValue::DurationMicrosecond(v) => { + let value = match v { + Some(v) => Value::DurationMicrosecondValue(*v), + None => Value::NullValue((&data_type).try_into()?), + }; + Ok(protobuf::ScalarValue { value: Some(value) }) + } + ScalarValue::DurationNanosecond(v) => { + let value = match v { + Some(v) => Value::DurationNanosecondValue(*v), + None => Value::NullValue((&data_type).try_into()?), + }; + Ok(protobuf::ScalarValue { value: Some(value) }) + } + + ScalarValue::Struct(values, fields) => { // encode null as empty field values list let field_values = if let Some(values) = values { if values.is_empty() { @@ -1284,7 +1312,7 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { }) } - datafusion::scalar::ScalarValue::Dictionary(index_type, val) => { + ScalarValue::Dictionary(index_type, val) => { let value: protobuf::ScalarValue = val.as_ref().try_into()?; Ok(protobuf::ScalarValue { value: Some(Value::DictionaryValue(Box::new(