Skip to main content

datatypes/
data_type.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt;
16use std::sync::Arc;
17
18use arrow::datatypes::{
19    DataType as ArrowDataType, IntervalUnit as ArrowIntervalUnit, TimeUnit as ArrowTimeUnit,
20};
21use arrow_schema::DECIMAL_DEFAULT_SCALE;
22use common_decimal::decimal128::DECIMAL128_MAX_PRECISION;
23use common_time::interval::IntervalUnit;
24use common_time::timestamp::TimeUnit;
25use enum_dispatch::enum_dispatch;
26use paste::paste;
27use serde::{Deserialize, Serialize};
28
29use crate::error::{self, Error, Result};
30use crate::type_id::LogicalTypeId;
31use crate::types::json_type::JsonNativeType;
32use crate::types::{
33    BinaryType, BooleanType, DateType, Decimal128Type, DictionaryType, DurationMicrosecondType,
34    DurationMillisecondType, DurationNanosecondType, DurationSecondType, DurationType, Float32Type,
35    Float64Type, Int8Type, Int16Type, Int32Type, Int64Type, IntervalDayTimeType,
36    IntervalMonthDayNanoType, IntervalType, IntervalYearMonthType, JsonType, ListType, NullType,
37    StringType, StructType, TimeMillisecondType, TimeType, TimestampMicrosecondType,
38    TimestampMillisecondType, TimestampNanosecondType, TimestampSecondType, TimestampType,
39    UInt8Type, UInt16Type, UInt32Type, UInt64Type, VectorType,
40};
41use crate::value::Value;
42use crate::vectors::MutableVector;
43
44#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
45#[enum_dispatch(DataType)]
46pub enum ConcreteDataType {
47    Null(NullType),
48    Boolean(BooleanType),
49
50    // Numeric types:
51    Int8(Int8Type),
52    Int16(Int16Type),
53    Int32(Int32Type),
54    Int64(Int64Type),
55    UInt8(UInt8Type),
56    UInt16(UInt16Type),
57    UInt32(UInt32Type),
58    UInt64(UInt64Type),
59    Float32(Float32Type),
60    Float64(Float64Type),
61
62    // Decimal128 type:
63    Decimal128(Decimal128Type),
64
65    // String types:
66    Binary(BinaryType),
67    String(StringType),
68
69    // Date and time types:
70    Date(DateType),
71    Timestamp(TimestampType),
72    Time(TimeType),
73
74    // Duration type:
75    Duration(DurationType),
76
77    // Interval type:
78    Interval(IntervalType),
79
80    // Compound types:
81    List(ListType),
82    Dictionary(DictionaryType),
83    Struct(StructType),
84
85    // JSON type:
86    Json(JsonType),
87
88    // Vector type:
89    Vector(VectorType),
90}
91
92impl fmt::Display for ConcreteDataType {
93    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94        match self {
95            ConcreteDataType::Null(v) => write!(f, "{}", v.name()),
96            ConcreteDataType::Boolean(v) => write!(f, "{}", v.name()),
97            ConcreteDataType::Int8(v) => write!(f, "{}", v.name()),
98            ConcreteDataType::Int16(v) => write!(f, "{}", v.name()),
99            ConcreteDataType::Int32(v) => write!(f, "{}", v.name()),
100            ConcreteDataType::Int64(v) => write!(f, "{}", v.name()),
101            ConcreteDataType::UInt8(v) => write!(f, "{}", v.name()),
102            ConcreteDataType::UInt16(v) => write!(f, "{}", v.name()),
103            ConcreteDataType::UInt32(v) => write!(f, "{}", v.name()),
104            ConcreteDataType::UInt64(v) => write!(f, "{}", v.name()),
105            ConcreteDataType::Float32(v) => write!(f, "{}", v.name()),
106            ConcreteDataType::Float64(v) => write!(f, "{}", v.name()),
107            ConcreteDataType::Binary(v) => write!(f, "{}", v.name()),
108            ConcreteDataType::String(v) => write!(f, "{}", v.name()),
109            ConcreteDataType::Date(v) => write!(f, "{}", v.name()),
110            ConcreteDataType::Timestamp(t) => match t {
111                TimestampType::Second(v) => write!(f, "{}", v.name()),
112                TimestampType::Millisecond(v) => write!(f, "{}", v.name()),
113                TimestampType::Microsecond(v) => write!(f, "{}", v.name()),
114                TimestampType::Nanosecond(v) => write!(f, "{}", v.name()),
115            },
116            ConcreteDataType::Time(t) => match t {
117                TimeType::Second(v) => write!(f, "{}", v.name()),
118                TimeType::Millisecond(v) => write!(f, "{}", v.name()),
119                TimeType::Microsecond(v) => write!(f, "{}", v.name()),
120                TimeType::Nanosecond(v) => write!(f, "{}", v.name()),
121            },
122            ConcreteDataType::Interval(i) => match i {
123                IntervalType::YearMonth(v) => write!(f, "{}", v.name()),
124                IntervalType::DayTime(v) => write!(f, "{}", v.name()),
125                IntervalType::MonthDayNano(v) => write!(f, "{}", v.name()),
126            },
127            ConcreteDataType::Duration(d) => match d {
128                DurationType::Second(v) => write!(f, "{}", v.name()),
129                DurationType::Millisecond(v) => write!(f, "{}", v.name()),
130                DurationType::Microsecond(v) => write!(f, "{}", v.name()),
131                DurationType::Nanosecond(v) => write!(f, "{}", v.name()),
132            },
133            ConcreteDataType::Decimal128(v) => write!(f, "{}", v.name()),
134            ConcreteDataType::List(v) => write!(f, "{}", v.name()),
135            ConcreteDataType::Struct(v) => write!(f, "{}", v.name()),
136            ConcreteDataType::Dictionary(v) => write!(f, "{}", v.name()),
137            ConcreteDataType::Json(v) => write!(f, "{}", v.name()),
138            ConcreteDataType::Vector(v) => write!(f, "{}", v.name()),
139        }
140    }
141}
142
143// TODO(yingwen): Refactor these `is_xxx()` methods, such as adding a `properties()` method
144// returning all these properties to the `DataType` trait
145impl ConcreteDataType {
146    pub fn is_float(&self) -> bool {
147        matches!(
148            self,
149            ConcreteDataType::Float64(_) | ConcreteDataType::Float32(_)
150        )
151    }
152
153    pub fn is_boolean(&self) -> bool {
154        matches!(self, ConcreteDataType::Boolean(_))
155    }
156
157    pub fn is_string(&self) -> bool {
158        matches!(self, ConcreteDataType::String(_))
159    }
160
161    pub fn is_stringifiable(&self) -> bool {
162        matches!(
163            self,
164            ConcreteDataType::String(_)
165                | ConcreteDataType::Date(_)
166                | ConcreteDataType::Timestamp(_)
167                | ConcreteDataType::Time(_)
168                | ConcreteDataType::Interval(_)
169                | ConcreteDataType::Duration(_)
170                | ConcreteDataType::Decimal128(_)
171                | ConcreteDataType::Binary(_)
172                | ConcreteDataType::Json(_)
173                | ConcreteDataType::Vector(_)
174        )
175    }
176
177    pub fn is_signed(&self) -> bool {
178        matches!(
179            self,
180            ConcreteDataType::Int8(_)
181                | ConcreteDataType::Int16(_)
182                | ConcreteDataType::Int32(_)
183                | ConcreteDataType::Int64(_)
184                | ConcreteDataType::Date(_)
185                | ConcreteDataType::Timestamp(_)
186                | ConcreteDataType::Time(_)
187                | ConcreteDataType::Interval(_)
188                | ConcreteDataType::Duration(_)
189                | ConcreteDataType::Decimal128(_)
190        )
191    }
192
193    pub fn is_unsigned(&self) -> bool {
194        matches!(
195            self,
196            ConcreteDataType::UInt8(_)
197                | ConcreteDataType::UInt16(_)
198                | ConcreteDataType::UInt32(_)
199                | ConcreteDataType::UInt64(_)
200        )
201    }
202
203    pub fn is_numeric(&self) -> bool {
204        matches!(
205            self,
206            ConcreteDataType::Int8(_)
207                | ConcreteDataType::Int16(_)
208                | ConcreteDataType::Int32(_)
209                | ConcreteDataType::Int64(_)
210                | ConcreteDataType::UInt8(_)
211                | ConcreteDataType::UInt16(_)
212                | ConcreteDataType::UInt32(_)
213                | ConcreteDataType::UInt64(_)
214                | ConcreteDataType::Float32(_)
215                | ConcreteDataType::Float64(_)
216        )
217    }
218
219    pub fn is_timestamp(&self) -> bool {
220        matches!(self, ConcreteDataType::Timestamp(_))
221    }
222
223    pub fn is_decimal(&self) -> bool {
224        matches!(self, ConcreteDataType::Decimal128(_))
225    }
226
227    pub fn is_json(&self) -> bool {
228        matches!(self, ConcreteDataType::Json(_))
229    }
230
231    /// Returns whether this is a JSON2 data type.
232    pub fn is_json2(&self) -> bool {
233        self.as_json().is_some_and(|json_type| json_type.is_json2())
234    }
235
236    pub fn is_vector(&self) -> bool {
237        matches!(self, ConcreteDataType::Vector(_))
238    }
239
240    pub fn numerics() -> Vec<ConcreteDataType> {
241        vec![
242            ConcreteDataType::int8_datatype(),
243            ConcreteDataType::int16_datatype(),
244            ConcreteDataType::int32_datatype(),
245            ConcreteDataType::int64_datatype(),
246            ConcreteDataType::uint8_datatype(),
247            ConcreteDataType::uint16_datatype(),
248            ConcreteDataType::uint32_datatype(),
249            ConcreteDataType::uint64_datatype(),
250            ConcreteDataType::float32_datatype(),
251            ConcreteDataType::float64_datatype(),
252        ]
253    }
254
255    pub fn unsigned_integers() -> Vec<ConcreteDataType> {
256        vec![
257            ConcreteDataType::uint8_datatype(),
258            ConcreteDataType::uint16_datatype(),
259            ConcreteDataType::uint32_datatype(),
260            ConcreteDataType::uint64_datatype(),
261        ]
262    }
263
264    pub fn timestamps() -> Vec<ConcreteDataType> {
265        vec![
266            ConcreteDataType::timestamp_second_datatype(),
267            ConcreteDataType::timestamp_millisecond_datatype(),
268            ConcreteDataType::timestamp_microsecond_datatype(),
269            ConcreteDataType::timestamp_nanosecond_datatype(),
270        ]
271    }
272
273    /// Convert arrow data type to [ConcreteDataType].
274    ///
275    /// # Panics
276    /// Panic if given arrow data type is not supported.
277    pub fn from_arrow_type(dt: &ArrowDataType) -> Self {
278        ConcreteDataType::try_from(dt).expect("Unimplemented type")
279    }
280
281    pub fn is_null(&self) -> bool {
282        matches!(self, ConcreteDataType::Null(NullType))
283    }
284
285    /// Try to cast the type as a [`ListType`].
286    pub fn as_list(&self) -> Option<&ListType> {
287        match self {
288            ConcreteDataType::List(t) => Some(t),
289            _ => None,
290        }
291    }
292
293    pub fn as_struct(&self) -> Option<&StructType> {
294        match self {
295            ConcreteDataType::Struct(s) => Some(s),
296            _ => None,
297        }
298    }
299
300    /// Try to cast data type as a [`TimestampType`].
301    pub fn as_timestamp(&self) -> Option<TimestampType> {
302        match self {
303            ConcreteDataType::Timestamp(t) => Some(*t),
304            _ => None,
305        }
306    }
307
308    /// Try to get numeric precision, returns `None` if it's not numeric type
309    pub fn numeric_precision(&self) -> Option<u8> {
310        match self {
311            ConcreteDataType::Int8(_) | ConcreteDataType::UInt8(_) => Some(3),
312            ConcreteDataType::Int16(_) | ConcreteDataType::UInt16(_) => Some(5),
313            ConcreteDataType::Int32(_) | ConcreteDataType::UInt32(_) => Some(10),
314            ConcreteDataType::Int64(_) => Some(19),
315            ConcreteDataType::UInt64(_) => Some(20),
316            ConcreteDataType::Float32(_) => Some(12),
317            ConcreteDataType::Float64(_) => Some(22),
318            ConcreteDataType::Decimal128(decimal_type) => Some(decimal_type.precision()),
319            _ => None,
320        }
321    }
322
323    /// Try to get numeric scale, returns `None` if it's float or not numeric type
324    pub fn numeric_scale(&self) -> Option<i8> {
325        match self {
326            ConcreteDataType::Int8(_)
327            | ConcreteDataType::UInt8(_)
328            | ConcreteDataType::Int16(_)
329            | ConcreteDataType::UInt16(_)
330            | ConcreteDataType::Int32(_)
331            | ConcreteDataType::UInt32(_)
332            | ConcreteDataType::Int64(_)
333            | ConcreteDataType::UInt64(_) => Some(0),
334            ConcreteDataType::Float32(_) | ConcreteDataType::Float64(_) => None,
335            ConcreteDataType::Decimal128(decimal_type) => Some(decimal_type.scale()),
336            _ => None,
337        }
338    }
339
340    /// Try to cast data type as a [`TimeType`].
341    pub fn as_time(&self) -> Option<TimeType> {
342        match self {
343            ConcreteDataType::Int64(_) => Some(TimeType::Millisecond(TimeMillisecondType)),
344            ConcreteDataType::Time(t) => Some(*t),
345            _ => None,
346        }
347    }
348
349    pub fn as_decimal128(&self) -> Option<Decimal128Type> {
350        match self {
351            ConcreteDataType::Decimal128(d) => Some(*d),
352            _ => None,
353        }
354    }
355
356    pub fn as_json(&self) -> Option<&JsonType> {
357        match self {
358            ConcreteDataType::Json(j) => Some(j),
359            _ => None,
360        }
361    }
362
363    pub fn as_vector(&self) -> Option<VectorType> {
364        match self {
365            ConcreteDataType::Vector(v) => Some(*v),
366            _ => None,
367        }
368    }
369
370    /// Checks if the data type can cast to another data type.
371    pub fn can_arrow_type_cast_to(&self, to_type: &ConcreteDataType) -> bool {
372        match (self, to_type) {
373            (ConcreteDataType::Json(this), ConcreteDataType::Json(that)) => that.is_include(this),
374            _ => arrow::compute::can_cast_types(&self.as_arrow_type(), &to_type.as_arrow_type()),
375        }
376    }
377
378    /// Returns true if both types are timestamps and `to_type`'s unit is strictly
379    /// finer (e.g. `Second -> Millisecond`). Such a change is lossless for
380    /// values that fit the target unit's `i64` range; the narrowing direction
381    /// truncates values.
382    pub fn is_timestamp_unit_widening_to(&self, to_type: &ConcreteDataType) -> bool {
383        match (self.as_timestamp(), to_type.as_timestamp()) {
384            (Some(from), Some(to)) => to.unit() > from.unit(),
385            _ => false,
386        }
387    }
388
389    /// Try to cast data type as a [`DurationType`].
390    pub fn as_duration(&self) -> Option<DurationType> {
391        match self {
392            ConcreteDataType::Duration(d) => Some(*d),
393            _ => None,
394        }
395    }
396
397    /// Return the datatype name in postgres type system
398    pub fn postgres_datatype_name(&self) -> &'static str {
399        match self {
400            &ConcreteDataType::Null(_) => "UNKNOWN",
401            &ConcreteDataType::Boolean(_) => "BOOL",
402            &ConcreteDataType::Int8(_) | &ConcreteDataType::UInt8(_) => "CHAR",
403            &ConcreteDataType::Int16(_) | &ConcreteDataType::UInt16(_) => "INT2",
404            &ConcreteDataType::Int32(_) | &ConcreteDataType::UInt32(_) => "INT4",
405            &ConcreteDataType::Int64(_) | &ConcreteDataType::UInt64(_) => "INT8",
406            &ConcreteDataType::Float32(_) => "FLOAT4",
407            &ConcreteDataType::Float64(_) => "FLOAT8",
408            &ConcreteDataType::Binary(_) | &ConcreteDataType::Vector(_) => "BYTEA",
409            &ConcreteDataType::String(_) => "VARCHAR",
410            &ConcreteDataType::Date(_) => "DATE",
411            &ConcreteDataType::Timestamp(_) => "TIMESTAMP",
412            &ConcreteDataType::Time(_) => "TIME",
413            &ConcreteDataType::Interval(_) => "INTERVAL",
414            &ConcreteDataType::Decimal128(_) => "NUMERIC",
415            &ConcreteDataType::Json(_) => "JSON",
416            ConcreteDataType::List(list) => match list.item_type() {
417                &ConcreteDataType::Null(_) => "UNKNOWN",
418                &ConcreteDataType::Boolean(_) => "_BOOL",
419                &ConcreteDataType::Int8(_) | &ConcreteDataType::UInt8(_) => "_CHAR",
420                &ConcreteDataType::Int16(_) | &ConcreteDataType::UInt16(_) => "_INT2",
421                &ConcreteDataType::Int32(_) | &ConcreteDataType::UInt32(_) => "_INT4",
422                &ConcreteDataType::Int64(_) | &ConcreteDataType::UInt64(_) => "_INT8",
423                &ConcreteDataType::Float32(_) => "_FLOAT4",
424                &ConcreteDataType::Float64(_) => "_FLOAT8",
425                &ConcreteDataType::Binary(_) => "_BYTEA",
426                &ConcreteDataType::String(_) => "_VARCHAR",
427                &ConcreteDataType::Date(_) => "_DATE",
428                &ConcreteDataType::Timestamp(_) => "_TIMESTAMP",
429                &ConcreteDataType::Time(_) => "_TIME",
430                &ConcreteDataType::Interval(_) => "_INTERVAL",
431                &ConcreteDataType::Decimal128(_) => "_NUMERIC",
432                &ConcreteDataType::Json(_) => "_JSON",
433                &ConcreteDataType::Duration(_)
434                | &ConcreteDataType::Dictionary(_)
435                | &ConcreteDataType::Vector(_)
436                | &ConcreteDataType::List(_)
437                | &ConcreteDataType::Struct(_) => "UNKNOWN",
438            },
439            &ConcreteDataType::Duration(_)
440            | &ConcreteDataType::Dictionary(_)
441            | &ConcreteDataType::Struct(_) => "UNKNOWN",
442        }
443    }
444}
445
446impl From<&ConcreteDataType> for ConcreteDataType {
447    fn from(t: &ConcreteDataType) -> Self {
448        t.clone()
449    }
450}
451
452impl TryFrom<&ArrowDataType> for ConcreteDataType {
453    type Error = Error;
454
455    fn try_from(dt: &ArrowDataType) -> Result<ConcreteDataType> {
456        let concrete_type = match dt {
457            ArrowDataType::Null => Self::null_datatype(),
458            ArrowDataType::Boolean => Self::boolean_datatype(),
459            ArrowDataType::UInt8 => Self::uint8_datatype(),
460            ArrowDataType::UInt16 => Self::uint16_datatype(),
461            ArrowDataType::UInt32 => Self::uint32_datatype(),
462            ArrowDataType::UInt64 => Self::uint64_datatype(),
463            ArrowDataType::Int8 => Self::int8_datatype(),
464            ArrowDataType::Int16 => Self::int16_datatype(),
465            ArrowDataType::Int32 => Self::int32_datatype(),
466            ArrowDataType::Int64 => Self::int64_datatype(),
467            ArrowDataType::Float32 => Self::float32_datatype(),
468            ArrowDataType::Float64 => Self::float64_datatype(),
469            ArrowDataType::Date32 => Self::date_datatype(),
470            ArrowDataType::Timestamp(u, _) => ConcreteDataType::from_arrow_time_unit(u),
471            ArrowDataType::Interval(u) => ConcreteDataType::from_arrow_interval_unit(u),
472            ArrowDataType::Binary | ArrowDataType::LargeBinary => {
473                Self::Binary(BinaryType::binary())
474            }
475            ArrowDataType::BinaryView => Self::Binary(BinaryType::binary_view()),
476            ArrowDataType::Utf8 => Self::String(StringType::utf8()),
477            ArrowDataType::Utf8View => Self::String(StringType::utf8_view()),
478            ArrowDataType::LargeUtf8 => Self::String(StringType::large_utf8()),
479            ArrowDataType::List(field) => Self::List(ListType::new(Arc::new(
480                ConcreteDataType::from_arrow_type(field.data_type()),
481            ))),
482            ArrowDataType::Dictionary(key_type, value_type) => {
483                let key_type = ConcreteDataType::from_arrow_type(key_type);
484                let value_type = ConcreteDataType::from_arrow_type(value_type);
485                Self::Dictionary(DictionaryType::new(key_type, value_type))
486            }
487            ArrowDataType::Time32(u) => ConcreteDataType::Time(TimeType::from_unit(u.into())),
488            ArrowDataType::Time64(u) => ConcreteDataType::Time(TimeType::from_unit(u.into())),
489            ArrowDataType::Duration(u) => {
490                ConcreteDataType::Duration(DurationType::from_unit(u.into()))
491            }
492            ArrowDataType::Decimal128(precision, scale) => {
493                ConcreteDataType::decimal128_datatype(*precision, *scale)
494            }
495            ArrowDataType::Struct(fields) => {
496                ConcreteDataType::Struct(StructType::try_from_arrow_fields(fields)?)
497            }
498            ArrowDataType::Float16
499            | ArrowDataType::Date64
500            | ArrowDataType::FixedSizeBinary(_)
501            | ArrowDataType::ListView(_)
502            | ArrowDataType::FixedSizeList(_, _)
503            | ArrowDataType::LargeList(_)
504            | ArrowDataType::LargeListView(_)
505            | ArrowDataType::Union(_, _)
506            | ArrowDataType::Decimal256(_, _)
507            | ArrowDataType::Map(_, _)
508            | ArrowDataType::RunEndEncoded(_, _)
509            | ArrowDataType::Decimal32(_, _)
510            | ArrowDataType::Decimal64(_, _) => {
511                return error::UnsupportedArrowTypeSnafu {
512                    arrow_type: dt.clone(),
513                }
514                .fail();
515            }
516        };
517
518        Ok(concrete_type)
519    }
520}
521
522macro_rules! impl_new_concrete_type_functions {
523    ($($Type: ident), +) => {
524        paste! {
525            impl ConcreteDataType {
526                $(
527                    pub fn [<$Type:lower _datatype>]() -> ConcreteDataType {
528                        ConcreteDataType::$Type([<$Type Type>]::default())
529                    }
530                )+
531            }
532        }
533    }
534}
535
536impl_new_concrete_type_functions!(
537    Null, Boolean, UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64, Float32, Float64,
538    Binary, Date, String, Json
539);
540
541impl ConcreteDataType {
542    pub fn large_string_datatype() -> Self {
543        ConcreteDataType::String(StringType::large_utf8())
544    }
545
546    pub fn utf8_view_datatype() -> Self {
547        ConcreteDataType::String(StringType::utf8_view())
548    }
549
550    pub fn binary_view_datatype() -> Self {
551        ConcreteDataType::Binary(BinaryType::binary_view())
552    }
553
554    pub fn timestamp_second_datatype() -> Self {
555        ConcreteDataType::Timestamp(TimestampType::Second(TimestampSecondType))
556    }
557
558    pub fn timestamp_millisecond_datatype() -> Self {
559        ConcreteDataType::Timestamp(TimestampType::Millisecond(TimestampMillisecondType))
560    }
561
562    pub fn timestamp_microsecond_datatype() -> Self {
563        ConcreteDataType::Timestamp(TimestampType::Microsecond(TimestampMicrosecondType))
564    }
565
566    pub fn timestamp_nanosecond_datatype() -> Self {
567        ConcreteDataType::Timestamp(TimestampType::Nanosecond(TimestampNanosecondType))
568    }
569
570    /// Returns the time data type with `TimeUnit`.
571    pub fn time_datatype(unit: TimeUnit) -> Self {
572        ConcreteDataType::Time(TimeType::from_unit(unit))
573    }
574
575    /// Creates a [Time(TimeSecondType)] datatype.
576    pub fn time_second_datatype() -> Self {
577        Self::time_datatype(TimeUnit::Second)
578    }
579
580    /// Creates a [Time(TimeMillisecondType)] datatype.
581    pub fn time_millisecond_datatype() -> Self {
582        Self::time_datatype(TimeUnit::Millisecond)
583    }
584
585    /// Creates a [Time(TimeMicrosecond)] datatype.
586    pub fn time_microsecond_datatype() -> Self {
587        Self::time_datatype(TimeUnit::Microsecond)
588    }
589
590    /// Creates a [Time(TimeNanosecond)] datatype.
591    pub fn time_nanosecond_datatype() -> Self {
592        Self::time_datatype(TimeUnit::Nanosecond)
593    }
594
595    /// Creates a [Duration(DurationSecondType)] datatype.
596    pub fn duration_second_datatype() -> Self {
597        ConcreteDataType::Duration(DurationType::Second(DurationSecondType))
598    }
599
600    /// Creates a [Duration(DurationMillisecondType)] datatype.
601    pub fn duration_millisecond_datatype() -> Self {
602        ConcreteDataType::Duration(DurationType::Millisecond(DurationMillisecondType))
603    }
604
605    /// Creates a [Duration(DurationMicrosecondType)] datatype.
606    pub fn duration_microsecond_datatype() -> Self {
607        ConcreteDataType::Duration(DurationType::Microsecond(DurationMicrosecondType))
608    }
609
610    /// Creates a [Duration(DurationNanosecondType)] datatype.
611    pub fn duration_nanosecond_datatype() -> Self {
612        ConcreteDataType::Duration(DurationType::Nanosecond(DurationNanosecondType))
613    }
614
615    /// Creates a [Interval(IntervalMonthDayNanoType)] datatype.
616    pub fn interval_month_day_nano_datatype() -> Self {
617        ConcreteDataType::Interval(IntervalType::MonthDayNano(IntervalMonthDayNanoType))
618    }
619
620    /// Creates a [Interval(IntervalYearMonthType)] datatype.
621    pub fn interval_year_month_datatype() -> Self {
622        ConcreteDataType::Interval(IntervalType::YearMonth(IntervalYearMonthType))
623    }
624
625    /// Creates a [Interval(IntervalDayTimeType)] datatype.
626    pub fn interval_day_time_datatype() -> Self {
627        ConcreteDataType::Interval(IntervalType::DayTime(IntervalDayTimeType))
628    }
629
630    pub fn timestamp_datatype(unit: TimeUnit) -> Self {
631        match unit {
632            TimeUnit::Second => Self::timestamp_second_datatype(),
633            TimeUnit::Millisecond => Self::timestamp_millisecond_datatype(),
634            TimeUnit::Microsecond => Self::timestamp_microsecond_datatype(),
635            TimeUnit::Nanosecond => Self::timestamp_nanosecond_datatype(),
636        }
637    }
638
639    /// Converts from arrow timestamp unit to
640    pub fn from_arrow_time_unit(t: &ArrowTimeUnit) -> Self {
641        match t {
642            ArrowTimeUnit::Second => Self::timestamp_second_datatype(),
643            ArrowTimeUnit::Millisecond => Self::timestamp_millisecond_datatype(),
644            ArrowTimeUnit::Microsecond => Self::timestamp_microsecond_datatype(),
645            ArrowTimeUnit::Nanosecond => Self::timestamp_nanosecond_datatype(),
646        }
647    }
648
649    pub fn duration_datatype(unit: TimeUnit) -> Self {
650        match unit {
651            TimeUnit::Second => Self::duration_second_datatype(),
652            TimeUnit::Millisecond => Self::duration_millisecond_datatype(),
653            TimeUnit::Microsecond => Self::duration_microsecond_datatype(),
654            TimeUnit::Nanosecond => Self::duration_nanosecond_datatype(),
655        }
656    }
657
658    pub fn interval_datatype(unit: IntervalUnit) -> Self {
659        match unit {
660            IntervalUnit::YearMonth => Self::interval_year_month_datatype(),
661            IntervalUnit::DayTime => Self::interval_day_time_datatype(),
662            IntervalUnit::MonthDayNano => Self::interval_month_day_nano_datatype(),
663        }
664    }
665
666    pub fn from_arrow_interval_unit(u: &ArrowIntervalUnit) -> Self {
667        match u {
668            ArrowIntervalUnit::YearMonth => Self::interval_year_month_datatype(),
669            ArrowIntervalUnit::DayTime => Self::interval_day_time_datatype(),
670            ArrowIntervalUnit::MonthDayNano => Self::interval_month_day_nano_datatype(),
671        }
672    }
673
674    pub fn list_datatype(item_type: Arc<ConcreteDataType>) -> ConcreteDataType {
675        ConcreteDataType::List(ListType::new(item_type))
676    }
677
678    pub fn struct_datatype(fields: StructType) -> ConcreteDataType {
679        ConcreteDataType::Struct(fields)
680    }
681
682    pub fn dictionary_datatype(
683        key_type: ConcreteDataType,
684        value_type: ConcreteDataType,
685    ) -> ConcreteDataType {
686        ConcreteDataType::Dictionary(DictionaryType::new(key_type, value_type))
687    }
688
689    pub fn decimal128_datatype(precision: u8, scale: i8) -> ConcreteDataType {
690        ConcreteDataType::Decimal128(Decimal128Type::new(precision, scale))
691    }
692
693    pub fn decimal128_default_datatype() -> ConcreteDataType {
694        Self::decimal128_datatype(DECIMAL128_MAX_PRECISION, DECIMAL_DEFAULT_SCALE)
695    }
696
697    pub fn vector_datatype(dim: u32) -> ConcreteDataType {
698        ConcreteDataType::Vector(VectorType::new(dim))
699    }
700
701    pub fn vector_default_datatype() -> ConcreteDataType {
702        Self::vector_datatype(0)
703    }
704
705    pub fn json2(native_type: JsonNativeType) -> ConcreteDataType {
706        ConcreteDataType::Json(JsonType::json2(Arc::new(native_type)))
707    }
708}
709
710/// Data type abstraction.
711#[enum_dispatch::enum_dispatch]
712pub trait DataType: std::fmt::Debug + Send + Sync {
713    /// Name of this data type.
714    fn name(&self) -> String;
715
716    /// Returns id of the Logical data type.
717    fn logical_type_id(&self) -> LogicalTypeId;
718
719    /// Returns the default value of this type.
720    fn default_value(&self) -> Value;
721
722    /// Convert this type as [arrow::datatypes::DataType].
723    fn as_arrow_type(&self) -> ArrowDataType;
724
725    /// Creates a mutable vector with given `capacity` of this type.
726    fn create_mutable_vector(&self, capacity: usize) -> Box<dyn MutableVector>;
727
728    /// Casts the value to specific DataType.
729    /// Return None if cast failed.
730    fn try_cast(&self, from: Value) -> Option<Value>;
731}
732
733pub type DataTypeRef = Arc<dyn DataType>;
734
735#[cfg(test)]
736mod tests {
737    use arrow::datatypes::Field;
738
739    use super::*;
740
741    #[test]
742    fn test_is_timestamp_unit_widening_to() {
743        let second = ConcreteDataType::timestamp_second_datatype();
744        let milli = ConcreteDataType::timestamp_millisecond_datatype();
745        let nano = ConcreteDataType::timestamp_nanosecond_datatype();
746
747        assert!(second.is_timestamp_unit_widening_to(&milli));
748        assert!(second.is_timestamp_unit_widening_to(&nano));
749        // Same unit and narrowing are not widening.
750        assert!(!milli.is_timestamp_unit_widening_to(&milli));
751        assert!(!nano.is_timestamp_unit_widening_to(&milli));
752        // Either side being a non-timestamp type disqualifies.
753        assert!(!milli.is_timestamp_unit_widening_to(&ConcreteDataType::int64_datatype()));
754        assert!(!ConcreteDataType::int64_datatype().is_timestamp_unit_widening_to(&nano));
755    }
756
757    #[test]
758    fn test_concrete_type_as_datatype_trait() {
759        let concrete_type = ConcreteDataType::boolean_datatype();
760
761        assert_eq!("Boolean", concrete_type.to_string());
762        assert_eq!(Value::Boolean(false), concrete_type.default_value());
763        assert_eq!(LogicalTypeId::Boolean, concrete_type.logical_type_id());
764        assert_eq!(ArrowDataType::Boolean, concrete_type.as_arrow_type());
765    }
766
767    #[test]
768    fn test_from_arrow_type() {
769        assert!(matches!(
770            ConcreteDataType::from_arrow_type(&ArrowDataType::Null),
771            ConcreteDataType::Null(_)
772        ));
773        assert!(matches!(
774            ConcreteDataType::from_arrow_type(&ArrowDataType::Boolean),
775            ConcreteDataType::Boolean(_)
776        ));
777        assert!(matches!(
778            ConcreteDataType::from_arrow_type(&ArrowDataType::Binary),
779            ConcreteDataType::Binary(_)
780        ));
781        assert!(matches!(
782            ConcreteDataType::from_arrow_type(&ArrowDataType::LargeBinary),
783            ConcreteDataType::Binary(_)
784        ));
785        assert!(matches!(
786            ConcreteDataType::from_arrow_type(&ArrowDataType::Int8),
787            ConcreteDataType::Int8(_)
788        ));
789        assert!(matches!(
790            ConcreteDataType::from_arrow_type(&ArrowDataType::Int16),
791            ConcreteDataType::Int16(_)
792        ));
793        assert!(matches!(
794            ConcreteDataType::from_arrow_type(&ArrowDataType::Int32),
795            ConcreteDataType::Int32(_)
796        ));
797        assert!(matches!(
798            ConcreteDataType::from_arrow_type(&ArrowDataType::Int64),
799            ConcreteDataType::Int64(_)
800        ));
801        assert!(matches!(
802            ConcreteDataType::from_arrow_type(&ArrowDataType::UInt8),
803            ConcreteDataType::UInt8(_)
804        ));
805        assert!(matches!(
806            ConcreteDataType::from_arrow_type(&ArrowDataType::UInt16),
807            ConcreteDataType::UInt16(_)
808        ));
809        assert!(matches!(
810            ConcreteDataType::from_arrow_type(&ArrowDataType::UInt32),
811            ConcreteDataType::UInt32(_)
812        ));
813        assert!(matches!(
814            ConcreteDataType::from_arrow_type(&ArrowDataType::UInt64),
815            ConcreteDataType::UInt64(_)
816        ));
817        assert!(matches!(
818            ConcreteDataType::from_arrow_type(&ArrowDataType::Float32),
819            ConcreteDataType::Float32(_)
820        ));
821        assert!(matches!(
822            ConcreteDataType::from_arrow_type(&ArrowDataType::Float64),
823            ConcreteDataType::Float64(_)
824        ));
825        assert!(matches!(
826            ConcreteDataType::from_arrow_type(&ArrowDataType::Utf8),
827            ConcreteDataType::String(_)
828        ));
829        let utf8_view_string_type = ConcreteDataType::from_arrow_type(&ArrowDataType::Utf8View);
830        assert!(matches!(utf8_view_string_type, ConcreteDataType::String(_)));
831        assert_eq!(
832            ArrowDataType::Utf8View,
833            utf8_view_string_type.as_arrow_type()
834        );
835        // Test LargeUtf8 mapping to large String type
836        let large_string_type = ConcreteDataType::from_arrow_type(&ArrowDataType::LargeUtf8);
837        assert!(matches!(large_string_type, ConcreteDataType::String(_)));
838        if let ConcreteDataType::String(string_type) = &large_string_type {
839            assert!(string_type.is_large());
840        } else {
841            panic!("Expected a String type");
842        }
843        assert_eq!(
844            ConcreteDataType::from_arrow_type(&ArrowDataType::List(Arc::new(Field::new(
845                "item",
846                ArrowDataType::Int32,
847                true,
848            )))),
849            ConcreteDataType::List(ListType::new(Arc::new(ConcreteDataType::int32_datatype())))
850        );
851        assert!(matches!(
852            ConcreteDataType::from_arrow_type(&ArrowDataType::Date32),
853            ConcreteDataType::Date(_)
854        ));
855    }
856
857    #[test]
858    fn test_view_round_trip() {
859        let utf8_view_arrow = ArrowDataType::Utf8View;
860        let concrete_type = ConcreteDataType::from_arrow_type(&utf8_view_arrow);
861        let back_to_arrow = concrete_type.as_arrow_type();
862        assert_eq!(utf8_view_arrow, back_to_arrow);
863
864        let binary_view_arrow = ArrowDataType::BinaryView;
865        let concrete_type = ConcreteDataType::from_arrow_type(&binary_view_arrow);
866        let back_to_arrow = concrete_type.as_arrow_type();
867        assert_eq!(binary_view_arrow, back_to_arrow);
868    }
869
870    #[test]
871    fn test_large_utf8_round_trip() {
872        // Test round-trip conversion for LargeUtf8
873        let large_utf8_arrow = ArrowDataType::LargeUtf8;
874        let concrete_type = ConcreteDataType::from_arrow_type(&large_utf8_arrow);
875        let back_to_arrow = concrete_type.as_arrow_type();
876
877        assert!(matches!(concrete_type, ConcreteDataType::String(_)));
878        // Round-trip should preserve the LargeUtf8 type
879        assert_eq!(large_utf8_arrow, back_to_arrow);
880
881        // Test that Utf8 and LargeUtf8 map to different string variants
882        let utf8_concrete = ConcreteDataType::from_arrow_type(&ArrowDataType::Utf8);
883        let large_utf8_concrete = ConcreteDataType::from_arrow_type(&ArrowDataType::LargeUtf8);
884
885        assert!(matches!(utf8_concrete, ConcreteDataType::String(_)));
886        assert!(matches!(large_utf8_concrete, ConcreteDataType::String(_)));
887
888        // They should have different size types
889        if let (ConcreteDataType::String(utf8_type), ConcreteDataType::String(large_type)) =
890            (&utf8_concrete, &large_utf8_concrete)
891        {
892            assert!(!utf8_type.is_large());
893            assert!(large_type.is_large());
894        } else {
895            panic!("Expected both to be String types");
896        }
897
898        // View strings should be distinct from Utf8 and LargeUtf8.
899        let view_concrete = ConcreteDataType::from_arrow_type(&ArrowDataType::Utf8View);
900        assert_ne!(utf8_concrete, view_concrete);
901        assert_ne!(large_utf8_concrete, view_concrete);
902
903        // They should be different types
904        assert_ne!(utf8_concrete, large_utf8_concrete);
905    }
906
907    #[test]
908    fn test_from_arrow_timestamp() {
909        assert_eq!(
910            ConcreteDataType::timestamp_millisecond_datatype(),
911            ConcreteDataType::from_arrow_time_unit(&ArrowTimeUnit::Millisecond)
912        );
913        assert_eq!(
914            ConcreteDataType::timestamp_microsecond_datatype(),
915            ConcreteDataType::from_arrow_time_unit(&ArrowTimeUnit::Microsecond)
916        );
917        assert_eq!(
918            ConcreteDataType::timestamp_nanosecond_datatype(),
919            ConcreteDataType::from_arrow_time_unit(&ArrowTimeUnit::Nanosecond)
920        );
921        assert_eq!(
922            ConcreteDataType::timestamp_second_datatype(),
923            ConcreteDataType::from_arrow_time_unit(&ArrowTimeUnit::Second)
924        );
925    }
926
927    #[test]
928    fn test_is_null() {
929        assert!(ConcreteDataType::null_datatype().is_null());
930        assert!(!ConcreteDataType::int32_datatype().is_null());
931    }
932
933    #[test]
934    fn test_is_float() {
935        assert!(!ConcreteDataType::int32_datatype().is_float());
936        assert!(ConcreteDataType::float32_datatype().is_float());
937        assert!(ConcreteDataType::float64_datatype().is_float());
938    }
939
940    #[test]
941    fn test_is_boolean() {
942        assert!(!ConcreteDataType::int32_datatype().is_boolean());
943        assert!(!ConcreteDataType::float32_datatype().is_boolean());
944        assert!(ConcreteDataType::boolean_datatype().is_boolean());
945    }
946
947    #[test]
948    fn test_is_decimal() {
949        assert!(!ConcreteDataType::int32_datatype().is_decimal());
950        assert!(!ConcreteDataType::float32_datatype().is_decimal());
951        assert!(ConcreteDataType::decimal128_datatype(10, 2).is_decimal());
952        assert!(ConcreteDataType::decimal128_datatype(18, 6).is_decimal());
953    }
954
955    #[test]
956    fn test_is_stringifiable() {
957        assert!(!ConcreteDataType::int32_datatype().is_stringifiable());
958        assert!(!ConcreteDataType::float32_datatype().is_stringifiable());
959        assert!(ConcreteDataType::string_datatype().is_stringifiable());
960        assert!(ConcreteDataType::binary_datatype().is_stringifiable());
961        assert!(ConcreteDataType::date_datatype().is_stringifiable());
962        assert!(ConcreteDataType::timestamp_second_datatype().is_stringifiable());
963        assert!(ConcreteDataType::timestamp_millisecond_datatype().is_stringifiable());
964        assert!(ConcreteDataType::timestamp_microsecond_datatype().is_stringifiable());
965        assert!(ConcreteDataType::timestamp_nanosecond_datatype().is_stringifiable());
966        assert!(ConcreteDataType::time_second_datatype().is_stringifiable());
967        assert!(ConcreteDataType::time_millisecond_datatype().is_stringifiable());
968        assert!(ConcreteDataType::time_microsecond_datatype().is_stringifiable());
969        assert!(ConcreteDataType::time_nanosecond_datatype().is_stringifiable());
970
971        assert!(ConcreteDataType::interval_year_month_datatype().is_stringifiable());
972        assert!(ConcreteDataType::interval_day_time_datatype().is_stringifiable());
973        assert!(ConcreteDataType::interval_month_day_nano_datatype().is_stringifiable());
974
975        assert!(ConcreteDataType::duration_second_datatype().is_stringifiable());
976        assert!(ConcreteDataType::duration_millisecond_datatype().is_stringifiable());
977        assert!(ConcreteDataType::duration_microsecond_datatype().is_stringifiable());
978        assert!(ConcreteDataType::duration_nanosecond_datatype().is_stringifiable());
979        assert!(ConcreteDataType::decimal128_datatype(10, 2).is_stringifiable());
980        assert!(ConcreteDataType::vector_default_datatype().is_stringifiable());
981    }
982
983    #[test]
984    fn test_is_signed() {
985        assert!(ConcreteDataType::int8_datatype().is_signed());
986        assert!(ConcreteDataType::int16_datatype().is_signed());
987        assert!(ConcreteDataType::int32_datatype().is_signed());
988        assert!(ConcreteDataType::int64_datatype().is_signed());
989        assert!(ConcreteDataType::date_datatype().is_signed());
990        assert!(ConcreteDataType::timestamp_second_datatype().is_signed());
991        assert!(ConcreteDataType::timestamp_millisecond_datatype().is_signed());
992        assert!(ConcreteDataType::timestamp_microsecond_datatype().is_signed());
993        assert!(ConcreteDataType::timestamp_nanosecond_datatype().is_signed());
994        assert!(ConcreteDataType::time_second_datatype().is_signed());
995        assert!(ConcreteDataType::time_millisecond_datatype().is_signed());
996        assert!(ConcreteDataType::time_microsecond_datatype().is_signed());
997        assert!(ConcreteDataType::time_nanosecond_datatype().is_signed());
998        assert!(ConcreteDataType::interval_year_month_datatype().is_signed());
999        assert!(ConcreteDataType::interval_day_time_datatype().is_signed());
1000        assert!(ConcreteDataType::interval_month_day_nano_datatype().is_signed());
1001        assert!(ConcreteDataType::duration_second_datatype().is_signed());
1002        assert!(ConcreteDataType::duration_millisecond_datatype().is_signed());
1003        assert!(ConcreteDataType::duration_microsecond_datatype().is_signed());
1004        assert!(ConcreteDataType::duration_nanosecond_datatype().is_signed());
1005
1006        assert!(!ConcreteDataType::uint8_datatype().is_signed());
1007        assert!(!ConcreteDataType::uint16_datatype().is_signed());
1008        assert!(!ConcreteDataType::uint32_datatype().is_signed());
1009        assert!(!ConcreteDataType::uint64_datatype().is_signed());
1010
1011        assert!(!ConcreteDataType::float32_datatype().is_signed());
1012        assert!(!ConcreteDataType::float64_datatype().is_signed());
1013
1014        assert!(ConcreteDataType::decimal128_datatype(10, 2).is_signed());
1015    }
1016
1017    #[test]
1018    fn test_is_unsigned() {
1019        assert!(!ConcreteDataType::int8_datatype().is_unsigned());
1020        assert!(!ConcreteDataType::int16_datatype().is_unsigned());
1021        assert!(!ConcreteDataType::int32_datatype().is_unsigned());
1022        assert!(!ConcreteDataType::int64_datatype().is_unsigned());
1023        assert!(!ConcreteDataType::date_datatype().is_unsigned());
1024        assert!(!ConcreteDataType::timestamp_second_datatype().is_unsigned());
1025        assert!(!ConcreteDataType::timestamp_millisecond_datatype().is_unsigned());
1026        assert!(!ConcreteDataType::timestamp_microsecond_datatype().is_unsigned());
1027        assert!(!ConcreteDataType::timestamp_nanosecond_datatype().is_unsigned());
1028        assert!(!ConcreteDataType::time_second_datatype().is_unsigned());
1029        assert!(!ConcreteDataType::time_millisecond_datatype().is_unsigned());
1030        assert!(!ConcreteDataType::time_microsecond_datatype().is_unsigned());
1031        assert!(!ConcreteDataType::time_nanosecond_datatype().is_unsigned());
1032        assert!(!ConcreteDataType::interval_year_month_datatype().is_unsigned());
1033        assert!(!ConcreteDataType::interval_day_time_datatype().is_unsigned());
1034        assert!(!ConcreteDataType::interval_month_day_nano_datatype().is_unsigned());
1035        assert!(!ConcreteDataType::duration_second_datatype().is_unsigned());
1036        assert!(!ConcreteDataType::duration_millisecond_datatype().is_unsigned());
1037        assert!(!ConcreteDataType::duration_microsecond_datatype().is_unsigned());
1038        assert!(!ConcreteDataType::duration_nanosecond_datatype().is_unsigned());
1039        assert!(!ConcreteDataType::decimal128_datatype(10, 2).is_unsigned());
1040
1041        assert!(ConcreteDataType::uint8_datatype().is_unsigned());
1042        assert!(ConcreteDataType::uint16_datatype().is_unsigned());
1043        assert!(ConcreteDataType::uint32_datatype().is_unsigned());
1044        assert!(ConcreteDataType::uint64_datatype().is_unsigned());
1045
1046        assert!(!ConcreteDataType::float32_datatype().is_unsigned());
1047        assert!(!ConcreteDataType::float64_datatype().is_unsigned());
1048    }
1049
1050    #[test]
1051    fn test_numerics() {
1052        let nums = ConcreteDataType::numerics();
1053        assert_eq!(10, nums.len());
1054    }
1055
1056    #[test]
1057    fn test_as_list() {
1058        let list_type =
1059            ConcreteDataType::list_datatype(Arc::new(ConcreteDataType::int32_datatype()));
1060        assert_eq!(
1061            ListType::new(Arc::new(ConcreteDataType::int32_datatype())),
1062            *list_type.as_list().unwrap()
1063        );
1064        assert!(ConcreteDataType::int32_datatype().as_list().is_none());
1065    }
1066
1067    #[test]
1068    fn test_display_concrete_data_type() {
1069        assert_eq!(ConcreteDataType::null_datatype().to_string(), "Null");
1070        assert_eq!(ConcreteDataType::boolean_datatype().to_string(), "Boolean");
1071        assert_eq!(ConcreteDataType::binary_datatype().to_string(), "Binary");
1072        assert_eq!(ConcreteDataType::int8_datatype().to_string(), "Int8");
1073        assert_eq!(ConcreteDataType::int16_datatype().to_string(), "Int16");
1074        assert_eq!(ConcreteDataType::int32_datatype().to_string(), "Int32");
1075        assert_eq!(ConcreteDataType::int64_datatype().to_string(), "Int64");
1076        assert_eq!(ConcreteDataType::uint8_datatype().to_string(), "UInt8");
1077        assert_eq!(ConcreteDataType::uint16_datatype().to_string(), "UInt16");
1078        assert_eq!(ConcreteDataType::uint32_datatype().to_string(), "UInt32");
1079        assert_eq!(ConcreteDataType::uint64_datatype().to_string(), "UInt64");
1080        assert_eq!(ConcreteDataType::float32_datatype().to_string(), "Float32");
1081        assert_eq!(ConcreteDataType::float64_datatype().to_string(), "Float64");
1082        assert_eq!(ConcreteDataType::string_datatype().to_string(), "String");
1083        assert_eq!(ConcreteDataType::date_datatype().to_string(), "Date");
1084        assert_eq!(
1085            ConcreteDataType::timestamp_millisecond_datatype().to_string(),
1086            "TimestampMillisecond"
1087        );
1088        assert_eq!(
1089            ConcreteDataType::time_millisecond_datatype().to_string(),
1090            "TimeMillisecond"
1091        );
1092        assert_eq!(
1093            ConcreteDataType::interval_month_day_nano_datatype().to_string(),
1094            "IntervalMonthDayNano"
1095        );
1096        assert_eq!(
1097            ConcreteDataType::duration_second_datatype().to_string(),
1098            "DurationSecond"
1099        );
1100        assert_eq!(
1101            ConcreteDataType::decimal128_datatype(10, 2).to_string(),
1102            "Decimal(10, 2)"
1103        );
1104        // Nested types
1105        assert_eq!(
1106            ConcreteDataType::list_datatype(Arc::new(ConcreteDataType::int32_datatype()))
1107                .to_string(),
1108            "List<Int32>"
1109        );
1110        assert_eq!(
1111            ConcreteDataType::list_datatype(Arc::new(ConcreteDataType::Dictionary(
1112                DictionaryType::new(
1113                    ConcreteDataType::int32_datatype(),
1114                    ConcreteDataType::string_datatype()
1115                )
1116            )))
1117            .to_string(),
1118            "List<Dictionary<Int32, String>>"
1119        );
1120        assert_eq!(
1121            ConcreteDataType::list_datatype(Arc::new(ConcreteDataType::list_datatype(Arc::new(
1122                ConcreteDataType::list_datatype(Arc::new(ConcreteDataType::int32_datatype()))
1123            ))))
1124            .to_string(),
1125            "List<List<List<Int32>>>"
1126        );
1127        assert_eq!(
1128            ConcreteDataType::dictionary_datatype(
1129                ConcreteDataType::int32_datatype(),
1130                ConcreteDataType::string_datatype()
1131            )
1132            .to_string(),
1133            "Dictionary<Int32, String>"
1134        );
1135        assert_eq!(
1136            ConcreteDataType::vector_datatype(3).to_string(),
1137            "Vector(3)"
1138        );
1139    }
1140}