Skip to content

Commit 4d45739

Browse files
Tried to simplify and extend test coverage
1 parent 3d677e1 commit 4d45739

File tree

2 files changed

+352
-177
lines changed

2 files changed

+352
-177
lines changed

src/parser/mod.rs

Lines changed: 43 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6431,32 +6431,33 @@ impl<'a> Parser<'a> {
64316431
}))
64326432
}
64336433

6434-
/// Helper function to parse an operator name (which can contain special characters)
6435-
/// Operator names can be schema-qualified (e.g., schema.operator)
6436-
fn parse_operator_name(&mut self) -> Result<ObjectName, ParserError> {
6437-
let mut name_parts = vec![];
6434+
/// Parse an operator name, which can contain special characters like +, -, <, >, =
6435+
/// that are tokenized as operator tokens rather than identifiers.
6436+
/// This is used for PostgreSQL CREATE OPERATOR statements.
6437+
///
6438+
/// Examples: `+`, `myschema.+`, `pg_catalog.<=`
6439+
pub fn parse_operator_name(&mut self) -> Result<ObjectName, ParserError> {
6440+
let mut parts = vec![];
64386441
loop {
6439-
let token = self.next_token();
6440-
let part = ObjectNamePart::Identifier(Ident::new(token.to_string()));
6441-
name_parts.push(part);
6442-
6442+
parts.push(ObjectNamePart::Identifier(Ident::new(self.next_token().to_string())));
64436443
if !self.consume_token(&Token::Period) {
64446444
break;
64456445
}
64466446
}
6447-
Ok(ObjectName(name_parts))
6447+
Ok(ObjectName(parts))
64486448
}
64496449

64506450
/// Parse a `CREATE OPERATOR` statement
64516451
///
64526452
/// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-createoperator.html)
64536453
pub fn parse_create_operator(&mut self) -> Result<Statement, ParserError> {
6454-
// Parse the operator name (can be schema-qualified)
6455-
// Operators can contain special characters like +, -, *, /, <, >, =, ~, !, @, #, %, ^, &, |, `, ?
6456-
// See https://www.postgresql.org/docs/current/sql-createoperator.html
6457-
let name = self.parse_operator_name()?;
6454+
macro_rules! dup_err {
6455+
($name:expr) => {
6456+
ParserError::ParserError(format!("Duplicate {} clause in CREATE OPERATOR", $name))
6457+
};
6458+
}
64586459

6459-
// Expect opening parenthesis
6460+
let name = self.parse_operator_name()?;
64606461
self.expect_token(&Token::LParen)?;
64616462

64626463
let mut function: Option<ObjectName> = None;
@@ -6471,82 +6472,74 @@ impl<'a> Parser<'a> {
64716472
let mut merges = false;
64726473

64736474
loop {
6474-
// Parse parameter name as keyword
64756475
let keyword = self.expect_one_of_keywords(&[
6476-
Keyword::FUNCTION,
6477-
Keyword::PROCEDURE,
6478-
Keyword::LEFTARG,
6479-
Keyword::RIGHTARG,
6480-
Keyword::COMMUTATOR,
6481-
Keyword::NEGATOR,
6482-
Keyword::RESTRICT,
6483-
Keyword::JOIN,
6484-
Keyword::HASHES,
6485-
Keyword::MERGES,
6476+
Keyword::FUNCTION, Keyword::PROCEDURE, Keyword::LEFTARG, Keyword::RIGHTARG,
6477+
Keyword::COMMUTATOR, Keyword::NEGATOR, Keyword::RESTRICT, Keyword::JOIN,
6478+
Keyword::HASHES, Keyword::MERGES,
64866479
])?;
64876480

6488-
// Check if this is a flag (HASHES or MERGES) - no '=' expected
64896481
match keyword {
64906482
Keyword::HASHES => {
6483+
if hashes { return Err(dup_err!("HASHES")); }
64916484
hashes = true;
64926485
}
64936486
Keyword::MERGES => {
6487+
if merges { return Err(dup_err!("MERGES")); }
64946488
merges = true;
64956489
}
64966490
Keyword::FUNCTION | Keyword::PROCEDURE => {
6491+
if function.is_some() { return Err(dup_err!("FUNCTION/PROCEDURE")); }
64976492
self.expect_token(&Token::Eq)?;
6498-
let func_name = self.parse_object_name(false)?;
6499-
function = Some(func_name);
6493+
function = Some(self.parse_object_name(false)?);
65006494
is_procedure = keyword == Keyword::PROCEDURE;
65016495
}
65026496
Keyword::LEFTARG => {
6497+
if left_arg.is_some() { return Err(dup_err!("LEFTARG")); }
65036498
self.expect_token(&Token::Eq)?;
6504-
let data_type = self.parse_data_type()?;
6505-
left_arg = Some(data_type);
6499+
left_arg = Some(self.parse_data_type()?);
65066500
}
65076501
Keyword::RIGHTARG => {
6502+
if right_arg.is_some() { return Err(dup_err!("RIGHTARG")); }
65086503
self.expect_token(&Token::Eq)?;
6509-
let data_type = self.parse_data_type()?;
6510-
right_arg = Some(data_type);
6504+
right_arg = Some(self.parse_data_type()?);
65116505
}
65126506
Keyword::COMMUTATOR => {
6507+
if commutator.is_some() { return Err(dup_err!("COMMUTATOR")); }
65136508
self.expect_token(&Token::Eq)?;
6514-
let op_name = if self.parse_keyword(Keyword::OPERATOR) {
6509+
if self.parse_keyword(Keyword::OPERATOR) {
65156510
self.expect_token(&Token::LParen)?;
6516-
let op = self.parse_operator_name()?;
6511+
commutator = Some(self.parse_operator_name()?);
65176512
self.expect_token(&Token::RParen)?;
6518-
op
65196513
} else {
6520-
self.parse_operator_name()?
6521-
};
6522-
commutator = Some(op_name);
6514+
commutator = Some(self.parse_operator_name()?);
6515+
}
65236516
}
65246517
Keyword::NEGATOR => {
6518+
if negator.is_some() { return Err(dup_err!("NEGATOR")); }
65256519
self.expect_token(&Token::Eq)?;
6526-
let op_name = if self.parse_keyword(Keyword::OPERATOR) {
6520+
if self.parse_keyword(Keyword::OPERATOR) {
65276521
self.expect_token(&Token::LParen)?;
6528-
let op = self.parse_operator_name()?;
6522+
negator = Some(self.parse_operator_name()?);
65296523
self.expect_token(&Token::RParen)?;
6530-
op
65316524
} else {
6532-
self.parse_operator_name()?
6533-
};
6534-
negator = Some(op_name);
6525+
negator = Some(self.parse_operator_name()?);
6526+
}
65356527
}
65366528
Keyword::RESTRICT => {
6529+
if restrict.is_some() { return Err(dup_err!("RESTRICT")); }
65376530
self.expect_token(&Token::Eq)?;
6538-
let func_name = self.parse_object_name(false)?;
6539-
restrict = Some(func_name);
6531+
restrict = Some(self.parse_object_name(false)?);
65406532
}
65416533
Keyword::JOIN => {
6534+
if join.is_some() { return Err(dup_err!("JOIN")); }
65426535
self.expect_token(&Token::Eq)?;
6543-
let func_name = self.parse_object_name(false)?;
6544-
join = Some(func_name);
6536+
join = Some(self.parse_object_name(false)?);
65456537
}
6546-
_ => unreachable!("unexpected keyword in CREATE OPERATOR"),
6538+
_ => return Err(ParserError::ParserError(format!(
6539+
"Unexpected keyword {:?} in CREATE OPERATOR", keyword
6540+
))),
65476541
}
65486542

6549-
// Check for comma or closing parenthesis
65506543
if !self.consume_token(&Token::Comma) {
65516544
break;
65526545
}

0 commit comments

Comments
 (0)