@@ -71,6 +71,8 @@ pub enum DataTypeNode {
7171 /// Precision and optional timezone (timezone is ignored in value operations)
7272 Time64 ( DateTimePrecision ) ,
7373
74+ Interval ( IntervalType ) ,
75+
7476 IPv4 ,
7577 IPv6 ,
7678
@@ -143,6 +145,7 @@ impl DataTypeNode {
143145 str if str. starts_with ( "DateTime" ) => parse_datetime ( str) ,
144146 str if str. starts_with ( "Time64" ) => parse_time64 ( str) ,
145147 str if str. starts_with ( "Time" ) => Ok ( Self :: Time ) ,
148+ str if str. starts_with ( "Interval" ) => Ok ( Self :: Interval ( str[ 8 ..] . parse ( ) ?) ) ,
146149
147150 str if str. starts_with ( "Nullable" ) => parse_nullable ( str) ,
148151 str if str. starts_with ( "LowCardinality" ) => parse_low_cardinality ( str) ,
@@ -208,6 +211,7 @@ impl Display for DataTypeNode {
208211 DateTime64 ( precision, Some ( tz) ) => write ! ( f, "DateTime64({precision}, '{tz}')" ) ,
209212 Time => write ! ( f, "Time" ) ,
210213 Time64 ( precision) => write ! ( f, "Time64({precision})" ) ,
214+ Interval ( interval) => write ! ( f, "Interval{interval}" ) ,
211215 IPv4 => write ! ( f, "IPv4" ) ,
212216 IPv6 => write ! ( f, "IPv6" ) ,
213217 Bool => write ! ( f, "Bool" ) ,
@@ -392,6 +396,65 @@ impl Display for DateTimePrecision {
392396 }
393397}
394398
399+ /// Represents the type of an interval.
400+ /// See also: <https://clickhouse.com/docs/sql-reference/data-types/special-data-types/interval>
401+ #[ derive( Debug , Clone , PartialEq ) ]
402+ #[ allow( missing_docs) ]
403+ pub enum IntervalType {
404+ Nanosecond ,
405+ Microsecond ,
406+ Millisecond ,
407+ Second ,
408+ Minute ,
409+ Hour ,
410+ Day ,
411+ Week ,
412+ Month ,
413+ Quarter ,
414+ Year ,
415+ }
416+
417+ impl std:: str:: FromStr for IntervalType {
418+ type Err = TypesError ;
419+
420+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
421+ match s {
422+ "Nanosecond" => Ok ( IntervalType :: Nanosecond ) ,
423+ "Microsecond" => Ok ( IntervalType :: Microsecond ) ,
424+ "Millisecond" => Ok ( IntervalType :: Millisecond ) ,
425+ "Second" => Ok ( IntervalType :: Second ) ,
426+ "Minute" => Ok ( IntervalType :: Minute ) ,
427+ "Hour" => Ok ( IntervalType :: Hour ) ,
428+ "Day" => Ok ( IntervalType :: Day ) ,
429+ "Week" => Ok ( IntervalType :: Week ) ,
430+ "Month" => Ok ( IntervalType :: Month ) ,
431+ "Quarter" => Ok ( IntervalType :: Quarter ) ,
432+ "Year" => Ok ( IntervalType :: Year ) ,
433+ _ => Err ( TypesError :: TypeParsingError ( format ! (
434+ "Unknown interval type: {s}"
435+ ) ) ) ,
436+ }
437+ }
438+ }
439+
440+ impl Display for IntervalType {
441+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
442+ match self {
443+ Self :: Nanosecond => write ! ( f, "Nanosecond" ) ,
444+ Self :: Microsecond => write ! ( f, "Microsecond" ) ,
445+ Self :: Millisecond => write ! ( f, "Millisecond" ) ,
446+ Self :: Second => write ! ( f, "Second" ) ,
447+ Self :: Minute => write ! ( f, "Minute" ) ,
448+ Self :: Hour => write ! ( f, "Hour" ) ,
449+ Self :: Day => write ! ( f, "Day" ) ,
450+ Self :: Week => write ! ( f, "Week" ) ,
451+ Self :: Month => write ! ( f, "Month" ) ,
452+ Self :: Quarter => write ! ( f, "Quarter" ) ,
453+ Self :: Year => write ! ( f, "Year" ) ,
454+ }
455+ }
456+ }
457+
395458fn parse_fixed_string ( input : & str ) -> Result < DataTypeNode , TypesError > {
396459 if input. len ( ) >= 14 {
397460 let size_str = & input[ 12 ..input. len ( ) - 1 ] ;
@@ -1136,6 +1199,54 @@ mod tests {
11361199 assert ! ( DataTypeNode :: new( "Time64(x)" ) . is_err( ) ) ;
11371200 }
11381201
1202+ #[ test]
1203+ fn test_data_type_new_interval ( ) {
1204+ assert_eq ! (
1205+ DataTypeNode :: new( "IntervalNanosecond" ) . unwrap( ) ,
1206+ DataTypeNode :: Interval ( IntervalType :: Nanosecond )
1207+ ) ;
1208+ assert_eq ! (
1209+ DataTypeNode :: new( "IntervalMicrosecond" ) . unwrap( ) ,
1210+ DataTypeNode :: Interval ( IntervalType :: Microsecond )
1211+ ) ;
1212+ assert_eq ! (
1213+ DataTypeNode :: new( "IntervalMillisecond" ) . unwrap( ) ,
1214+ DataTypeNode :: Interval ( IntervalType :: Millisecond )
1215+ ) ;
1216+ assert_eq ! (
1217+ DataTypeNode :: new( "IntervalSecond" ) . unwrap( ) ,
1218+ DataTypeNode :: Interval ( IntervalType :: Second )
1219+ ) ;
1220+ assert_eq ! (
1221+ DataTypeNode :: new( "IntervalMinute" ) . unwrap( ) ,
1222+ DataTypeNode :: Interval ( IntervalType :: Minute )
1223+ ) ;
1224+ assert_eq ! (
1225+ DataTypeNode :: new( "IntervalHour" ) . unwrap( ) ,
1226+ DataTypeNode :: Interval ( IntervalType :: Hour )
1227+ ) ;
1228+ assert_eq ! (
1229+ DataTypeNode :: new( "IntervalDay" ) . unwrap( ) ,
1230+ DataTypeNode :: Interval ( IntervalType :: Day )
1231+ ) ;
1232+ assert_eq ! (
1233+ DataTypeNode :: new( "IntervalWeek" ) . unwrap( ) ,
1234+ DataTypeNode :: Interval ( IntervalType :: Week )
1235+ ) ;
1236+ assert_eq ! (
1237+ DataTypeNode :: new( "IntervalMonth" ) . unwrap( ) ,
1238+ DataTypeNode :: Interval ( IntervalType :: Month )
1239+ ) ;
1240+ assert_eq ! (
1241+ DataTypeNode :: new( "IntervalQuarter" ) . unwrap( ) ,
1242+ DataTypeNode :: Interval ( IntervalType :: Quarter )
1243+ ) ;
1244+ assert_eq ! (
1245+ DataTypeNode :: new( "IntervalYear" ) . unwrap( ) ,
1246+ DataTypeNode :: Interval ( IntervalType :: Year )
1247+ ) ;
1248+ }
1249+
11391250 #[ test]
11401251 fn test_data_type_new_low_cardinality ( ) {
11411252 assert_eq ! (
@@ -1542,6 +1653,54 @@ mod tests {
15421653 }
15431654 }
15441655
1656+ #[ test]
1657+ fn test_interval_to_string ( ) {
1658+ assert_eq ! (
1659+ DataTypeNode :: Interval ( IntervalType :: Nanosecond ) . to_string( ) ,
1660+ "IntervalNanosecond"
1661+ ) ;
1662+ assert_eq ! (
1663+ DataTypeNode :: Interval ( IntervalType :: Microsecond ) . to_string( ) ,
1664+ "IntervalMicrosecond"
1665+ ) ;
1666+ assert_eq ! (
1667+ DataTypeNode :: Interval ( IntervalType :: Millisecond ) . to_string( ) ,
1668+ "IntervalMillisecond"
1669+ ) ;
1670+ assert_eq ! (
1671+ DataTypeNode :: Interval ( IntervalType :: Second ) . to_string( ) ,
1672+ "IntervalSecond"
1673+ ) ;
1674+ assert_eq ! (
1675+ DataTypeNode :: Interval ( IntervalType :: Minute ) . to_string( ) ,
1676+ "IntervalMinute"
1677+ ) ;
1678+ assert_eq ! (
1679+ DataTypeNode :: Interval ( IntervalType :: Hour ) . to_string( ) ,
1680+ "IntervalHour"
1681+ ) ;
1682+ assert_eq ! (
1683+ DataTypeNode :: Interval ( IntervalType :: Day ) . to_string( ) ,
1684+ "IntervalDay"
1685+ ) ;
1686+ assert_eq ! (
1687+ DataTypeNode :: Interval ( IntervalType :: Week ) . to_string( ) ,
1688+ "IntervalWeek"
1689+ ) ;
1690+ assert_eq ! (
1691+ DataTypeNode :: Interval ( IntervalType :: Month ) . to_string( ) ,
1692+ "IntervalMonth"
1693+ ) ;
1694+ assert_eq ! (
1695+ DataTypeNode :: Interval ( IntervalType :: Quarter ) . to_string( ) ,
1696+ "IntervalQuarter"
1697+ ) ;
1698+ assert_eq ! (
1699+ DataTypeNode :: Interval ( IntervalType :: Year ) . to_string( ) ,
1700+ "IntervalYear"
1701+ ) ;
1702+ }
1703+
15451704 #[ test]
15461705 fn test_data_type_node_into_string ( ) {
15471706 let data_type = DataTypeNode :: new ( "Array(Int32)" ) . unwrap ( ) ;
0 commit comments