Simplify custom datatypes handling and add a test

1) Simplified the bit in parse_datatype()
2) Made sure it was covered by the test (the "public.year" bit)
2a) ...the rest of changes in the test are to fix incorrect variable
 names: c_name/c_lat/c_lng were copy-pasted from a previous test.
3) Removed the branch from parse_pg_cast, which duplicated what
parse_data_type already handled (added in the same commit even
2007995938 )
This commit is contained in:
Nickolay Ponomarev 2019-01-11 01:22:10 +03:00
parent 7c6e6970fa
commit f21cd697c3
2 changed files with 25 additions and 28 deletions

View file

@ -224,19 +224,13 @@ impl Parser {
})
}
/// Parse a postgresql casting style which is in the form or expr::datatype
/// Parse a postgresql casting style which is in the form of `expr::datatype`
pub fn parse_pg_cast(&mut self, expr: ASTNode) -> Result<ASTNode, ParserError> {
let _ = self.consume_token(&Token::DoubleColon)?;
let datatype = if let Ok(data_type) = self.parse_data_type() {
Ok(data_type)
} else if let Ok(table_name) = self.parse_tablename() {
Ok(SQLType::Custom(table_name))
} else {
parser_err!("Expecting datatype or identifier")
};
let datatype = self.parse_data_type()?;
let pg_cast = ASTNode::SQLCast {
expr: Box::new(expr),
data_type: datatype?,
data_type: datatype,
};
if let Some(Token::DoubleColon) = self.peek_token() {
self.parse_pg_cast(pg_cast)
@ -945,13 +939,10 @@ impl Parser {
}
_ => parser_err!(format!("Invalid data type '{:?}'", k)),
},
Some(Token::Identifier(id)) => {
if let Ok(true) = self.consume_token(&Token::Period) {
let ids = self.parse_tablename()?;
Ok(SQLType::Custom(format!("{}.{}", id, ids)))
} else {
Ok(SQLType::Custom(id))
}
Some(Token::Identifier(_)) => {
self.prev_token();
let type_name = self.parse_tablename()?; // TODO: this actually reads a possibly schema-qualified name of a (custom) type
Ok(SQLType::Custom(type_name))
}
other => parser_err!(format!("Invalid data type: '{:?}'", other)),
}

View file

@ -517,20 +517,26 @@ fn parse_create_table_from_pg_dump() {
ASTNode::SQLCreateTable { name, columns } => {
assert_eq!("public.customer", name);
let c_name = &columns[0];
assert_eq!("customer_id", c_name.name);
assert_eq!(SQLType::Int, c_name.data_type);
assert_eq!(false, c_name.allow_null);
let c_customer_id = &columns[0];
assert_eq!("customer_id", c_customer_id.name);
assert_eq!(SQLType::Int, c_customer_id.data_type);
assert_eq!(false, c_customer_id.allow_null);
let c_lat = &columns[1];
assert_eq!("store_id", c_lat.name);
assert_eq!(SQLType::SmallInt, c_lat.data_type);
assert_eq!(false, c_lat.allow_null);
let c_store_id = &columns[1];
assert_eq!("store_id", c_store_id.name);
assert_eq!(SQLType::SmallInt, c_store_id.data_type);
assert_eq!(false, c_store_id.allow_null);
let c_lng = &columns[2];
assert_eq!("first_name", c_lng.name);
assert_eq!(SQLType::Varchar(Some(45)), c_lng.data_type);
assert_eq!(false, c_lng.allow_null);
let c_first_name = &columns[2];
assert_eq!("first_name", c_first_name.name);
assert_eq!(SQLType::Varchar(Some(45)), c_first_name.data_type);
assert_eq!(false, c_first_name.allow_null);
let c_release_year = &columns[10];
assert_eq!(
SQLType::Custom("public.year".to_string()),
c_release_year.data_type
);
}
_ => assert!(false),
}