Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 17 additions & 27 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7992,20 +7992,7 @@ impl<'a> Parser<'a> {
None
};

// Optional purpose
let purpose = if self.parse_keyword(Keyword::FOR) {
if self.parse_keyword(Keyword::SEARCH) {
Some(OperatorPurpose::ForSearch)
} else if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
let sort_family = self.parse_object_name(false)?;
Some(OperatorPurpose::ForOrderBy { sort_family })
} else {
return self
.expected_ref("SEARCH or ORDER BY after FOR", self.peek_token_ref());
}
} else {
None
};
let purpose = self.parse_operator_purpose()?;

items.push(OperatorClassItem::Operator {
strategy_number,
Expand Down Expand Up @@ -12247,6 +12234,21 @@ impl<'a> Parser<'a> {
})
}

fn parse_operator_purpose(&mut self) -> Result<Option<OperatorPurpose>, ParserError> {
if !self.parse_keyword(Keyword::FOR) {
return Ok(None);
}

if self.parse_keyword(Keyword::SEARCH) {
Ok(Some(OperatorPurpose::ForSearch))
} else if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
let sort_family = self.parse_object_name(false)?;
Ok(Some(OperatorPurpose::ForOrderBy { sort_family }))
} else {
self.expected_ref("SEARCH or ORDER BY after FOR", self.peek_token_ref())
}
}

/// Parse an operator item for ALTER OPERATOR FAMILY ADD operations
fn parse_operator_family_add_operator(&mut self) -> Result<OperatorFamilyItem, ParserError> {
let strategy_number = self.parse_literal_uint()?;
Expand All @@ -12257,19 +12259,7 @@ impl<'a> Parser<'a> {
let op_types = self.parse_comma_separated(Parser::parse_data_type)?;
self.expect_token(&Token::RParen)?;

// Optional purpose
let purpose = if self.parse_keyword(Keyword::FOR) {
if self.parse_keyword(Keyword::SEARCH) {
Some(OperatorPurpose::ForSearch)
} else if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
let sort_family = self.parse_object_name(false)?;
Some(OperatorPurpose::ForOrderBy { sort_family })
} else {
return self.expected_ref("SEARCH or ORDER BY after FOR", self.peek_token_ref());
}
} else {
None
};
let purpose = self.parse_operator_purpose()?;

Ok(OperatorFamilyItem::Operator {
strategy_number,
Expand Down
34 changes: 34 additions & 0 deletions tests/sqlparser_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11039,3 +11039,37 @@ fn operator_function_display_preserves_empty_operator_types() {
assert_eq!(item.to_string(), expected);
}
}

#[test]
fn parse_alter_operator_family_order_by_followed_by_search() {
let sql = r#"ALTER OPERATOR FAMILY my_ops USING gist ADD OPERATOR 1 < (INT4, INT4) FOR ORDER BY sort_schema."sort family", OPERATOR 2 > (INT4, INT4) FOR SEARCH"#;
let Statement::AlterOperatorFamily(AlterOperatorFamily {
operation: AlterOperatorFamilyOperation::Add { items },
..
}) = pg_and_generic().verified_stmt(sql)
else {
panic!("Expected ALTER OPERATOR FAMILY");
};
assert_eq!(
items,
vec![
OperatorFamilyItem::Operator {
strategy_number: 1,
operator_name: ObjectName::from(vec![Ident::new("<")]),
op_types: vec![DataType::Int4(None), DataType::Int4(None)],
purpose: Some(OperatorPurpose::ForOrderBy {
sort_family: ObjectName::from(vec![
Ident::new("sort_schema"),
Ident::with_quote('"', "sort family"),
]),
}),
},
OperatorFamilyItem::Operator {
strategy_number: 2,
operator_name: ObjectName::from(vec![Ident::new(">")]),
op_types: vec![DataType::Int4(None), DataType::Int4(None)],
purpose: Some(OperatorPurpose::ForSearch),
},
]
);
}
Loading