datatypes/types/
date_type.rs1use arrow::datatypes::{DataType as ArrowDataType, Date32Type};
16use common_time::Date;
17use serde::{Deserialize, Serialize};
18use snafu::OptionExt;
19
20use crate::data_type::{ConcreteDataType, DataType};
21use crate::error::{self, Result};
22use crate::scalars::ScalarVectorBuilder;
23use crate::type_id::LogicalTypeId;
24use crate::types::LogicalPrimitiveType;
25use crate::value::{Value, ValueRef};
26use crate::vectors::{DateVector, DateVectorBuilder, MutableVector, Vector};
27
28#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
30pub struct DateType;
31
32impl DataType for DateType {
33 fn name(&self) -> String {
34 "Date".to_string()
35 }
36
37 fn logical_type_id(&self) -> LogicalTypeId {
38 LogicalTypeId::Date
39 }
40
41 fn default_value(&self) -> Value {
42 Value::Date(Default::default())
43 }
44
45 fn as_arrow_type(&self) -> ArrowDataType {
46 ArrowDataType::Date32
47 }
48
49 fn create_mutable_vector(&self, capacity: usize) -> Box<dyn MutableVector> {
50 Box::new(DateVectorBuilder::with_capacity(capacity))
51 }
52
53 fn try_cast(&self, from: Value) -> Option<Value> {
54 match from {
55 Value::Int32(v) => Some(Value::Date(Date::from(v))),
56 Value::String(v) => Date::from_str_utc(v.as_utf8()).map(Value::Date).ok(),
57 Value::Timestamp(v) => v.to_chrono_date().map(|date| Value::Date(date.into())),
58 _ => None,
59 }
60 }
61}
62
63impl LogicalPrimitiveType for DateType {
64 type ArrowPrimitive = Date32Type;
65 type Native = i32;
66 type Wrapper = Date;
67 type LargestType = Self;
68
69 fn build_data_type() -> ConcreteDataType {
70 ConcreteDataType::date_datatype()
71 }
72
73 fn type_name() -> &'static str {
74 "Date"
75 }
76
77 fn cast_vector(vector: &dyn Vector) -> Result<&DateVector> {
78 vector
79 .as_any()
80 .downcast_ref::<DateVector>()
81 .with_context(|| error::CastTypeSnafu {
82 msg: format!("Failed to cast {} to DateVector", vector.vector_type_name(),),
83 })
84 }
85
86 fn cast_value_ref(value: ValueRef) -> Result<Option<Date>> {
87 match value {
88 ValueRef::Null => Ok(None),
89 ValueRef::Date(v) => Ok(Some(v)),
90 other => error::CastTypeSnafu {
91 msg: format!("Failed to cast value {other:?} to Date"),
92 }
93 .fail(),
94 }
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use common_base::bytes::StringBytes;
101 use common_time::timezone::set_default_timezone;
102 use common_time::Timestamp;
103
104 use super::*;
105
106 #[test]
108 fn test_date_cast() {
109 set_default_timezone(Some("Asia/Shanghai")).unwrap();
110 let ts = Value::Timestamp(Timestamp::from_str_utc("2000-01-01 08:00:01").unwrap());
112 let date = ConcreteDataType::date_datatype().try_cast(ts).unwrap();
113 assert_eq!(date, Value::Date(Date::from_str_utc("2000-01-01").unwrap()));
114
115 let ts = Value::Timestamp(Timestamp::from_str_utc("2000-01-02 07:59:59").unwrap());
117 let date = ConcreteDataType::date_datatype().try_cast(ts).unwrap();
118 assert_eq!(date, Value::Date(Date::from_str_utc("2000-01-02").unwrap()));
119
120 let ts = Value::Timestamp(Timestamp::from_str_utc("2000-01-02 07:59:59+08:00").unwrap());
122 let date = ConcreteDataType::date_datatype().try_cast(ts).unwrap();
123 assert_eq!(date, Value::Date(Date::from_str_utc("2000-01-01").unwrap()));
124
125 let val = Value::Int32(0);
127 let date = ConcreteDataType::date_datatype().try_cast(val).unwrap();
128 assert_eq!(date, Value::Date(Date::from_str_utc("1970-01-01").unwrap()));
129
130 let val = Value::Int32(19614);
131 let date = ConcreteDataType::date_datatype().try_cast(val).unwrap();
132 assert_eq!(date, Value::Date(Date::from_str_utc("2023-09-14").unwrap()));
133
134 let s = Value::String(StringBytes::from("1970-02-12"));
136 let date = ConcreteDataType::date_datatype().try_cast(s).unwrap();
137 assert_eq!(date, Value::Date(Date::from_str_utc("1970-02-12").unwrap()));
138 }
139}