1515
1616use std:: cmp:: Ordering ;
1717use std:: convert:: TryFrom ;
18+ use std:: fmt:: Debug ;
19+ use std:: fmt:: Display ;
20+ use std:: fmt:: Formatter ;
1821use std:: hash:: Hash ;
1922use std:: hash:: Hasher ;
2023use std:: ops:: Add ;
@@ -27,12 +30,17 @@ use borsh::BorshSerialize;
2730use bytemuck:: Pod ;
2831use bytemuck:: Zeroable ;
2932use databend_common_base:: base:: OrderedFloat ;
33+ use jiff:: fmt:: strtime;
34+ use jiff:: tz;
35+ use jiff:: Timestamp ;
3036use log:: error;
3137use serde_derive:: Deserialize ;
3238use serde_derive:: Serialize ;
3339
3440use super :: PrimitiveType ;
3541
42+ pub const TIMESTAMP_TIMEZONE_FORMAT : & str = "%Y-%m-%d %H:%M:%S%.6f %z" ;
43+
3644/// Sealed trait implemented by all physical types that can be allocated,
3745/// serialized and deserialized by this crate.
3846/// All O(N) allocations in this crate are done for this trait alone.
@@ -71,6 +79,10 @@ pub trait NativeType:
7179
7280 /// From bytes in big endian
7381 fn from_be_bytes ( bytes : Self :: Bytes ) -> Self ;
82+
83+ fn size_of ( ) -> usize {
84+ std:: mem:: size_of :: < Self > ( )
85+ }
7486}
7587
7688macro_rules! native_type {
@@ -428,6 +440,138 @@ impl Neg for months_days_micros {
428440 }
429441}
430442
443+ /// The in-memory representation of the MonthDayNano variant of the "Interval" logical type.
444+ #[ derive(
445+ Debug ,
446+ Copy ,
447+ Clone ,
448+ Default ,
449+ Eq ,
450+ Zeroable ,
451+ Pod ,
452+ Serialize ,
453+ Deserialize ,
454+ BorshSerialize ,
455+ BorshDeserialize ,
456+ ) ]
457+ #[ allow( non_camel_case_types) ]
458+ #[ repr( C ) ]
459+ pub struct timestamp_tz ( pub i128 ) ;
460+
461+ impl Hash for timestamp_tz {
462+ fn hash < H : Hasher > ( & self , state : & mut H ) {
463+ self . total_micros ( ) . hash ( state)
464+ }
465+ }
466+ impl PartialEq for timestamp_tz {
467+ fn eq ( & self , other : & Self ) -> bool {
468+ self . total_micros ( ) == other. total_micros ( )
469+ }
470+ }
471+ impl PartialOrd for timestamp_tz {
472+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
473+ Some ( self . cmp ( other) )
474+ }
475+ }
476+
477+ impl Ord for timestamp_tz {
478+ fn cmp ( & self , other : & Self ) -> Ordering {
479+ let total_micros = self . total_micros ( ) ;
480+ let other_micros = other. total_micros ( ) ;
481+ total_micros. cmp ( & other_micros)
482+ }
483+ }
484+
485+ impl timestamp_tz {
486+ pub const MICROS_PER_SECOND : i64 = 1_000_000 ;
487+
488+ pub fn new ( timestamp : i64 , offset : i32 ) -> Self {
489+ let ts = timestamp as u64 as i128 ; // <- 中间加一次 u64 屏蔽符号位
490+ let off = ( offset as i128 ) << 64 ;
491+ Self ( off | ts)
492+ }
493+
494+ #[ inline]
495+ pub fn timestamp ( & self ) -> i64 {
496+ self . 0 as u64 as i64
497+ }
498+
499+ #[ inline]
500+ pub fn seconds_offset ( & self ) -> i32 {
501+ ( self . 0 >> 64 ) as i32
502+ }
503+
504+ #[ inline]
505+ pub fn micros_offset ( & self ) -> Option < i64 > {
506+ ( self . seconds_offset ( ) as i64 ) . checked_mul ( Self :: MICROS_PER_SECOND )
507+ }
508+
509+ #[ inline]
510+ pub fn hours_offset ( & self ) -> i8 {
511+ ( self . seconds_offset ( ) / 3600 ) as i8
512+ }
513+
514+ #[ inline]
515+ pub fn total_micros ( & self ) -> i64 {
516+ self . try_total_micros ( ) . unwrap_or_else ( || {
517+ error ! (
518+ "interval is out of range: timestamp={}, offset={}" ,
519+ self . timestamp( ) ,
520+ self . seconds_offset( )
521+ ) ;
522+ 0
523+ } )
524+ }
525+
526+ #[ inline]
527+ pub fn try_total_micros ( & self ) -> Option < i64 > {
528+ let offset_micros = self . micros_offset ( ) ?;
529+ self . timestamp ( ) . checked_sub ( offset_micros)
530+ }
531+ }
532+
533+ impl Display for timestamp_tz {
534+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
535+ let timestamp = Timestamp :: from_microsecond ( self . timestamp ( ) ) . unwrap ( ) ;
536+
537+ let offset = tz:: Offset :: from_seconds ( self . seconds_offset ( ) ) . unwrap ( ) ;
538+ let string = strtime:: format (
539+ TIMESTAMP_TIMEZONE_FORMAT ,
540+ & timestamp. to_zoned ( offset. to_time_zone ( ) ) ,
541+ )
542+ . unwrap ( ) ;
543+ write ! ( f, "{}" , string)
544+ }
545+ }
546+
547+ impl NativeType for timestamp_tz {
548+ const PRIMITIVE : PrimitiveType = PrimitiveType :: TimestampTz ;
549+ type Bytes = [ u8 ; 16 ] ;
550+ #[ inline]
551+ fn to_le_bytes ( & self ) -> Self :: Bytes {
552+ self . 0 . to_le_bytes ( )
553+ }
554+
555+ #[ inline]
556+ fn to_be_bytes ( & self ) -> Self :: Bytes {
557+ self . 0 . to_be_bytes ( )
558+ }
559+
560+ #[ inline]
561+ fn from_le_bytes ( bytes : Self :: Bytes ) -> Self {
562+ let mut buf16 = [ 0u8 ; 16 ] ;
563+ buf16. copy_from_slice ( & bytes) ;
564+ Self ( i128:: from_le_bytes ( buf16) )
565+ }
566+
567+ #[ inline]
568+ fn from_be_bytes ( bytes : Self :: Bytes ) -> Self {
569+ let mut buf16 = [ 0u8 ; 16 ] ;
570+ buf16. copy_from_slice ( & bytes) ;
571+ Self ( i128:: from_be_bytes ( buf16) )
572+ }
573+ }
574+
431575/// Type representation of the Float16 physical type
432576#[ derive( Copy , Clone , Default , Zeroable , Pod ) ]
433577#[ allow( non_camel_case_types) ]
0 commit comments