wing_sqlparser/ast/
data_type.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13#[cfg(not(feature = "std"))]
14use alloc::boxed::Box;
15use core::fmt;
16
17#[cfg(feature = "serde")]
18use serde::{Deserialize, Serialize};
19
20use crate::ast::ObjectName;
21
22/// SQL data types
23#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25pub enum DataType {
26    /// Fixed-length character type e.g. CHAR(10)
27    Char(Option<u64>),
28    /// Variable-length character type e.g. VARCHAR(10)
29    Varchar(Option<u64>),
30    /// Uuid type
31    Uuid,
32    /// Large character object e.g. CLOB(1000)
33    Clob(u64),
34    /// Fixed-length binary type e.g. BINARY(10)
35    Binary(u64),
36    /// Variable-length binary type e.g. VARBINARY(10)
37    Varbinary(u64),
38    /// Large binary object e.g. BLOB(1000)
39    Blob(u64),
40    /// Decimal type with optional precision and scale e.g. DECIMAL(10,2)
41    Decimal(Option<u64>, Option<u64>),
42    /// Floating point with optional precision e.g. FLOAT(8)
43    Float(Option<u64>),
44    /// Tiny integer with optional display width e.g. TINYINT or TINYINT(3)
45    TinyInt(Option<u64>),
46    /// Small integer with optional display width e.g. SMALLINT or SMALLINT(5)
47    SmallInt(Option<u64>),
48    /// Integer with optional display width e.g. INT or INT(11)
49    Int(Option<u64>),
50    /// Big integer with optional display width e.g. BIGINT or BIGINT(20)
51    BigInt(Option<u64>),
52    /// Floating point e.g. REAL
53    Real,
54    /// Double e.g. DOUBLE PRECISION
55    Double,
56    /// Boolean
57    Boolean,
58    /// Date
59    Date,
60    /// Time
61    Time,
62    /// Timestamp
63    Timestamp,
64    /// Interval
65    Interval,
66    /// Regclass used in postgresql serial
67    Regclass,
68    /// Text
69    Text,
70    /// String
71    String,
72    /// Bytea
73    Bytea,
74    /// Custom type such as enums
75    Custom(ObjectName),
76    /// Arrays
77    Array(Box<DataType>),
78}
79
80impl fmt::Display for DataType {
81    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82        match self {
83            DataType::Char(size) => format_type_with_optional_length(f, "CHAR", size),
84            DataType::Varchar(size) => {
85                format_type_with_optional_length(f, "CHARACTER VARYING", size)
86            }
87            DataType::Uuid => write!(f, "UUID"),
88            DataType::Clob(size) => write!(f, "CLOB({})", size),
89            DataType::Binary(size) => write!(f, "BINARY({})", size),
90            DataType::Varbinary(size) => write!(f, "VARBINARY({})", size),
91            DataType::Blob(size) => write!(f, "BLOB({})", size),
92            DataType::Decimal(precision, scale) => {
93                if let Some(scale) = scale {
94                    write!(f, "NUMERIC({},{})", precision.unwrap(), scale)
95                } else {
96                    format_type_with_optional_length(f, "NUMERIC", precision)
97                }
98            }
99            DataType::Float(size) => format_type_with_optional_length(f, "FLOAT", size),
100            DataType::TinyInt(zerofill) => format_type_with_optional_length(f, "TINYINT", zerofill),
101            DataType::SmallInt(zerofill) => {
102                format_type_with_optional_length(f, "SMALLINT", zerofill)
103            }
104            DataType::Int(zerofill) => format_type_with_optional_length(f, "INT", zerofill),
105            DataType::BigInt(zerofill) => format_type_with_optional_length(f, "BIGINT", zerofill),
106            DataType::Real => write!(f, "REAL"),
107            DataType::Double => write!(f, "DOUBLE"),
108            DataType::Boolean => write!(f, "BOOLEAN"),
109            DataType::Date => write!(f, "DATE"),
110            DataType::Time => write!(f, "TIME"),
111            DataType::Timestamp => write!(f, "TIMESTAMP"),
112            DataType::Interval => write!(f, "INTERVAL"),
113            DataType::Regclass => write!(f, "REGCLASS"),
114            DataType::Text => write!(f, "TEXT"),
115            DataType::String => write!(f, "STRING"),
116            DataType::Bytea => write!(f, "BYTEA"),
117            DataType::Array(ty) => write!(f, "{}[]", ty),
118            DataType::Custom(ty) => write!(f, "{}", ty),
119        }
120    }
121}
122
123fn format_type_with_optional_length(
124    f: &mut fmt::Formatter,
125    sql_type: &'static str,
126    len: &Option<u64>,
127) -> fmt::Result {
128    write!(f, "{}", sql_type)?;
129    if let Some(len) = len {
130        write!(f, "({})", len)?;
131    }
132    Ok(())
133}