Skip to content
Open
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
1 change: 1 addition & 0 deletions fuzz/fuzz_seeds/postgres_alter_index_attach_partition.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER INDEX d.orders_note_idx ATTACH PARTITION d.p0_note_idx
10 changes: 10 additions & 0 deletions src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,13 @@ pub enum AlterIndexOperation {
/// The new name for the index.
index_name: ObjectName,
},
/// Attach the partition index `index_name` to the index.
///
/// See <https://www.postgresql.org/docs/current/sql-alterindex.html>
AttachPartition {
/// The partition index to attach.
index_name: ObjectName,
},
}

impl fmt::Display for AlterTableOperation {
Expand Down Expand Up @@ -1188,6 +1195,9 @@ impl fmt::Display for AlterIndexOperation {
AlterIndexOperation::RenameIndex { index_name } => {
write!(f, "RENAME TO {index_name}")
}
AlterIndexOperation::AttachPartition { index_name } => {
write!(f, "ATTACH PARTITION {index_name}")
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,7 @@ impl Spanned for AlterIndexOperation {
fn span(&self) -> Span {
match self {
AlterIndexOperation::RenameIndex { index_name } => index_name.span(),
AlterIndexOperation::AttachPartition { index_name } => index_name.span(),
}
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11941,8 +11941,15 @@ impl<'a> Parser<'a> {
} else {
return self.expected_ref("TO after RENAME", self.peek_token_ref());
}
} else if self.parse_keyword(Keyword::ATTACH) {
self.expect_keyword_is(Keyword::PARTITION)?;
let index_name = self.parse_object_name(false)?;
AlterIndexOperation::AttachPartition { index_name }
} else {
return self.expected_ref("RENAME after ALTER INDEX", self.peek_token_ref());
return self.expected_ref(
"RENAME or ATTACH PARTITION after ALTER INDEX",
self.peek_token_ref(),
);
};

Ok(Statement::AlterIndex {
Expand Down
37 changes: 37 additions & 0 deletions tests/sqlparser_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13144,3 +13144,40 @@ fn parse_alter_table_no_inherit() {
);
}
}

#[test]
fn parse_alter_index_attach_partition() {
let sql = "ALTER INDEX d.orders_note_idx ATTACH PARTITION d.p0_note_idx";
assert_eq!(
Parser::parse_sql(&PostgreSqlDialect {}, sql).unwrap()[0].span(),
Span::new(Location::new(1, 13), Location::new(1, 61))
);
match pg().verified_stmt(sql) {
Statement::AlterIndex {
name,
operation: AlterIndexOperation::AttachPartition { index_name },
} => {
assert_eq!("d.orders_note_idx", name.to_string());
assert_eq!("d.p0_note_idx", index_name.to_string());
}
_ => unreachable!(),
}

for (sql, expected) in [
("ALTER INDEX i ATTACH p", "Expected: PARTITION, found: p"),
(
"ALTER INDEX i ATTACH PARTITION",
"Expected: identifier, found: EOF",
),
(
"ALTER INDEX i DETACH PARTITION p",
"Expected: RENAME or ATTACH PARTITION after ALTER INDEX, found: DETACH",
),
] {
assert_eq!(
pg().parse_sql_statements(sql).unwrap_err().to_string(),
format!("sql parser error: {expected}"),
"{sql}"
);
}
}
Loading