@@ -179,81 +179,100 @@ impl From<DataTypeNode> for String {
179179impl Display for DataTypeNode {
180180 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
181181 use DataTypeNode :: * ;
182- let str = match self {
183- UInt8 => "UInt8" . to_string ( ) ,
184- UInt16 => "UInt16" . to_string ( ) ,
185- UInt32 => "UInt32" . to_string ( ) ,
186- UInt64 => "UInt64" . to_string ( ) ,
187- UInt128 => "UInt128" . to_string ( ) ,
188- UInt256 => "UInt256" . to_string ( ) ,
189- Int8 => "Int8" . to_string ( ) ,
190- Int16 => "Int16" . to_string ( ) ,
191- Int32 => "Int32" . to_string ( ) ,
192- Int64 => "Int64" . to_string ( ) ,
193- Int128 => "Int128" . to_string ( ) ,
194- Int256 => "Int256" . to_string ( ) ,
195- Float32 => "Float32" . to_string ( ) ,
196- Float64 => "Float64" . to_string ( ) ,
197- BFloat16 => "BFloat16" . to_string ( ) ,
182+ match self {
183+ UInt8 => write ! ( f , "UInt8" ) ,
184+ UInt16 => write ! ( f , "UInt16" ) ,
185+ UInt32 => write ! ( f , "UInt32" ) ,
186+ UInt64 => write ! ( f , "UInt64" ) ,
187+ UInt128 => write ! ( f , "UInt128" ) ,
188+ UInt256 => write ! ( f , "UInt256" ) ,
189+ Int8 => write ! ( f , "Int8" ) ,
190+ Int16 => write ! ( f , "Int16" ) ,
191+ Int32 => write ! ( f , "Int32" ) ,
192+ Int64 => write ! ( f , "Int64" ) ,
193+ Int128 => write ! ( f , "Int128" ) ,
194+ Int256 => write ! ( f , "Int256" ) ,
195+ Float32 => write ! ( f , "Float32" ) ,
196+ Float64 => write ! ( f , "Float64" ) ,
197+ BFloat16 => write ! ( f , "BFloat16" ) ,
198198 Decimal ( precision, scale, _) => {
199- format ! ( "Decimal({precision}, {scale})" )
199+ write ! ( f , "Decimal({precision}, {scale})" )
200200 }
201- String => "String" . to_string ( ) ,
202- UUID => "UUID" . to_string ( ) ,
203- Date => "Date" . to_string ( ) ,
204- Date32 => "Date32" . to_string ( ) ,
205- DateTime ( None ) => "DateTime" . to_string ( ) ,
206- DateTime ( Some ( tz) ) => format ! ( "DateTime('{tz}')" ) ,
207- DateTime64 ( precision, None ) => format ! ( "DateTime64({precision})" ) ,
208- DateTime64 ( precision, Some ( tz) ) => format ! ( "DateTime64({precision}, '{tz}')" ) ,
209- Time => "Time" . to_string ( ) ,
210- Time64 ( precision) => format ! ( "Time64({precision})" ) ,
211- IPv4 => "IPv4" . to_string ( ) ,
212- IPv6 => "IPv6" . to_string ( ) ,
213- Bool => "Bool" . to_string ( ) ,
214- Nullable ( inner) => format ! ( "Nullable({inner})" ) ,
215- Array ( inner) => format ! ( "Array({inner})" ) ,
201+ String => write ! ( f , "String" ) ,
202+ UUID => write ! ( f , "UUID" ) ,
203+ Date => write ! ( f , "Date" ) ,
204+ Date32 => write ! ( f , "Date32" ) ,
205+ DateTime ( None ) => write ! ( f , "DateTime" ) ,
206+ DateTime ( Some ( tz) ) => write ! ( f , "DateTime('{tz}')" ) ,
207+ DateTime64 ( precision, None ) => write ! ( f , "DateTime64({precision})" ) ,
208+ DateTime64 ( precision, Some ( tz) ) => write ! ( f , "DateTime64({precision}, '{tz}')" ) ,
209+ Time => write ! ( f , "Time" ) ,
210+ Time64 ( precision) => write ! ( f , "Time64({precision})" ) ,
211+ IPv4 => write ! ( f , "IPv4" ) ,
212+ IPv6 => write ! ( f , "IPv6" ) ,
213+ Bool => write ! ( f , "Bool" ) ,
214+ Nullable ( inner) => write ! ( f , "Nullable({inner})" ) ,
215+ Array ( inner) => write ! ( f , "Array({inner})" ) ,
216216 Tuple ( elements) => {
217- let elements_str = data_types_to_string ( elements) ;
218- format ! ( "Tuple({elements_str})" )
217+ write ! ( f, "Tuple(" ) ?;
218+ for ( i, element) in elements. iter ( ) . enumerate ( ) {
219+ if i > 0 {
220+ write ! ( f, ", " ) ?;
221+ }
222+ write ! ( f, "{element}" ) ?;
223+ }
224+ write ! ( f, ")" )
219225 }
220226 Map ( [ key, value] ) => {
221- format ! ( "Map({key}, {value})" )
227+ write ! ( f , "Map({key}, {value})" )
222228 }
223229 LowCardinality ( inner) => {
224- format ! ( "LowCardinality({inner})" )
230+ write ! ( f , "LowCardinality({inner})" )
225231 }
226232 Enum ( enum_type, values) => {
227233 let mut values_vec = values. iter ( ) . collect :: < Vec < _ > > ( ) ;
228234 values_vec. sort_by ( |( i1, _) , ( i2, _) | ( * i1) . cmp ( * i2) ) ;
229- let values_str = values_vec
230- . iter ( )
231- . map ( |( index, name) | format ! ( "'{name}' = {index}" ) )
232- . collect :: < Vec < _ > > ( )
233- . join ( ", " ) ;
234- format ! ( "{enum_type}({values_str})" )
235+ write ! ( f, "{enum_type}(" ) ?;
236+ for ( i, ( index, name) ) in values_vec. iter ( ) . enumerate ( ) {
237+ if i > 0 {
238+ write ! ( f, ", " ) ?;
239+ }
240+ write ! ( f, "'{name}' = {index}" ) ?;
241+ }
242+ write ! ( f, ")" )
235243 }
236244 AggregateFunction ( func_name, args) => {
237- let args_str = data_types_to_string ( args) ;
238- format ! ( "AggregateFunction({func_name}, {args_str})" )
245+ write ! ( f, "AggregateFunction({func_name}, " ) ?;
246+ for ( i, element) in args. iter ( ) . enumerate ( ) {
247+ if i > 0 {
248+ write ! ( f, ", " ) ?;
249+ }
250+ write ! ( f, "{element}" ) ?;
251+ }
252+ write ! ( f, ")" )
239253 }
240254 FixedString ( size) => {
241- format ! ( "FixedString({size})" )
255+ write ! ( f , "FixedString({size})" )
242256 }
243257 Variant ( types) => {
244- let types_str = data_types_to_string ( types) ;
245- format ! ( "Variant({types_str})" )
258+ write ! ( f, "Variant(" ) ?;
259+ for ( i, element) in types. iter ( ) . enumerate ( ) {
260+ if i > 0 {
261+ write ! ( f, ", " ) ?;
262+ }
263+ write ! ( f, "{element}" ) ?;
264+ }
265+ write ! ( f, ")" )
246266 }
247- JSON => "JSON" . to_string ( ) ,
248- Dynamic => "Dynamic" . to_string ( ) ,
249- Point => "Point" . to_string ( ) ,
250- Ring => "Ring" . to_string ( ) ,
251- LineString => "LineString" . to_string ( ) ,
252- MultiLineString => "MultiLineString" . to_string ( ) ,
253- Polygon => "Polygon" . to_string ( ) ,
254- MultiPolygon => "MultiPolygon" . to_string ( ) ,
255- } ;
256- write ! ( f, "{str}" )
267+ JSON => write ! ( f, "JSON" ) ,
268+ Dynamic => write ! ( f, "Dynamic" ) ,
269+ Point => write ! ( f, "Point" ) ,
270+ Ring => write ! ( f, "Ring" ) ,
271+ LineString => write ! ( f, "LineString" ) ,
272+ MultiLineString => write ! ( f, "MultiLineString" ) ,
273+ Polygon => write ! ( f, "Polygon" ) ,
274+ MultiPolygon => write ! ( f, "MultiPolygon" ) ,
275+ }
257276 }
258277}
259278
@@ -373,14 +392,6 @@ impl Display for DateTimePrecision {
373392 }
374393}
375394
376- fn data_types_to_string ( elements : & [ DataTypeNode ] ) -> String {
377- elements
378- . iter ( )
379- . map ( |a| a. to_string ( ) )
380- . collect :: < Vec < _ > > ( )
381- . join ( ", " )
382- }
383-
384395fn parse_fixed_string ( input : & str ) -> Result < DataTypeNode , TypesError > {
385396 if input. len ( ) >= 14 {
386397 let size_str = & input[ 12 ..input. len ( ) - 1 ] ;
@@ -745,6 +756,107 @@ fn parse_enum_values_map(input: &str) -> Result<HashMap<i16, String>, TypesError
745756mod tests {
746757 use super :: * ;
747758
759+ #[ test]
760+ fn test_aggregate_function_display ( ) {
761+ let simple = DataTypeNode :: AggregateFunction ( "sum" . to_string ( ) , vec ! [ DataTypeNode :: UInt64 ] ) ;
762+ assert_eq ! ( simple. to_string( ) , "AggregateFunction(sum, UInt64)" ) ;
763+
764+ let complex = DataTypeNode :: AggregateFunction (
765+ "groupArray" . to_string ( ) ,
766+ vec ! [
767+ DataTypeNode :: String ,
768+ DataTypeNode :: UInt32 ,
769+ DataTypeNode :: Nullable ( Box :: new( DataTypeNode :: Float64 ) ) ,
770+ ] ,
771+ ) ;
772+ assert_eq ! (
773+ complex. to_string( ) ,
774+ "AggregateFunction(groupArray, String, UInt32, Nullable(Float64))"
775+ ) ;
776+ }
777+
778+ #[ test]
779+ fn test_tuple_display ( ) {
780+ let empty = DataTypeNode :: Tuple ( vec ! [ ] ) ;
781+ assert_eq ! ( empty. to_string( ) , "Tuple()" ) ;
782+
783+ let single = DataTypeNode :: Tuple ( vec ! [ DataTypeNode :: String ] ) ;
784+ assert_eq ! ( single. to_string( ) , "Tuple(String)" ) ;
785+
786+ let multiple = DataTypeNode :: Tuple ( vec ! [
787+ DataTypeNode :: UInt64 ,
788+ DataTypeNode :: String ,
789+ DataTypeNode :: DateTime ( None ) ,
790+ DataTypeNode :: Array ( Box :: new( DataTypeNode :: Int32 ) ) ,
791+ ] ) ;
792+ assert_eq ! (
793+ multiple. to_string( ) ,
794+ "Tuple(UInt64, String, DateTime, Array(Int32))"
795+ ) ;
796+ }
797+
798+ #[ test]
799+ fn test_enum_display ( ) {
800+ let mut values1 = HashMap :: new ( ) ;
801+ values1. insert ( 1 , "one" . to_string ( ) ) ;
802+ values1. insert ( 2 , "two" . to_string ( ) ) ;
803+ values1. insert ( 3 , "three" . to_string ( ) ) ;
804+
805+ let simple_enum = DataTypeNode :: Enum ( EnumType :: Enum8 , values1) ;
806+ assert_eq ! (
807+ simple_enum. to_string( ) ,
808+ "Enum8('one' = 1, 'two' = 2, 'three' = 3)"
809+ ) ;
810+
811+ // Enum with unordered values (should sort by index)
812+ let mut values2 = HashMap :: new ( ) ;
813+ values2. insert ( 10 , "ten" . to_string ( ) ) ;
814+ values2. insert ( 1 , "one" . to_string ( ) ) ;
815+ values2. insert ( 5 , "five" . to_string ( ) ) ;
816+
817+ let ordered_enum = DataTypeNode :: Enum ( EnumType :: Enum16 , values2) ;
818+ assert_eq ! (
819+ ordered_enum. to_string( ) ,
820+ "Enum16('one' = 1, 'five' = 5, 'ten' = 10)"
821+ ) ;
822+ }
823+
824+ #[ test]
825+ fn test_variant_display ( ) {
826+ // Empty variant
827+ let empty = DataTypeNode :: Variant ( vec ! [ ] ) ;
828+ assert_eq ! ( empty. to_string( ) , "Variant()" ) ;
829+
830+ // Single type variant
831+ let single = DataTypeNode :: Variant ( vec ! [ DataTypeNode :: String ] ) ;
832+ assert_eq ! ( single. to_string( ) , "Variant(String)" ) ;
833+
834+ // Multiple types variant
835+ let multiple = DataTypeNode :: Variant ( vec ! [
836+ DataTypeNode :: UInt64 ,
837+ DataTypeNode :: String ,
838+ DataTypeNode :: Nullable ( Box :: new( DataTypeNode :: DateTime ( None ) ) ) ,
839+ DataTypeNode :: Array ( Box :: new( DataTypeNode :: Int32 ) ) ,
840+ ] ) ;
841+ assert_eq ! (
842+ multiple. to_string( ) ,
843+ "Variant(UInt64, String, Nullable(DateTime), Array(Int32))"
844+ ) ;
845+
846+ // Nested variant
847+ let nested = DataTypeNode :: Variant ( vec ! [
848+ DataTypeNode :: Tuple ( vec![ DataTypeNode :: String , DataTypeNode :: UInt64 ] ) ,
849+ DataTypeNode :: Map ( [
850+ Box :: new( DataTypeNode :: String ) ,
851+ Box :: new( DataTypeNode :: Int32 ) ,
852+ ] ) ,
853+ ] ) ;
854+ assert_eq ! (
855+ nested. to_string( ) ,
856+ "Variant(Tuple(String, UInt64), Map(String, Int32))"
857+ ) ;
858+ }
859+
748860 #[ test]
749861 fn test_data_type_new_simple ( ) {
750862 assert_eq ! ( DataTypeNode :: new( "UInt8" ) . unwrap( ) , DataTypeNode :: UInt8 ) ;
0 commit comments