@@ -4,11 +4,13 @@ use std::fmt::Formatter;
44use std:: hash:: Hash ;
55use std:: str:: FromStr ;
66use std:: sync:: Arc ;
7- use chrono:: { Duration , NaiveDateTime , Utc , TimeZone } ;
7+ use chrono:: { NaiveDateTime , Datelike , NaiveDate } ;
8+ use chrono:: format:: { DelayedFormat , StrftimeItems } ;
89use integer_encoding:: FixedInt ;
910use lazy_static:: lazy_static;
1011
1112use ordered_float:: OrderedFloat ;
13+ use crate :: types:: errors:: TypeError ;
1214
1315use super :: LogicalType ;
1416
@@ -18,6 +20,9 @@ lazy_static! {
1820 } ;
1921}
2022
23+ pub const DATE_FMT : & str = "%Y-%m-%d" ;
24+ pub const DATE_TIME_FMT : & str = "%Y-%m-%d %H:%M:%S" ;
25+
2126pub type ValueRef = Arc < DataValue > ;
2227
2328#[ derive( Clone ) ]
@@ -35,7 +40,9 @@ pub enum DataValue {
3540 UInt32 ( Option < u32 > ) ,
3641 UInt64 ( Option < u64 > ) ,
3742 Utf8 ( Option < String > ) ,
38- /// Date stored as a unsigned 64bit int days since UNIX epoch 1970-01-01
43+ /// Date stored as a signed 32bit int days since UNIX epoch 1970-01-01
44+ Date32 ( Option < i32 > ) ,
45+ /// Date stored as a signed 64bit int timestamp since UNIX epoch 1970-01-01
3946 Date64 ( Option < i64 > ) ,
4047}
4148
@@ -77,6 +84,8 @@ impl PartialEq for DataValue {
7784 ( Utf8 ( _) , _) => false ,
7885 ( Null , Null ) => true ,
7986 ( Null , _) => false ,
87+ ( Date32 ( v1) , Date32 ( v2) ) => v1. eq ( v2) ,
88+ ( Date32 ( _) , _) => false ,
8089 ( Date64 ( v1) , Date64 ( v2) ) => v1. eq ( v2) ,
8190 ( Date64 ( _) , _) => false ,
8291 }
@@ -121,6 +130,8 @@ impl PartialOrd for DataValue {
121130 ( Utf8 ( _) , _) => None ,
122131 ( Null , Null ) => Some ( Ordering :: Equal ) ,
123132 ( Null , _) => None ,
133+ ( Date32 ( v1) , Date32 ( v2) ) => v1. partial_cmp ( v2) ,
134+ ( Date32 ( _) , _) => None ,
124135 ( Date64 ( v1) , Date64 ( v2) ) => v1. partial_cmp ( v2) ,
125136 ( Date64 ( _) , _) => None ,
126137 }
@@ -152,6 +163,7 @@ impl Hash for DataValue {
152163 UInt64 ( v) => v. hash ( state) ,
153164 Utf8 ( v) => v. hash ( state) ,
154165 Null => 1 . hash ( state) ,
166+ Date32 ( v) => v. hash ( state) ,
155167 Date64 ( v) => v. hash ( state) ,
156168 }
157169 }
@@ -180,6 +192,7 @@ impl DataValue {
180192 DataValue :: UInt32 ( value) => value. is_none ( ) ,
181193 DataValue :: UInt64 ( value) => value. is_none ( ) ,
182194 DataValue :: Utf8 ( value) => value. is_none ( ) ,
195+ DataValue :: Date32 ( value) => value. is_none ( ) ,
183196 DataValue :: Date64 ( value) => value. is_none ( ) ,
184197 }
185198 }
@@ -200,6 +213,7 @@ impl DataValue {
200213 LogicalType :: Float => DataValue :: Float32 ( None ) ,
201214 LogicalType :: Double => DataValue :: Float64 ( None ) ,
202215 LogicalType :: Varchar => DataValue :: Utf8 ( None ) ,
216+ LogicalType :: Date => DataValue :: Date32 ( None ) ,
203217 LogicalType :: DateTime => DataValue :: Date64 ( None )
204218 }
205219 }
@@ -220,6 +234,7 @@ impl DataValue {
220234 LogicalType :: Float => DataValue :: Float32 ( Some ( 0.0 ) ) ,
221235 LogicalType :: Double => DataValue :: Float64 ( Some ( 0.0 ) ) ,
222236 LogicalType :: Varchar => DataValue :: Utf8 ( Some ( "" . to_string ( ) ) ) ,
237+ LogicalType :: Date => DataValue :: Date32 ( Some ( UNIX_DATETIME . num_days_from_ce ( ) ) ) ,
223238 LogicalType :: DateTime => DataValue :: Date64 ( Some ( UNIX_DATETIME . timestamp ( ) ) )
224239 }
225240 }
@@ -239,6 +254,7 @@ impl DataValue {
239254 DataValue :: UInt32 ( v) => v. map ( |v| v. encode_fixed_vec ( ) ) ,
240255 DataValue :: UInt64 ( v) => v. map ( |v| v. encode_fixed_vec ( ) ) ,
241256 DataValue :: Utf8 ( v) => v. clone ( ) . map ( |v| v. into_bytes ( ) ) ,
257+ DataValue :: Date32 ( v) => v. map ( |v| v. encode_fixed_vec ( ) ) ,
242258 DataValue :: Date64 ( v) => v. map ( |v| v. encode_fixed_vec ( ) ) ,
243259 } . unwrap_or ( vec ! [ ] )
244260 }
@@ -267,6 +283,7 @@ impl DataValue {
267283 f64:: from_ne_bytes ( buf)
268284 } ) ) ,
269285 LogicalType :: Varchar => DataValue :: Utf8 ( ( !bytes. is_empty ( ) ) . then ( || String :: from_utf8 ( bytes. to_owned ( ) ) . unwrap ( ) ) ) ,
286+ LogicalType :: Date => DataValue :: Date32 ( ( !bytes. is_empty ( ) ) . then ( || i32:: decode_fixed ( bytes) ) ) ,
270287 LogicalType :: DateTime => DataValue :: Date64 ( ( !bytes. is_empty ( ) ) . then ( || i64:: decode_fixed ( bytes) ) ) ,
271288 }
272289 }
@@ -286,6 +303,7 @@ impl DataValue {
286303 DataValue :: UInt32 ( _) => LogicalType :: UInteger ,
287304 DataValue :: UInt64 ( _) => LogicalType :: UBigint ,
288305 DataValue :: Utf8 ( _) => LogicalType :: Varchar ,
306+ DataValue :: Date32 ( _) => LogicalType :: Date ,
289307 DataValue :: Date64 ( _) => LogicalType :: DateTime ,
290308 }
291309 }
@@ -308,6 +326,7 @@ impl DataValue {
308326 LogicalType :: Float => DataValue :: Float32 ( None ) ,
309327 LogicalType :: Double => DataValue :: Float64 ( None ) ,
310328 LogicalType :: Varchar => DataValue :: Utf8 ( None ) ,
329+ LogicalType :: Date => DataValue :: Date32 ( None ) ,
311330 LogicalType :: DateTime => DataValue :: Date64 ( None ) ,
312331 }
313332 }
@@ -327,7 +346,7 @@ impl DataValue {
327346 LogicalType :: Float => DataValue :: Float32 ( value. map ( |v| v. into ( ) ) ) ,
328347 LogicalType :: Double => DataValue :: Float64 ( value. map ( |v| v. into ( ) ) ) ,
329348 LogicalType :: Varchar => DataValue :: Utf8 ( value. map ( |v| format ! ( "{}" , v) ) ) ,
330- LogicalType :: DateTime => panic ! ( "not support" ) ,
349+ _ => panic ! ( "not support" ) ,
331350 }
332351 }
333352 DataValue :: Float32 ( value) => {
@@ -481,9 +500,24 @@ impl DataValue {
481500 LogicalType :: Float => DataValue :: Float32 ( value. map ( |v| f32:: from_str ( & v) . unwrap ( ) ) ) ,
482501 LogicalType :: Double => DataValue :: Float64 ( value. map ( |v| f64:: from_str ( & v) . unwrap ( ) ) ) ,
483502 LogicalType :: Varchar => DataValue :: Utf8 ( value) ,
503+ LogicalType :: Date => {
504+ let option = value. map ( |v| {
505+ NaiveDate :: parse_from_str ( & v, DATE_FMT )
506+ . unwrap ( )
507+ . num_days_from_ce ( )
508+ } ) ;
509+
510+ DataValue :: Date32 ( option)
511+ }
484512 LogicalType :: DateTime => {
485513 let option = value. map ( |v| {
486- NaiveDateTime :: parse_from_str ( & v, "%Y-%m-%d %H:%M:%S" )
514+ NaiveDateTime :: parse_from_str ( & v, DATE_TIME_FMT )
515+ . or_else ( |_| {
516+ NaiveDate :: parse_from_str ( & v, DATE_FMT )
517+ . unwrap ( )
518+ . and_hms_opt ( 0 , 0 , 0 )
519+ . ok_or_else ( || TypeError :: InternalError ( "wrong format" . to_string ( ) ) )
520+ } )
487521 . unwrap ( )
488522 . timestamp ( )
489523 } ) ;
@@ -492,17 +526,63 @@ impl DataValue {
492526 }
493527 }
494528 }
529+ DataValue :: Date32 ( value) => {
530+ match to {
531+ LogicalType :: Invalid => panic ! ( "invalid logical type" ) ,
532+ LogicalType :: SqlNull => DataValue :: Null ,
533+ LogicalType :: Varchar => DataValue :: Utf8 ( value. map ( |v| {
534+ format ! ( "{}" , Self :: date_format( v) )
535+ } ) ) ,
536+ LogicalType :: Date => DataValue :: Date32 ( value) ,
537+ LogicalType :: DateTime => {
538+ let option = value. map ( |v| {
539+ NaiveDate :: from_num_days_from_ce_opt ( v)
540+ . unwrap ( )
541+ . and_hms_opt ( 0 , 0 , 0 )
542+ . unwrap ( )
543+ . timestamp ( )
544+ } ) ;
545+
546+ DataValue :: Date64 ( option)
547+ } ,
548+ _ => panic ! ( "not support" ) ,
549+ }
550+ }
495551 DataValue :: Date64 ( value) => {
496552 match to {
497553 LogicalType :: Invalid => panic ! ( "invalid logical type" ) ,
498554 LogicalType :: SqlNull => DataValue :: Null ,
499- LogicalType :: Varchar => DataValue :: Utf8 ( value. map ( |v| format ! ( "{}" , v) ) ) ,
555+ LogicalType :: Varchar => DataValue :: Utf8 ( value. map ( |v| {
556+ format ! ( "{}" , Self :: date_time_format( v) )
557+ } ) ) ,
558+ LogicalType :: Date => {
559+ let option = value. map ( |v| {
560+ NaiveDateTime :: from_timestamp_opt ( v, 0 )
561+ . unwrap ( )
562+ . date ( )
563+ . num_days_from_ce ( )
564+ } ) ;
565+
566+ DataValue :: Date32 ( option)
567+ }
500568 LogicalType :: DateTime => DataValue :: Date64 ( value) ,
501569 _ => panic ! ( "not support" ) ,
502570 }
503571 }
504572 }
505573 }
574+
575+ fn date_format < ' a > ( v : i32 ) -> DelayedFormat < StrftimeItems < ' a > > {
576+ NaiveDate :: from_num_days_from_ce_opt ( v)
577+ . unwrap ( )
578+ . format ( DATE_FMT )
579+ }
580+
581+ fn date_time_format < ' a > ( v : i64 ) -> DelayedFormat < StrftimeItems < ' a > > {
582+ NaiveDateTime :: from_timestamp_opt ( v, 0 )
583+ . unwrap ( )
584+ . format ( DATE_TIME_FMT )
585+ }
506586}
507587
508588macro_rules! impl_scalar {
@@ -585,12 +665,11 @@ impl fmt::Display for DataValue {
585665 DataValue :: UInt64 ( e) => format_option ! ( f, e) ?,
586666 DataValue :: Utf8 ( e) => format_option ! ( f, e) ?,
587667 DataValue :: Null => write ! ( f, "null" ) ?,
668+ DataValue :: Date32 ( e) => {
669+ format_option ! ( f, e. map( |s| DataValue :: date_format( s) ) ) ?
670+ }
588671 DataValue :: Date64 ( e) => {
589- format_option ! ( f, e. map( |s| {
590- let datetime_utc = Utc . from_utc_datetime( & UNIX_DATETIME ) ;
591-
592- datetime_utc + Duration :: seconds( s)
593- } ) ) ?
672+ format_option ! ( f, e. map( |s| DataValue :: date_time_format( s) ) ) ?
594673 } ,
595674 } ;
596675 Ok ( ( ) )
@@ -614,6 +693,7 @@ impl fmt::Debug for DataValue {
614693 DataValue :: Utf8 ( None ) => write ! ( f, "Utf8({})" , self ) ,
615694 DataValue :: Utf8 ( Some ( _) ) => write ! ( f, "Utf8(\" {}\" )" , self ) ,
616695 DataValue :: Null => write ! ( f, "null" ) ,
696+ DataValue :: Date32 ( _) => write ! ( f, "Date32({})" , self ) ,
617697 DataValue :: Date64 ( _) => write ! ( f, "Date64({})" , self ) ,
618698 }
619699 }
0 commit comments