mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-31 23:27:39 +00:00
Generalize conflict target (#762)
Postgres supports `ON CONFLICT ON CONSTRAINT <constraint_name>` to explicitly name the constraint that fails. Support this.
This commit is contained in:
parent
6d6eb4bc9b
commit
3d5cc54dcf
3 changed files with 70 additions and 15 deletions
|
|
@ -2728,11 +2728,17 @@ pub enum OnInsert {
|
|||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct OnConflict {
|
||||
pub conflict_target: Vec<Ident>,
|
||||
pub conflict_target: Option<ConflictTarget>,
|
||||
pub action: OnConflictAction,
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub enum ConflictTarget {
|
||||
Columns(Vec<Ident>),
|
||||
OnConstraint(ObjectName),
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub enum OnConflictAction {
|
||||
DoNothing,
|
||||
DoUpdate(DoUpdate),
|
||||
|
|
@ -2762,12 +2768,20 @@ impl fmt::Display for OnInsert {
|
|||
impl fmt::Display for OnConflict {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, " ON CONFLICT")?;
|
||||
if !self.conflict_target.is_empty() {
|
||||
write!(f, "({})", display_comma_separated(&self.conflict_target))?;
|
||||
if let Some(target) = &self.conflict_target {
|
||||
write!(f, "{}", target)?;
|
||||
}
|
||||
write!(f, " {}", self.action)
|
||||
}
|
||||
}
|
||||
impl fmt::Display for ConflictTarget {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ConflictTarget::Columns(cols) => write!(f, "({})", display_comma_separated(cols)),
|
||||
ConflictTarget::OnConstraint(name) => write!(f, " ON CONSTRAINT {}", name),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl fmt::Display for OnConflictAction {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
|
|
|
|||
|
|
@ -5630,7 +5630,15 @@ impl<'a> Parser<'a> {
|
|||
let on = if self.parse_keyword(Keyword::ON) {
|
||||
if self.parse_keyword(Keyword::CONFLICT) {
|
||||
let conflict_target =
|
||||
self.parse_parenthesized_column_list(IsOptional::Optional)?;
|
||||
if self.parse_keywords(&[Keyword::ON, Keyword::CONSTRAINT]) {
|
||||
Some(ConflictTarget::OnConstraint(self.parse_object_name()?))
|
||||
} else if self.peek_token() == Token::LParen {
|
||||
Some(ConflictTarget::Columns(
|
||||
self.parse_parenthesized_column_list(IsOptional::Mandatory)?,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
self.expect_keyword(Keyword::DO)?;
|
||||
let action = if self.parse_keyword(Keyword::NOTHING) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue