#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use core::fmt;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::ast::ObjectName;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum DataType {
Char(Option<u64>),
Varchar(Option<u64>),
Uuid,
Clob(u64),
Binary(u64),
Varbinary(u64),
Blob(Option<u64>),
Decimal(Option<u64>, Option<u64>),
Float(Option<u64>),
TinyInt(Option<u64>),
SmallInt(Option<u64>),
Int(Option<u64>),
BigInt(Option<u64>),
Real,
Double,
Boolean,
Date,
Time,
Timestamp,
Interval,
Regclass,
Text,
String,
Bytea,
Custom(ObjectName),
Array(Box<DataType>),
}
impl fmt::Display for DataType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DataType::Char(size) => format_type_with_optional_length(f, "CHAR", size),
DataType::Varchar(size) => {
format_type_with_optional_length(f, "CHARACTER VARYING", size)
}
DataType::Uuid => write!(f, "UUID"),
DataType::Clob(size) => write!(f, "CLOB({})", size),
DataType::Binary(size) => write!(f, "BINARY({})", size),
DataType::Varbinary(size) => write!(f, "VARBINARY({})", size),
DataType::Blob(size) => {
if let Some(size) = size {
write!(f, "BLOB({})", size)
} else {
write!(f, "BLOB")
}
}
DataType::Decimal(precision, scale) => {
if let Some(scale) = scale {
write!(f, "NUMERIC({},{})", precision.unwrap(), scale)
} else {
format_type_with_optional_length(f, "NUMERIC", precision)
}
}
DataType::Float(size) => format_type_with_optional_length(f, "FLOAT", size),
DataType::TinyInt(zerofill) => format_type_with_optional_length(f, "TINYINT", zerofill),
DataType::SmallInt(zerofill) => {
format_type_with_optional_length(f, "SMALLINT", zerofill)
}
DataType::Int(zerofill) => {
if let Some(len) = zerofill {
write!(f, "INT({})", len)
} else {
write!(f, "INTEGER")
}
}
DataType::BigInt(zerofill) => format_type_with_optional_length(f, "BIGINT", zerofill),
DataType::Real => write!(f, "REAL"),
DataType::Double => write!(f, "DOUBLE"),
DataType::Boolean => write!(f, "BOOLEAN"),
DataType::Date => write!(f, "DATE"),
DataType::Time => write!(f, "TIME"),
DataType::Timestamp => write!(f, "TIMESTAMP"),
DataType::Interval => write!(f, "INTERVAL"),
DataType::Regclass => write!(f, "REGCLASS"),
DataType::Text => write!(f, "TEXT"),
DataType::String => write!(f, "STRING"),
DataType::Bytea => write!(f, "BYTEA"),
DataType::Array(ty) => write!(f, "{}[]", ty),
DataType::Custom(ty) => write!(f, "{}", ty),
}
}
}
fn format_type_with_optional_length(
f: &mut fmt::Formatter,
sql_type: &'static str,
len: &Option<u64>,
) -> fmt::Result {
write!(f, "{}", sql_type)?;
if let Some(len) = len {
write!(f, "({})", len)?;
}
Ok(())
}