datatypes/types/
duration_type.rs1use arrow::datatypes::{
16 DataType as ArrowDataType, DurationMicrosecondType as ArrowDurationMicrosecondType,
17 DurationMillisecondType as ArrowDurationMillisecondType,
18 DurationNanosecondType as ArrowDurationNanosecondType,
19 DurationSecondType as ArrowDurationSecondType, TimeUnit as ArrowTimeUnit,
20};
21use common_time::duration::Duration;
22use common_time::timestamp::TimeUnit;
23use enum_dispatch::enum_dispatch;
24use paste::paste;
25use serde::{Deserialize, Serialize};
26use snafu::OptionExt;
27
28use crate::data_type::DataType;
29use crate::duration::{
30 DurationMicrosecond, DurationMillisecond, DurationNanosecond, DurationSecond,
31};
32use crate::error;
33use crate::prelude::{
34 ConcreteDataType, LogicalTypeId, MutableVector, ScalarVectorBuilder, Value, ValueRef, Vector,
35};
36use crate::types::LogicalPrimitiveType;
37use crate::vectors::{
38 DurationMicrosecondVector, DurationMicrosecondVectorBuilder, DurationMillisecondVector,
39 DurationMillisecondVectorBuilder, DurationNanosecondVector, DurationNanosecondVectorBuilder,
40 DurationSecondVector, DurationSecondVectorBuilder, PrimitiveVector,
41};
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
44#[enum_dispatch(DataType)]
45pub enum DurationType {
46 Second(DurationSecondType),
47 Millisecond(DurationMillisecondType),
48 Microsecond(DurationMicrosecondType),
49 Nanosecond(DurationNanosecondType),
50}
51
52impl DurationType {
53 pub fn from_unit(unit: TimeUnit) -> Self {
55 match unit {
56 TimeUnit::Second => Self::Second(DurationSecondType),
57 TimeUnit::Millisecond => Self::Millisecond(DurationMillisecondType),
58 TimeUnit::Microsecond => Self::Microsecond(DurationMicrosecondType),
59 TimeUnit::Nanosecond => Self::Nanosecond(DurationNanosecondType),
60 }
61 }
62
63 pub fn unit(&self) -> TimeUnit {
65 match self {
66 DurationType::Second(_) => TimeUnit::Second,
67 DurationType::Millisecond(_) => TimeUnit::Millisecond,
68 DurationType::Microsecond(_) => TimeUnit::Microsecond,
69 DurationType::Nanosecond(_) => TimeUnit::Nanosecond,
70 }
71 }
72}
73
74macro_rules! impl_data_type_for_duration {
75 ($unit: ident) => {
76 paste! {
77 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
78 pub struct [<Duration $unit Type>];
79
80 impl DataType for [<Duration $unit Type>] {
81 fn name(&self) -> String {
82 stringify!([<Duration $unit>]).to_string()
83 }
84
85 fn logical_type_id(&self) -> LogicalTypeId {
86 LogicalTypeId::[<Duration $unit>]
87 }
88
89 fn default_value(&self) -> Value {
90 Value::Duration(Duration::new(0, TimeUnit::$unit))
91 }
92
93 fn as_arrow_type(&self) -> ArrowDataType {
94 ArrowDataType::Duration(ArrowTimeUnit::$unit)
95 }
96
97 fn create_mutable_vector(&self, capacity: usize) -> Box<dyn MutableVector> {
98 Box::new([<Duration $unit Vector Builder>]::with_capacity(capacity))
99 }
100
101
102 fn try_cast(&self, _: Value) -> Option<Value> {
103 None
105 }
106 }
107
108 impl LogicalPrimitiveType for [<Duration $unit Type>] {
109 type ArrowPrimitive = [<Arrow Duration $unit Type>];
110 type Native = i64;
111 type Wrapper = [<Duration $unit>];
112 type LargestType = Self;
113
114 fn build_data_type() -> ConcreteDataType {
115 ConcreteDataType::Duration(DurationType::$unit(
116 [<Duration $unit Type>]::default(),
117 ))
118 }
119
120 fn type_name() -> &'static str {
121 stringify!([<Duration $unit Type>])
122 }
123
124 fn cast_vector(vector: &dyn Vector) -> crate::Result<&PrimitiveVector<Self>> {
125 vector
126 .as_any()
127 .downcast_ref::<[<Duration $unit Vector>]>()
128 .with_context(|| error::CastTypeSnafu {
129 msg: format!(
130 "Failed to cast {} to {}",
131 vector.vector_type_name(), stringify!([<Duration $unit Vector>])
132 ),
133 })
134 }
135
136 fn cast_value_ref(value: ValueRef) -> crate::Result<Option<Self::Wrapper>> {
137 match value {
138 ValueRef::Null => Ok(None),
139 ValueRef::Duration(t) => match t.unit() {
140 TimeUnit::$unit => Ok(Some([<Duration $unit>](t))),
141 other => error::CastTypeSnafu {
142 msg: format!(
143 "Failed to cast Duration value with different unit {:?} to {}",
144 other, stringify!([<Duration $unit>])
145 ),
146 }
147 .fail(),
148 },
149 other => error::CastTypeSnafu {
150 msg: format!("Failed to cast value {:?} to {}", other, stringify!([<Duration $unit>])),
151 }
152 .fail(),
153 }
154 }
155 }
156 }
157 }
158}
159
160impl_data_type_for_duration!(Second);
161impl_data_type_for_duration!(Millisecond);
162impl_data_type_for_duration!(Microsecond);
163impl_data_type_for_duration!(Nanosecond);
164
165#[cfg(test)]
166mod tests {
167 use super::*;
168
169 #[test]
170 fn test_duration_type_unit() {
171 assert_eq!(
172 TimeUnit::Second,
173 DurationType::Second(DurationSecondType).unit()
174 );
175
176 assert_eq!(
177 TimeUnit::Millisecond,
178 DurationType::Millisecond(DurationMillisecondType).unit()
179 );
180
181 assert_eq!(
182 TimeUnit::Microsecond,
183 DurationType::Microsecond(DurationMicrosecondType).unit()
184 );
185
186 assert_eq!(
187 TimeUnit::Nanosecond,
188 DurationType::Nanosecond(DurationNanosecondType).unit()
189 );
190 }
191
192 #[test]
193 fn test_from_unit() {
194 assert_eq!(
195 DurationType::Second(DurationSecondType),
196 DurationType::from_unit(TimeUnit::Second)
197 );
198
199 assert_eq!(
200 DurationType::Millisecond(DurationMillisecondType),
201 DurationType::from_unit(TimeUnit::Millisecond)
202 );
203
204 assert_eq!(
205 DurationType::Microsecond(DurationMicrosecondType),
206 DurationType::from_unit(TimeUnit::Microsecond)
207 );
208
209 assert_eq!(
210 DurationType::Nanosecond(DurationNanosecondType),
211 DurationType::from_unit(TimeUnit::Nanosecond)
212 );
213 }
214}