Skip to content

Commit

Permalink
Merge 46ff407 into 2c266a4
Browse files Browse the repository at this point in the history
  • Loading branch information
sunng87 committed Oct 20, 2022
2 parents 2c266a4 + 46ff407 commit 91a592a
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 4 deletions.
10 changes: 8 additions & 2 deletions src/ast/data_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ pub enum DataType {
/// Bytea
Bytea,
/// Custom type such as enums
Custom(ObjectName),
Custom(ObjectName, Vec<String>),
/// Arrays
Array(Box<DataType>),
/// Enums
Expand Down Expand Up @@ -217,7 +217,13 @@ impl fmt::Display for DataType {
DataType::String => write!(f, "STRING"),
DataType::Bytea => write!(f, "BYTEA"),
DataType::Array(ty) => write!(f, "{}[]", ty),
DataType::Custom(ty) => write!(f, "{}", ty),
DataType::Custom(ty, modifiers) => {
if modifiers.is_empty() {
write!(f, "{}", ty)
} else {
write!(f, "{}({})", ty, modifiers.join(", "))
}
}
DataType::Enum(vals) => {
write!(f, "ENUM(")?;
for (i, v) in vals.iter().enumerate() {
Expand Down
63 changes: 61 additions & 2 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3661,7 +3661,11 @@ impl<'a> Parser<'a> {
_ => {
self.prev_token();
let type_name = self.parse_object_name()?;
Ok(DataType::Custom(type_name))
if let Some(modifiers) = self.parse_optional_type_modifiers()? {
Ok(DataType::Custom(type_name, modifiers))
} else {
Ok(DataType::Custom(type_name, vec![]))
}
}
},
unexpected => self.expected("a data type name", unexpected),
Expand Down Expand Up @@ -3907,6 +3911,31 @@ impl<'a> Parser<'a> {
}
}

pub fn parse_optional_type_modifiers(&mut self) -> Result<Option<Vec<String>>, ParserError> {
if self.consume_token(&Token::LParen) {
let mut modifiers = Vec::new();
loop {
match self.next_token() {
Token::Word(w) => modifiers.push(w.to_string()),
Token::Number(n, _) => modifiers.push(n),
Token::SingleQuotedString(s) => modifiers.push(s),

Token::Comma => {
continue;
}
Token::RParen => {
break;
}
unexpected => self.expected("type modifiers", unexpected)?,
}
}

Ok(Some(modifiers))
} else {
Ok(None)
}
}

pub fn parse_delete(&mut self) -> Result<Statement, ParserError> {
self.expect_keyword(Keyword::FROM)?;
let table_name = self.parse_table_factor()?;
Expand Down Expand Up @@ -5540,7 +5569,7 @@ mod tests {
#[cfg(test)]
mod test_parse_data_type {
use crate::ast::{
CharLengthUnits, CharacterLength, DataType, ExactNumberInfo, TimezoneInfo,
CharLengthUnits, CharacterLength, DataType, ExactNumberInfo, ObjectName, TimezoneInfo,
};
use crate::dialect::{AnsiDialect, GenericDialect};
use crate::test_utils::TestedDialects;
Expand Down Expand Up @@ -5717,6 +5746,36 @@ mod tests {
test_parse_data_type!(dialect, "CLOB(20)", DataType::Clob(Some(20)));
}

#[test]
fn test_parse_custom_types() {
let dialect = TestedDialects {
dialects: vec![Box::new(GenericDialect {}), Box::new(AnsiDialect {})],
};
test_parse_data_type!(
dialect,
"GEOMETRY",
DataType::Custom(ObjectName(vec!["GEOMETRY".into()]), vec![])
);

test_parse_data_type!(
dialect,
"GEOMETRY(POINT)",
DataType::Custom(
ObjectName(vec!["GEOMETRY".into()]),
vec!["POINT".to_string()]
)
);

test_parse_data_type!(
dialect,
"GEOMETRY(POINT, 4326)",
DataType::Custom(
ObjectName(vec!["GEOMETRY".into()]),
vec!["POINT".to_string(), "4326".to_string()]
)
);
}

#[test]
fn test_ansii_exact_numeric_types() {
// Exact numeric types: <https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type>
Expand Down

0 comments on commit 91a592a

Please sign in to comment.