Add parse_parenthesized_column_list to reduce code duplication

This commit is contained in:
Nickolay Ponomarev 2019-05-04 05:52:32 +03:00
parent cccf7f0d8e
commit f93e69d1d4

View file

@ -805,9 +805,7 @@ impl Parser {
let is_primary_key = self.parse_keywords(vec!["PRIMARY", "KEY"]); let is_primary_key = self.parse_keywords(vec!["PRIMARY", "KEY"]);
let is_unique_key = self.parse_keywords(vec!["UNIQUE", "KEY"]); let is_unique_key = self.parse_keywords(vec!["UNIQUE", "KEY"]);
let is_foreign_key = self.parse_keywords(vec!["FOREIGN", "KEY"]); let is_foreign_key = self.parse_keywords(vec!["FOREIGN", "KEY"]);
self.expect_token(&Token::LParen)?; let column_names = self.parse_parenthesized_column_list(false)?;
let column_names = self.parse_column_names()?;
self.expect_token(&Token::RParen)?;
let key = Key { let key = Key {
name: constraint_name, name: constraint_name,
columns: column_names, columns: column_names,
@ -819,9 +817,7 @@ impl Parser {
} else if is_foreign_key { } else if is_foreign_key {
self.expect_keyword("REFERENCES")?; self.expect_keyword("REFERENCES")?;
let foreign_table = self.parse_object_name()?; let foreign_table = self.parse_object_name()?;
self.expect_token(&Token::LParen)?; let referred_columns = self.parse_parenthesized_column_list(false)?;
let referred_columns = self.parse_column_names()?;
self.expect_token(&Token::RParen)?;
Ok(TableKey::ForeignKey { Ok(TableKey::ForeignKey {
key, key,
foreign_table, foreign_table,
@ -859,13 +855,7 @@ impl Parser {
/// Parse a copy statement /// Parse a copy statement
pub fn parse_copy(&mut self) -> Result<SQLStatement, ParserError> { pub fn parse_copy(&mut self) -> Result<SQLStatement, ParserError> {
let table_name = self.parse_object_name()?; let table_name = self.parse_object_name()?;
let columns = if self.consume_token(&Token::LParen) { let columns = self.parse_parenthesized_column_list(true)?;
let column_names = self.parse_column_names()?;
self.expect_token(&Token::RParen)?;
column_names
} else {
vec![]
};
self.expect_keyword("FROM")?; self.expect_keyword("FROM")?;
self.expect_keyword("STDIN")?; self.expect_keyword("STDIN")?;
self.expect_token(&Token::SemiColon)?; self.expect_token(&Token::SemiColon)?;
@ -1122,9 +1112,20 @@ impl Parser {
} }
} }
/// Parse a comma-separated list of unqualified, possibly quoted identifiers /// Parse a parenthesized comma-separated list of unqualified, possibly quoted identifiers
pub fn parse_column_names(&mut self) -> Result<Vec<SQLIdent>, ParserError> { pub fn parse_parenthesized_column_list(
Ok(self.parse_list_of_ids(&Token::Comma)?) &mut self,
optional: bool,
) -> Result<Vec<SQLIdent>, ParserError> {
if self.consume_token(&Token::LParen) {
let cols = self.parse_list_of_ids(&Token::Comma)?;
self.expect_token(&Token::RParen)?;
Ok(cols)
} else if optional {
Ok(vec![])
} else {
self.expected("a list of columns in parentheses", self.peek_token())
}
} }
pub fn parse_precision(&mut self) -> Result<usize, ParserError> { pub fn parse_precision(&mut self) -> Result<usize, ParserError> {
@ -1215,13 +1216,7 @@ impl Parser {
let mut cte = vec![]; let mut cte = vec![];
loop { loop {
let alias = self.parse_identifier()?; let alias = self.parse_identifier()?;
let renamed_columns = if self.consume_token(&Token::LParen) { let renamed_columns = self.parse_parenthesized_column_list(true)?;
let cols = self.parse_column_names()?;
self.expect_token(&Token::RParen)?;
cols
} else {
vec![]
};
self.expect_keyword("AS")?; self.expect_keyword("AS")?;
self.expect_token(&Token::LParen)?; self.expect_token(&Token::LParen)?;
cte.push(Cte { cte.push(Cte {
@ -1381,10 +1376,8 @@ impl Parser {
let constraint = self.parse_expr()?; let constraint = self.parse_expr()?;
Ok(JoinConstraint::On(constraint)) Ok(JoinConstraint::On(constraint))
} else if self.parse_keyword("USING") { } else if self.parse_keyword("USING") {
self.expect_token(&Token::LParen)?; let columns = self.parse_parenthesized_column_list(false)?;
let attributes = self.parse_column_names()?; Ok(JoinConstraint::Using(columns))
self.expect_token(&Token::RParen)?;
Ok(JoinConstraint::Using(attributes))
} else { } else {
self.expected("ON, or USING after JOIN", self.peek_token()) self.expected("ON, or USING after JOIN", self.peek_token())
} }
@ -1484,13 +1477,7 @@ impl Parser {
pub fn parse_insert(&mut self) -> Result<SQLStatement, ParserError> { pub fn parse_insert(&mut self) -> Result<SQLStatement, ParserError> {
self.expect_keyword("INTO")?; self.expect_keyword("INTO")?;
let table_name = self.parse_object_name()?; let table_name = self.parse_object_name()?;
let columns = if self.consume_token(&Token::LParen) { let columns = self.parse_parenthesized_column_list(true)?;
let column_names = self.parse_column_names()?;
self.expect_token(&Token::RParen)?;
column_names
} else {
vec![]
};
self.expect_keyword("VALUES")?; self.expect_keyword("VALUES")?;
self.expect_token(&Token::LParen)?; self.expect_token(&Token::LParen)?;
let values = self.parse_expr_list()?; let values = self.parse_expr_list()?;