mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-11 08:26:18 +00:00
Modifier support for Custom Datatype (#680)
* feat: add support for custom types with argument * refactor: add support for number and string as type arguments * fix: ignore CustomWithArgs when parsing TypedString * refactor: merge CustomWithArgs into Custom * refactor: rename arguments to modifiers
This commit is contained in:
parent
2c266a437c
commit
914810d366
2 changed files with 69 additions and 4 deletions
|
@ -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
|
||||
|
@ -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() {
|
||||
|
|
|
@ -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),
|
||||
|
@ -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()?;
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue