clickhouse_data_type/
nullable.rs

1use chrono_tz::Tz;
2use pest::iterators::{Pair, Pairs};
3
4use crate::{
5    date_time,
6    date_time64::{self, DateTime64Precision},
7    decimal::{self, DecimalPrecision, DecimalScale},
8    fixed_string::{self, FixedStringN},
9    r#enum::{self, Enum16, Enum8},
10    type_name_parser::Rule,
11    ParseError,
12};
13
14#[derive(PartialEq, Eq, Debug, Clone)]
15pub enum NullableTypeName {
16    Nothing,
17    //
18    UInt8,
19    UInt16,
20    UInt32,
21    UInt64,
22    UInt256,
23    Int8,
24    Int16,
25    Int32,
26    Int64,
27    Int128,
28    Int256,
29    Float32,
30    Float64,
31    Decimal(DecimalPrecision, DecimalScale),
32    String,
33    FixedString(FixedStringN),
34    Uuid,
35    Date,
36    DateTime(Option<Tz>),
37    DateTime64(DateTime64Precision, Option<Tz>),
38    Enum8(Enum8),
39    Enum16(Enum16),
40    Ipv4,
41    Ipv6,
42}
43
44impl TryFrom<Pair<'_, Rule>> for NullableTypeName {
45    type Error = ParseError;
46
47    fn try_from(pair: Pair<'_, Rule>) -> Result<Self, Self::Error> {
48        match pair.as_rule() {
49            Rule::Nullable_Nothing => Ok(Self::Nothing),
50            //
51            Rule::UInt8 => Ok(Self::UInt8),
52            Rule::UInt16 => Ok(Self::UInt16),
53            Rule::UInt32 => Ok(Self::UInt32),
54            Rule::UInt64 => Ok(Self::UInt64),
55            Rule::UInt256 => Ok(Self::UInt256),
56            Rule::Int8 => Ok(Self::Int8),
57            Rule::Int16 => Ok(Self::Int16),
58            Rule::Int32 => Ok(Self::Int32),
59            Rule::Int64 => Ok(Self::Int64),
60            Rule::Int128 => Ok(Self::Int128),
61            Rule::Int256 => Ok(Self::Int256),
62            Rule::Float32 => Ok(Self::Float32),
63            Rule::Float64 => Ok(Self::Float64),
64            Rule::Decimal => {
65                let (precision, scale) = decimal::get_precision_and_scale(pair.into_inner())?;
66
67                Ok(Self::Decimal(precision, scale))
68            }
69            Rule::String => Ok(Self::String),
70            Rule::FixedString => {
71                let n = fixed_string::get_n(pair.into_inner())?;
72
73                Ok(Self::FixedString(n))
74            }
75            Rule::UUID => Ok(Self::Uuid),
76            Rule::Date => Ok(Self::Date),
77            Rule::DateTime => {
78                let timezone = date_time::get_timezone(pair.into_inner())?;
79
80                Ok(Self::DateTime(timezone))
81            }
82            Rule::DateTime64 => {
83                let (precision, timezone) =
84                    date_time64::get_precision_and_timezone(pair.into_inner())?;
85
86                Ok(Self::DateTime64(precision, timezone))
87            }
88            Rule::Enum8 => {
89                let inner = r#enum::get_enum8(pair.into_inner())?;
90
91                Ok(Self::Enum8(inner))
92            }
93            Rule::Enum16 => {
94                let inner = r#enum::get_enum16(pair.into_inner())?;
95
96                Ok(Self::Enum16(inner))
97            }
98            Rule::IPv4 => Ok(Self::Ipv4),
99            Rule::IPv6 => Ok(Self::Ipv6),
100            _ => Err(ParseError::Unknown),
101        }
102    }
103}
104
105pub(crate) fn get_type_name(
106    mut nullable_pairs: Pairs<'_, Rule>,
107) -> Result<NullableTypeName, ParseError> {
108    let nullable_pair = nullable_pairs.next().ok_or(ParseError::Unknown)?;
109
110    let mut type_name_pairs = nullable_pair.into_inner();
111    let type_name_pair = type_name_pairs.next().ok_or(ParseError::Unknown)?;
112
113    let data_type = NullableTypeName::try_from(type_name_pair)?;
114
115    Ok(data_type)
116}